Merge "Pass call capabilities from connection to call" into lmp-dev
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 10244b2..7718df6 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -708,9 +708,9 @@
     void abort() {
         if (mCreateConnectionProcessor != null) {
             mCreateConnectionProcessor.abort();
-        } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
-                mState == CallState.CONNECTING) {
-            handleCreateConnectionFailure(DisconnectCause.LOCAL, null);
+        } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT
+                || mState == CallState.CONNECTING) {
+            handleCreateConnectionFailure(DisconnectCause.OUTGOING_CANCELED, null);
         } else {
             Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING");
         }
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 10db104..89b89e6 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -117,7 +117,6 @@
      * @param intent Call intent containing data about the handle to call.
      */
     private void processOutgoingCallIntent(Intent intent) {
-
         String uriString = intent.getData().getSchemeSpecificPart();
         Uri handle = Uri.fromParts(
                 PhoneNumberUtils.isUriNumber(uriString) ? "sip" : "tel", uriString, null);
diff --git a/src/com/android/telecomm/CallLogManager.java b/src/com/android/telecomm/CallLogManager.java
index d0668b9..ee65255 100644
--- a/src/com/android/telecomm/CallLogManager.java
+++ b/src/com/android/telecomm/CallLogManager.java
@@ -23,6 +23,7 @@
 import android.telecomm.CallState;
 import android.telecomm.PhoneAccountHandle;
 import android.telecomm.VideoProfile;
+import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 
 import com.android.internal.telephony.CallerInfo;
@@ -88,8 +89,9 @@
 
     @Override
     public void onCallStateChanged(Call call, int oldState, int newState) {
-        if ((newState == CallState.DISCONNECTED || newState == CallState.ABORTED) &&
-                oldState != CallState.PRE_DIAL_WAIT) {
+        if ((newState == CallState.DISCONNECTED || newState == CallState.ABORTED)
+                && oldState != CallState.PRE_DIAL_WAIT
+                && call.getDisconnectCause() != DisconnectCause.OUTGOING_CANCELED) {
             int type;
             if (!call.isIncoming()) {
                 type = Calls.OUTGOING_TYPE;
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 80ef854..a9c2c3e 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -250,8 +250,8 @@
     /**
      * Starts the process to attach the call to a connection service.
      *
-     * @param phoneAccountHandle The phone account which contains the component name of the connection
-     *                     service to use for this call.
+     * @param phoneAccountHandle The phone account which contains the component name of the
+     *        connection service to use for this call.
      * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      */
     void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
@@ -273,7 +273,6 @@
         call.startCreateConnection();
     }
 
-
     /**
      * Kicks off the first steps to creating an outgoing call so that InCallUI can launch.
      *
@@ -281,10 +280,9 @@
      * placeOutgoingCall directly.
      *
      * @param handle Handle to connect the call with.
-     * @param phoneAccountHandle The phone account which contains the component name of the connection
-     *                     service to use for this call.
-     * @param extras The optional extras Bundle passed with the intent used for the outgoing call.
-     *
+     * @param phoneAccountHandle The phone account which contains the component name of the
+     *        connection service to use for this call.
+     * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      */
     Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras) {
         // We only allow a single outgoing call at any given time. Before placing a call, make sure
@@ -296,6 +294,27 @@
             return null;
         }
 
+        TelecommApp app = TelecommApp.getInstance();
+
+        // Only dial with the requested phoneAccount if it is still valid. Otherwise treat this call
+        // as if a phoneAccount was not specified (does the default behavior instead).
+        if (phoneAccountHandle != null) {
+            List<PhoneAccountHandle> enabledAccounts =
+                    app.getPhoneAccountRegistrar().getOutgoingPhoneAccounts();
+            if (!enabledAccounts.contains(phoneAccountHandle)) {
+                phoneAccountHandle = null;
+            }
+        }
+
+        if (phoneAccountHandle == null) {
+            // No preset account, check if default exists
+            PhoneAccountHandle defaultAccountHandle =
+                    app.getPhoneAccountRegistrar().getDefaultOutgoingPhoneAccount();
+            if (defaultAccountHandle != null) {
+                phoneAccountHandle = defaultAccountHandle;
+            }
+        }
+
         // Create a call with original handle. The handle may be changed when the call is attached
         // to a connection service, but in most cases will remain the same.
         call = new Call(
@@ -307,7 +326,14 @@
                 false /* isIncoming */,
                 false /* isConference */);
         call.setExtras(extras);
-        call.setState(CallState.CONNECTING);
+
+        final boolean emergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle());
+        if (phoneAccountHandle == null && !emergencyCall) {
+            // This is the state where the user is expected to select an account
+            call.setState(CallState.PRE_DIAL_WAIT);
+        } else {
+            call.setState(CallState.CONNECTING);
+        }
 
         if (!isPotentialMMICode(handle)) {
             addCall(call);
@@ -327,15 +353,14 @@
      * @param speakerphoneOn Whether or not to turn the speakerphone on once the call connects.
      * @param videoState The desired video state for the outgoing call.
      */
-    void placeOutgoingCall(Call call, Uri handle, GatewayInfo gatewayInfo,
-            PhoneAccountHandle accountHandle, boolean speakerphoneOn, int videoState) {
+    void placeOutgoingCall(Call call, Uri handle, GatewayInfo gatewayInfo, boolean speakerphoneOn,
+            int videoState) {
         if (call == null) {
             // don't do anything if the call no longer exists
             Log.i(this, "Canceling unknown call.");
             return;
         }
 
-        TelecommApp app = TelecommApp.getInstance();
         final Uri uriHandle = (gatewayInfo == null) ? handle : gatewayInfo.getGatewayHandle();
 
         if (gatewayInfo == null) {
@@ -345,49 +370,22 @@
                     Log.pii(uriHandle), Log.pii(handle));
         }
 
-        //TODO: phone account is already set in {@link #startOutgoingCall}, refactor so this is
-        // not redundant.
-        //
-        // Only dial with the requested phoneAccount if it is still valid. Otherwise treat this call
-        // as if a phoneAccount was not specified (does the default behavior instead).
-        if (accountHandle != null) {
-            List<PhoneAccountHandle> enabledAccounts =
-                    app.getPhoneAccountRegistrar().getOutgoingPhoneAccounts();
-            if (!enabledAccounts.contains(accountHandle)) {
-                accountHandle = null;
-            }
-        }
-
         call.setHandle(uriHandle);
         call.setGatewayInfo(gatewayInfo);
         call.setStartWithSpeakerphoneOn(speakerphoneOn);
         call.setVideoState(videoState);
 
-        // This block of code will attempt to pre-determine a phone account
+        TelecommApp app = TelecommApp.getInstance();
         final boolean emergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle());
         if (emergencyCall) {
             // Emergency -- CreateConnectionProcessor will choose accounts automatically
             call.setTargetPhoneAccount(null);
-        } else if (accountHandle != null) {
-            // NOTE: this is currently not an option because no feature currently exists to
-            // preset a phone account
-            Log.d(this, "CALL with phone account: " + accountHandle);
-            call.setTargetPhoneAccount(accountHandle);
-        } else {
-            // No preset account, check if default exists
-            PhoneAccountHandle defaultAccountHandle =
-                    app.getPhoneAccountRegistrar().getDefaultOutgoingPhoneAccount();
-            if (defaultAccountHandle != null) {
-                call.setTargetPhoneAccount(defaultAccountHandle);
-            }
         }
 
         if (call.getTargetPhoneAccount() != null || emergencyCall) {
-            // If the account is selected, proceed to place the outgoing call
+            // If the account has been set, proceed to place the outgoing call.
+            // Otherwise the connection will be initiated when the account is set by the user.
             call.startCreateConnection();
-        } else {
-            // This is the state where the user is expected to select an account
-            setCallState(call, CallState.PRE_DIAL_WAIT);
         }
     }
 
@@ -515,6 +513,7 @@
         }
     }
 
