Add field to store who is initiating the call

Insert userhandle of user that initiate the call before forwarding
the intent to primary user.

Previous ACTION_CALL flow:
Fire ACTION_SEND (managed user) ->
UserCallActivity in Telecom (parent user) ->
PrimaryCallReceiver (parent user)

Current ACTION_CALL flow:
Fire ACTION_SEND (managed user) ->
UserCallActivity in Telecom (managed user) ->
PrimaryCallReceiver (parent user)

The field can be used for:
1. Filter phone accounts for outgoing call
2. Insert call log based on who initiates the call
3. Pass the field to in-call UI which may uses it to indicate it is a work
   call.


Change-Id: I78611a4394f00ce0655c37d52b7b456f213ec802
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index c36761a..6d6ee29 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -38,6 +38,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
+import android.os.UserHandle;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telecom.IVideoProvider;
@@ -226,6 +227,8 @@
 
     private PhoneAccountHandle mTargetPhoneAccountHandle;
 
+    private UserHandle mInitiatingUser;
+
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     private final List<Call> mConferenceableCalls = new ArrayList<>();
@@ -383,7 +386,6 @@
         mIsIncoming = isIncoming;
         mIsConference = isConference;
         maybeLoadCannedSmsResponses();
-
         Log.event(this, Log.Events.CREATED);
     }
 
@@ -1694,6 +1696,22 @@
         mIsLocallyDisconnecting = isLocallyDisconnecting;
     }
 
+    /**
+     * @return user handle of user initiating the outgoing call.
+     */
+    public UserHandle getInitiatingUser() {
+        return mInitiatingUser;
+    }
+
+    /**
+     * Set the user handle of user initiating the outgoing call.
+     * @param initiatingUser
+     */
+    public void setInitiatingUser(UserHandle initiatingUser) {
+        Preconditions.checkNotNull(initiatingUser);
+        mInitiatingUser = initiatingUser;
+    }
+
     static int getStateFromConnectionState(int state) {
         switch (state) {
             case Connection.STATE_INITIALIZING:
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index a6840b9..57db8a4 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -33,6 +33,12 @@
      */
     public static final String KEY_IS_PRIVILEGED_DIALER = "is_privileged_dialer";
 
+    /**
+     * The user initiating the outgoing call.
+     */
+    public static final String KEY_INITIATING_USER = "initiating_user";
+
+
     private final Context mContext;
     private final CallsManager mCallsManager;
 
@@ -96,8 +102,11 @@
 
         final boolean isPrivilegedDialer = intent.getBooleanExtra(KEY_IS_PRIVILEGED_DIALER, false);
 
+        UserHandle initiatingUser = intent.getParcelableExtra(KEY_INITIATING_USER);
+
         // Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
-        Call call = callsManager.startOutgoingCall(handle, phoneAccountHandle, clientExtras);
+        Call call = callsManager
+                .startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser);
 
         if (call != null) {
             // Asynchronous calls should not usually be made inside a BroadcastReceiver because once
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index c6bd951..7a17dde 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -24,6 +24,7 @@
 import android.os.SystemProperties;
 import android.os.SystemVibrator;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.provider.CallLog.Calls;
 import android.telecom.CallAudioState;
 import android.telecom.Conference;
@@ -557,8 +558,8 @@
                 null /* connectionManagerPhoneAccount */,
                 phoneAccountHandle,
                 true /* isIncoming */,
-                false /* isConference */);
-
+                false /* isConference */
+        );
         call.setIntentExtras(extras);
         // TODO: Move this to be a part of addCall()
         call.addListener(this);
@@ -583,7 +584,8 @@
                 // Use onCreateIncomingConnection in TelephonyConnectionService, so that we attach
                 // to the existing connection instead of trying to create a new one.
                 true /* isIncoming */,
-                false /* isConference */);
+                false /* isConference */
+        );
         call.setIsUnknown(true);
         call.setIntentExtras(extras);
         call.addListener(this);
