Instantiate third party phone on call DO NOT MERGE

With this CL we now create a new third party phone as needed.

Change-Id: I31880c9ac758ddf7f9538e1c182197b8d3e073e4
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 52dbf76..1da6d36 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -26,6 +26,7 @@
 import com.android.phone.OtaUtils.CdmaOtaScreenState;
 
 import android.app.AlertDialog;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Handler;
@@ -324,7 +325,10 @@
             // or any of combinations
             String sipPhoneUri = intent.getStringExtra(
                     OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI);
-            phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri);
+            ComponentName thirdPartyCallComponent = (ComponentName) intent.getParcelableExtra(
+                    OutgoingCallBroadcaster.EXTRA_THIRD_PARTY_CALL_COMPONENT);
+            phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri,
+                    thirdPartyCallComponent);
             if (VDBG) log("- got Phone instance: " + phone + ", class = " + phone.getClass());
 
             // update okToCallStatus based on new phone
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index 6e0c13e..a27ea57 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -77,6 +77,8 @@
     public static final String EXTRA_SIP_PHONE_URI = "android.phone.extra.SIP_PHONE_URI";
     public static final String EXTRA_ACTUAL_NUMBER_TO_DIAL =
             "android.phone.extra.ACTUAL_NUMBER_TO_DIAL";
+    public static final String EXTRA_THIRD_PARTY_CALL_COMPONENT =
+            "android.phone.extra.THIRD_PARTY_CALL_COMPONENT";
 
     /**
      * Identifier for intent extra for sending an empty Flash message for
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 2834c9a..05b2308 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -180,16 +180,9 @@
                     request = (MainThreadRequest) msg.obj;
                     Pair<ComponentName, String> pair =
                             (Pair<ComponentName, String>) request.argument;
-                    for (Phone phone : CallManager.getInstance().getAllPhones()) {
-                        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_THIRD_PARTY) {
-                            ThirdPartyPhone thirdPartyPhone = (ThirdPartyPhone) phone;
-                            if (thirdPartyPhone.getCallProviderComponent().equals(pair.first) &&
-                                    thirdPartyPhone.takeIncomingCall(pair.first, pair.second)) {
-                                if (DBG) log("newIncomingThirdPartyCall: call taken");
-                                return;
-                            }
-                        }
-                    }
+                    ThirdPartyPhone thirdPartyPhone = (ThirdPartyPhone)
+                            PhoneUtils.getThirdPartyPhoneFromComponent(mCM, pair.first);
+                    thirdPartyPhone.takeIncomingCall(pair.first, pair.second);
                     break;
                 }
 
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 596426b..d3a8da5 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -21,6 +21,7 @@
 import android.app.ProgressDialog;
 import android.bluetooth.IBluetoothHeadsetPhone;
 import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -55,10 +56,12 @@
 import com.android.internal.telephony.MmiCode;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.cdma.CdmaConnection;
 import com.android.internal.telephony.sip.SipPhone;
+import com.android.internal.telephony.thirdpartyphone.ThirdPartyPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 
 import java.util.ArrayList;
@@ -2554,19 +2557,25 @@
      * @param scheme the scheme from the data URI that the number originally came from.
      * @param number the phone number, or SIP address.
      */
-    public static Phone pickPhoneBasedOnNumber(CallManager cm,
-            String scheme, String number, String primarySipUri) {
+    public static Phone pickPhoneBasedOnNumber(CallManager cm, String scheme, String number,
+            String primarySipUri, ComponentName thirdPartyCallComponent) {
         if (DBG) {
             log("pickPhoneBasedOnNumber: scheme " + scheme
                     + ", number " + toLogSafePhoneNumber(number)
                     + ", sipUri "
-                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null"));
+                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null")
+                    + ", thirdPartyCallComponent: " + thirdPartyCallComponent);
         }
 
         if (primarySipUri != null) {
             Phone phone = getSipPhoneFromUri(cm, primarySipUri);
             if (phone != null) return phone;
         }
+
+        if (thirdPartyCallComponent != null) {
+            return getThirdPartyPhoneFromComponent(cm, thirdPartyCallComponent);
+        }
+
         return cm.getDefaultPhone();
     }
 
@@ -2585,6 +2594,20 @@
         return null;
     }
 
+    public static Phone getThirdPartyPhoneFromComponent(CallManager cm, ComponentName component) {
+        for (Phone phone : cm.getAllPhones()) {
+            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_THIRD_PARTY) {
+                ThirdPartyPhone thirdPartyPhone = (ThirdPartyPhone) phone;
+                if (thirdPartyPhone.getCallProviderComponent().equals(component)) {
+                    return thirdPartyPhone;
+                }
+            }
+        }
+        ThirdPartyPhone thirdPartyPhone = PhoneFactory.makeThirdPartyPhone(component);
+        cm.registerPhone(thirdPartyPhone);
+        return thirdPartyPhone;
+    }
+
     /**
      * Returns true when the given call is in INCOMING state and there's no foreground phone call,
      * meaning the call is the first real incoming call the phone is having.
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
index 5a7e91f..84fb7e3 100644
--- a/src/com/android/phone/SipCallOptionHandler.java
+++ b/src/com/android/phone/SipCallOptionHandler.java
@@ -19,6 +19,7 @@
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.thirdpartyphone.ThirdPartyPhone;
 import com.android.phone.sip.SipProfileDb;
 import com.android.phone.sip.SipSettings;
 import com.android.phone.sip.SipSharedPreferences;
@@ -26,9 +27,12 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
@@ -181,7 +185,7 @@
             if (!isRegularCall) {
                 showDialog(DIALOG_NO_VOIP);
             } else {
-                setResultAndFinish();
+                checkThirdPartyPhone();
             }
             return;
         }
@@ -221,8 +225,10 @@
             } else {
                 mUseSipPhone = false;
             }
+            setResultAndFinish();
+        } else {
+            checkThirdPartyPhone();
         }
-        setResultAndFinish();
     }
 
     /**
@@ -470,4 +476,39 @@
         }
         return null;
     }
+
+    private boolean isConnectedToWifi() {
+        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+        if (cm != null) {
+            NetworkInfo ni = cm.getActiveNetworkInfo();
+            return ni != null && ni.isConnected() && ni.getType() == ConnectivityManager.TYPE_WIFI;
+        }
+        return false;
+    }
+
+    private void checkThirdPartyPhone() {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                // TODO(sail): Move this out of this file or rename this file.
+                // TODO(sail): Move this logic to the switchboard.
+                if (isConnectedToWifi()) {
+                    Intent intent = new Intent(ThirdPartyPhone.ACTION_THIRD_PARTY_CALL_SERVICE);
+                    PackageManager pm = getPackageManager();
+                    // TODO(sail): Need to handle case where there are multiple services.
+                    // TODO(sail): Need to enforce permissions.
+                    ResolveInfo info = pm.resolveService(intent, 0);
+                    if (info != null && info.serviceInfo != null) {
+                        ComponentName component = new ComponentName(info.serviceInfo.packageName,
+                                info.serviceInfo.name);
+                        mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_THIRD_PARTY_CALL_COMPONENT,
+                                component);
+                        PhoneGlobals.getInstance().callController.placeCall(mIntent);
+                        startDelayedFinish();
+                        return;
+                    }
+                }
+                setResultAndFinish();
+            }
+        });
+    }
 }