+
     /**
      * Instructs Telecomm to put the specified call on hold. Intended to be invoked by the
      * in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered by
@@ -755,6 +754,7 @@
         return call;
     }
 
+
     /**
      * Adds the specified call to the main list of live calls.
      *
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index f535267..264ee63 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -889,10 +889,7 @@
         if (connection.getState() == Connection.STATE_DISCONNECTED) {
             // A connection that begins in the DISCONNECTED state is an indication of
             // failure to connect; we handle all failures uniformly
-            removeCall(
-                    callId,
-                    connection.getFailureCode(),
-                    connection.getFailureMessage());
+            removeCall(callId, connection.getDisconnectCause(), connection.getDisconnectMessage());
         } else {
             // Successful connection
             if (mPendingResponses.containsKey(callId)) {
diff --git a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
index 65c1309..a45f4ef 100644
--- a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
@@ -24,7 +24,6 @@
 import android.net.Uri;
 import android.os.UserHandle;
 import android.telecomm.GatewayInfo;
-import android.telecomm.PhoneAccountHandle;
 import android.telecomm.TelecommManager;
 import android.telecomm.VideoProfile;
 import android.telephony.PhoneNumberUtils;
@@ -133,8 +132,7 @@
             }
 
             GatewayInfo gatewayInfo = getGateWayInfoFromIntent(intent, resultHandleUri);
-            PhoneAccountHandle accountHandle = getAccountHandleFromIntent(intent);
-            mCallsManager.placeOutgoingCall(mCall, resultHandleUri, gatewayInfo, accountHandle,
+            mCallsManager.placeOutgoingCall(mCall, resultHandleUri, gatewayInfo,
                     mIntent.getBooleanExtra(TelecommManager.EXTRA_START_CALL_WITH_SPEAKERPHONE,
                             false),
                     mIntent.getIntExtra(TelecommManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
@@ -215,7 +213,7 @@
             int videoState = mIntent.getIntExtra(
                     TelecommManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
                     VideoProfile.VideoState.AUDIO_ONLY);
-            mCallsManager.placeOutgoingCall(mCall, Uri.fromParts(scheme, handle, null), null, null,
+            mCallsManager.placeOutgoingCall(mCall, Uri.fromParts(scheme, handle, null), null,
                     speakerphoneOn, videoState);
 
             // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
@@ -285,12 +283,6 @@
             Log.d(this, "Found and copied gateway provider extras to broadcast intent.");
             return;
         }
-        PhoneAccountHandle extraAccountHandle =
-                src.getParcelableExtra(TelecommManager.EXTRA_PHONE_ACCOUNT_HANDLE);
-        if (extraAccountHandle != null) {
-            dst.putExtra(TelecommManager.EXTRA_PHONE_ACCOUNT_HANDLE, extraAccountHandle);
-            Log.d(this, "Found and copied account extra to broadcast intent.");
-        }
 
         Log.d(this, "No provider extras found in call intent.");
     }
@@ -335,20 +327,6 @@
         return null;
     }
 
-    /**
-     * Extracts account/connection provider information from a provided intent..
-     *
-     * @param intent to extract account information from.
-     * @return Account object containing extracted account information
-     */
-    public static PhoneAccountHandle getAccountHandleFromIntent(Intent intent) {
-        if (intent == null) {
-            return null;
-        }
-
-        return intent.getParcelableExtra(TelecommManager.EXTRA_PHONE_ACCOUNT_HANDLE);
-    }
-
     private void launchSystemDialer(Context context, Uri handle) {
         Intent systemDialerIntent = new Intent();
         final Resources resources = context.getResources();
diff --git a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index 0688f3b..5fd75e5 100644
--- a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -96,6 +96,8 @@
         TelecommManager telecommManager =
                 (TelecommManager) context.getSystemService(Context.TELECOMM_SERVICE);
 
+        telecommManager.clearAccounts(context.getPackageName());
+
         telecommManager.registerPhoneAccount(PhoneAccount.builder()
                 .withAccountHandle(
                         new PhoneAccountHandle(
@@ -105,21 +107,22 @@
                 .withSubscriptionNumber("555-TEST")
                 .withCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
                 .withIconResId(R.drawable.stat_sys_phone_call)
-                .withLabel("Dummy Service")
-                .withShortDescription("a short description for the dummy service")
+                .withLabel("TelecommTestApp Call Provider")
+                .withShortDescription("a short description for the call provider")
                 .build());
 
         telecommManager.registerPhoneAccount(PhoneAccount.builder()
                 .withAccountHandle(
                         new PhoneAccountHandle(
-                                new ComponentName(context, TestConnectionManager.class),
+                                new ComponentName(context, TestConnectionService.class),
                                 SIM_SUBSCRIPTION_ID))
-                .withHandle(Uri.parse("tel:555-CMGR"))
-                .withSubscriptionNumber("555-CMGR")
-                .withCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+                .withHandle(Uri.parse("tel:555-TSIM"))
+                .withSubscriptionNumber("555-TSIM")
+                .withCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
                 .withIconResId(R.drawable.stat_sys_phone_call)
-                .withLabel("Dummy Connection Manager")
-                .withShortDescription("a short description for the dummy connection manager")
+                .withLabel("TelecommTestApp SIM Subscription")
+                .withShortDescription("a short description for the sim subscription")
                 .build());
 
         telecommManager.registerPhoneAccount(PhoneAccount.builder()
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
index 69c5ea6..902ace7 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
@@ -181,7 +181,7 @@
     }
 
     private static void log(String msg) {
-        Log.w("telecomtestcs", "[TestConnectionService] " + msg);
+        Log.w("telecomtestcs", "[TestConnectionManager] " + msg);
     }
 
     @Override
@@ -200,7 +200,7 @@
             PhoneAccountHandle connectionManagerAccount,
             final ConnectionRequest request) {
         return new TestManagedConnection(
-                createRemoteOutgoingConnection(
+                createRemoteIncomingConnection(
                         request.getAccountHandle(),
                         request),
                 true);