@@ -629,8 +631,10 @@
      * @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.
+     * @param initiatingUser {@link UserHandle} of user that place the outgoing call.
      */
-    Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras) {
+    Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras,
+            UserHandle initiatingUser) {
         boolean isReusedCall = true;
         Call call = reuseOutgoingCall(handle);
 
@@ -648,8 +652,9 @@
                     null /* connectionManagerPhoneAccount */,
                     null /* phoneAccountHandle */,
                     false /* isIncoming */,
-                    false /* isConference */);
-
+                    false /* isConference */
+            );
+            call.setInitiatingUser(initiatingUser);
             isReusedCall = false;
         }
 
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessor.java b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
index f7e2191..920c1fc 100644
--- a/src/com/android/server/telecom/components/UserCallIntentProcessor.java
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
@@ -140,6 +140,10 @@
 
         intent.putExtra(CallIntentProcessor.KEY_IS_PRIVILEGED_DIALER,
                 isDefaultOrSystemDialer(callingPackageName));
+
+        // Save the user handle of current user before forwarding the intent to primary user.
+        intent.putExtra(CallIntentProcessor.KEY_INITIATING_USER, mUserHandle);
+
         sendBroadcastToReceiver(intent);
     }
 
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 75a4429..dfaeed1 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -39,6 +39,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Process;
 import android.os.UserHandle;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
@@ -54,6 +55,7 @@
 import com.android.internal.telecom.IInCallAdapter;
 import com.android.server.telecom.BluetoothPhoneServiceImpl;
 import com.android.server.telecom.CallAudioManager;
+import com.android.server.telecom.CallIntentProcessor;
 import com.android.server.telecom.CallsManager;
 import com.android.server.telecom.HeadsetMediaButton;
 import com.android.server.telecom.HeadsetMediaButtonFactory;
@@ -65,6 +67,7 @@
 import com.android.server.telecom.ProximitySensorManager;
 import com.android.server.telecom.ProximitySensorManagerFactory;
 import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.components.UserCallIntentProcessor;
 
 import com.google.common.base.Predicate;
 
@@ -317,7 +320,8 @@
     private IdPair startOutgoingPhoneCall(
             String number,
             PhoneAccountHandle phoneAccountHandle,
-            ConnectionServiceFixture connectionServiceFixture) throws Exception {
+            ConnectionServiceFixture connectionServiceFixture,
+            UserHandle initiatingUser) throws Exception {
         reset(
                 connectionServiceFixture.getTestDouble(),
                 mInCallServiceFixtureX.getTestDouble(),
@@ -344,8 +348,14 @@
                     phoneAccountHandle);
         }
 
+        final UserHandle userHandle = initiatingUser;
+        new UserCallIntentProcessor(mContext, userHandle)
+                .processIntent(actionCallIntent, null, true /* hasCallAppOp*/);
         mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
 
+        assertEquals(userHandle,
+                actionCallIntent.getParcelableExtra(CallIntentProcessor.KEY_INITIATING_USER));
+
         if (!hasInCallAdapter) {
             verify(mInCallServiceFixtureX.getTestDouble())
                     .setInCallAdapter(
@@ -553,7 +563,8 @@
             String number,
             PhoneAccountHandle phoneAccountHandle,
             ConnectionServiceFixture connectionServiceFixture) throws Exception {
-        IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
+        IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
+                Process.myUserHandle());
 
         connectionServiceFixture.sendSetDialing(ids.mConnectionId);
         assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
@@ -653,7 +664,8 @@
         final IdPair ids = startOutgoingPhoneCall(
                 "650-555-1212",
                 mPhoneAccountA0.getAccountHandle(),
-                mConnectionServiceFixtureA);
+                mConnectionServiceFixtureA,
+                Process.myUserHandle());
         rapidFire(
                 new Runnable() {
                     @Override