Merge "Protect against null mBluetoothHeadset" into lmp-dev
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 9b6ece1..85463eb 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -297,6 +297,8 @@
     // switches every time the user hits "swap".
     private Call mConferenceLevelActiveCall = null;
 
+    private boolean mIsLocallyDisconnecting = false;
+
     /**
      * Persists the specified parameters and initializes the new instance.
      *
@@ -372,6 +374,7 @@
             maybeLoadCannedSmsResponses();
 
             if (mState == CallState.DISCONNECTED) {
+                setLocallyDisconnecting(false);
                 fixParentAfterDisconnect();
             }
         }
@@ -744,6 +747,9 @@
      * Attempts to disconnect the call through the connection service.
      */
     void disconnect() {
+        // Track that the call is now locally disconnecting.
+        setLocallyDisconnecting(true);
+
         if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
                 mState == CallState.CONNECTING) {
             Log.v(this, "Aborting call %s", this);
@@ -1282,6 +1288,24 @@
         mIsUnknown = isUnknown;
     }
 
+    /**
+     * Determines if this call is in a disconnecting state.
+     *
+     * @return {@code true} if this call is locally disconnecting.
+     */
+    public boolean isLocallyDisconnecting() {
+        return mIsLocallyDisconnecting;
+    }
+
+    /**
+     * Sets whether this call is in a disconnecting state.
+     *
+     * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting.
+     */
+    private void setLocallyDisconnecting(boolean isLocallyDisconnecting) {
+        mIsLocallyDisconnecting = isLocallyDisconnecting;
+    }
+
     static int getStateFromConnectionState(int state) {
         switch (state) {
             case Connection.STATE_INITIALIZING:
diff --git a/src/com/android/server/telecom/CallActivity.java b/src/com/android/server/telecom/CallActivity.java
index 07f66e4..7022327 100644
--- a/src/com/android/server/telecom/CallActivity.java
+++ b/src/com/android/server/telecom/CallActivity.java
@@ -78,6 +78,7 @@
             return;
         }
 
+        verifyCallAction(intent);
         String action = intent.getAction();
 
         if (Intent.ACTION_CALL.equals(action) ||
@@ -89,6 +90,17 @@
         }
     }
 
+    private void verifyCallAction(Intent intent) {
+        if (CallActivity.class.getName().equals(intent.getComponent().getClassName())) {
+            // If we were launched directly from the CallActivity, not one of its more privileged
+            // aliases, then make sure that only the non-privileged actions are allowed.
+            if (!Intent.ACTION_CALL.equals(intent.getAction())) {
+                Log.w(this, "Attempt to deliver non-CALL action; forcing to CALL");
+                intent.setAction(Intent.ACTION_CALL);
+            }
+        }
+    }
+
     private void processOutgoingCallIntent(Intent intent) {
         Uri handle = intent.getData();
         String scheme = handle.getScheme();
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 6621c7c..78553ad 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -445,6 +445,10 @@
             state = CallState.DISCONNECTED;
         }
 
+        if (call.isLocallyDisconnecting() && state != CallState.DISCONNECTED) {
+            state = CallState.DISCONNECTING;
+        }
+
         String parentCallId = null;
         Call parentCall = call.getParentCall();
         if (parentCall != null) {
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 4e866a1..d645009 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -361,7 +361,7 @@
         systemDialerIntent.setData(handle);
         systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         Log.v(this, "calling startActivity for default dialer: %s", systemDialerIntent);
-        mContext.startActivity(systemDialerIntent);
+        mContext.startActivityAsUser(systemDialerIntent, UserHandle.CURRENT);
     }
 
     /**
@@ -393,15 +393,6 @@
      * number.
      */
     private void rewriteCallIntentAction(Intent intent, boolean isPotentialEmergencyNumber) {
-        if (CallActivity.class.getName().equals(intent.getComponent().getClassName())) {
-            // If we were launched directly from the CallActivity, not one of its more privileged
-            // aliases, then make sure that only the non-privileged actions are allowed.
-            if (!Intent.ACTION_CALL.equals(intent.getAction())) {
-                Log.w(this, "Attempt to deliver non-CALL action; forcing to CALL");
-                intent.setAction(Intent.ACTION_CALL);
-            }
-        }
-
         String action = intent.getAction();
 
         /* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */