diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 57db8a4..831b708 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -24,6 +24,30 @@
  * which interacts with the rest of Telecom, both of which run only as the primary user.
  */
 public class CallIntentProcessor {
+    public interface Adapter {
+        void processOutgoingCallIntent(Context context, CallsManager callsManager,
+                Intent intent);
+        void processIncomingCallIntent(CallsManager callsManager, Intent intent);
+        void processUnknownCallIntent(CallsManager callsManager, Intent intent);
+    }
+
+    public static class AdapterImpl implements Adapter {
+        @Override
+        public void processOutgoingCallIntent(Context context, CallsManager callsManager,
+                Intent intent) {
+            CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent);
+        }
+
+        @Override
+        public void processIncomingCallIntent(CallsManager callsManager, Intent intent) {
+            CallIntentProcessor.processIncomingCallIntent(callsManager, intent);
+        }
+
+        @Override
+        public void processUnknownCallIntent(CallsManager callsManager, Intent intent) {
+            CallIntentProcessor.processUnknownCallIntent(callsManager, intent);
+        }
+    }
 
     public static final String KEY_IS_UNKNOWN_CALL = "is_unknown_call";
     public static final String KEY_IS_INCOMING_CALL = "is_incoming_call";
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 709c044..604aed9 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -219,7 +219,8 @@
      * @return The user-selected outgoing {@link PhoneAccount}, or null if it hasn't been set (or
      *      if it was set by another user).
      */
-    PhoneAccountHandle getUserSelectedOutgoingPhoneAccount(UserHandle userHandle) {
+    @VisibleForTesting
+    public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount(UserHandle userHandle) {
         if (userHandle == null) {
             return null;
         }
@@ -231,6 +232,7 @@
         // Make sure the account is still registered and owned by the user.
         PhoneAccount account = getPhoneAccount(defaultPhoneAccountHandle.phoneAccountHandle,
                 userHandle);
+
         if (account != null) {
             return defaultPhoneAccountHandle.phoneAccountHandle;
         }
@@ -642,12 +644,6 @@
         }
     }
 
-    private void fireSimCallManagerChanged() {
-        for (Listener l : mListeners) {
-            l.onSimCallManagerChanged(this);
-        }
-    }
-
     private String getAccountDiffString(PhoneAccount account1, PhoneAccount account2) {
         if (account1 == null || account2 == null) {
             return "Diff: " + account1 + ", " + account2;
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 30fcb65..10e2844 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -48,7 +48,7 @@
 // TODO: Needed for move to system service: import com.android.internal.R;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.telecom.components.UserCallIntentProcessor;
+import com.android.server.telecom.components.UserCallIntentProcessorFactory;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -60,6 +60,29 @@
  * Implementation of the ITelecom interface.
  */
 public class TelecomServiceImpl {
+    public interface DefaultDialerManagerAdapter {
+        String getDefaultDialerApplication(Context context);
+        boolean setDefaultDialerApplication(Context context, String packageName);
+        boolean isDefaultOrSystemDialer(Context context, String packageName);
+    }
+
+    static class DefaultDialerManagerAdapterImpl implements DefaultDialerManagerAdapter {
+        @Override
+        public String getDefaultDialerApplication(Context context) {
+            return DefaultDialerManager.getDefaultDialerApplication(context);
+        }
+
+        @Override
+        public boolean setDefaultDialerApplication(Context context, String packageName) {
+            return DefaultDialerManager.setDefaultDialerApplication(context, packageName);
+        }
+
+        @Override
+        public boolean isDefaultOrSystemDialer(Context context, String packageName) {
+            return DefaultDialerManager.isDefaultOrSystemDialer(context, packageName);
+        }
+
+    }
     private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
             "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
     private static final int DEFAULT_VIDEO_STATE = -1;
@@ -572,7 +595,7 @@
                 Log.startSession("TSI.gDDP");
                 final long token = Binder.clearCallingIdentity();
                 try {
-                    return DefaultDialerManager.getDefaultDialerApplication(mContext);
+                    return mDefaultDialerManagerAdapter.getDefaultDialerApplication(mContext);
                 } finally {
                     Binder.restoreCallingIdentity(token);
                 }
@@ -937,7 +960,8 @@
                             if (extras != null) {
                                 intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);
                             }
-                            CallIntentProcessor.processIncomingCallIntent(mCallsManager, intent);
+                            mCallIntentProcessorAdapter.processIncomingCallIntent(
+                                    mCallsManager, intent);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
@@ -975,7 +999,7 @@
                             intent.putExtra(CallIntentProcessor.KEY_IS_UNKNOWN_CALL, true);
                             intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
                                     phoneAccountHandle);
-                            CallIntentProcessor.processUnknownCallIntent(mCallsManager, intent);
+                            mCallIntentProcessorAdapter.processUnknownCallIntent(mCallsManager, intent);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
@@ -1022,8 +1046,9 @@
                     try {
                         final Intent intent = new Intent(Intent.ACTION_CALL, handle);
                         intent.putExtras(extras);
-                        new UserCallIntentProcessor(mContext, userHandle).processIntent(intent,
-                                callingPackage, hasCallAppOp && hasCallPermission);
+                        mUserCallIntentProcessorFactory.create(mContext, userHandle)
+                                .processIntent(
+                                        intent, callingPackage, hasCallAppOp && hasCallPermission);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
@@ -1065,8 +1090,8 @@
                     long token = Binder.clearCallingIdentity();
                     try {
                         final boolean result =
-                                DefaultDialerManager.setDefaultDialerApplication(mContext,
-                                        packageName);
+                                mDefaultDialerManagerAdapter
+                                        .setDefaultDialerApplication(mContext, packageName);
                         if (result) {
                             final Intent intent =
                                     new Intent(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
@@ -1131,12 +1156,18 @@
     private PackageManager mPackageManager;
     private CallsManager mCallsManager;
     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
+    private final CallIntentProcessor.Adapter mCallIntentProcessorAdapter;
+    private final UserCallIntentProcessorFactory mUserCallIntentProcessorFactory;
+    private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter;
     private final TelecomSystem.SyncRoot mLock;
 
     public TelecomServiceImpl(
             Context context,
             CallsManager callsManager,
             PhoneAccountRegistrar phoneAccountRegistrar,
+            CallIntentProcessor.Adapter callIntentProcessorAdapter,
+            UserCallIntentProcessorFactory userCallIntentProcessorFactory,
+            DefaultDialerManagerAdapter defaultDialerManagerAdapter,
             TelecomSystem.SyncRoot lock) {
         mContext = context;
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -1147,6 +1178,9 @@
         mCallsManager = callsManager;
         mLock = lock;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
+        mUserCallIntentProcessorFactory = userCallIntentProcessorFactory;
+        mDefaultDialerManagerAdapter = defaultDialerManagerAdapter;
+        mCallIntentProcessorAdapter = callIntentProcessorAdapter;
     }
 
     public ITelecomService.Stub getBinder() {
@@ -1356,11 +1390,11 @@
 
     private boolean isPrivilegedDialerCalling(String callingPackage) {
         mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-        return DefaultDialerManager.isDefaultOrSystemDialer(mContext, callingPackage);
+        return mDefaultDialerManagerAdapter.isDefaultOrSystemDialer(mContext, callingPackage);
     }
 
     private TelephonyManager getTelephonyManager() {
-        return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
     }
 
     /**
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index e0c3602..d28a9d7 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -17,6 +17,8 @@
 package com.android.server.telecom;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.telecom.components.UserCallIntentProcessor;
+import com.android.server.telecom.components.UserCallIntentProcessorFactory;
 
 import android.Manifest;
 import android.content.BroadcastReceiver;
@@ -159,7 +161,16 @@
                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
 
         mTelecomServiceImpl = new TelecomServiceImpl(
-                mContext, mCallsManager, mPhoneAccountRegistrar, mLock);
+                mContext, mCallsManager, mPhoneAccountRegistrar,
+                new CallIntentProcessor.AdapterImpl(),
+                new UserCallIntentProcessorFactory() {
+                    @Override
+                    public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
+                        return new UserCallIntentProcessor(context, userHandle);
+                    }
+                },
+                new TelecomServiceImpl.DefaultDialerManagerAdapterImpl(),
+                mLock);
     }
 
     @VisibleForTesting
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessorFactory.java b/src/com/android/server/telecom/components/UserCallIntentProcessorFactory.java
new file mode 100644
index 0000000..d37cd06
--- /dev/null
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessorFactory.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.components;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+public interface UserCallIntentProcessorFactory {
+    UserCallIntentProcessor create(Context context, UserHandle userHandle);
+}
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index 52ab512..d16f86b 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -251,6 +251,7 @@
 
         @Override
         public void sendBroadcastAsUser(Intent intent, UserHandle userHandle) {
+            // TODO -- need to ensure this is captured
         }
 
         @Override
@@ -273,9 +274,18 @@
         }
 
         @Override
+        public int checkCallingOrSelfPermission(String permission) {
+            return PackageManager.PERMISSION_GRANTED;
+        }
+
+        @Override
         public void enforceCallingOrSelfPermission(String permission, String message) {
             // Don't bother enforcing anything in mock.
         }
+
+        /**
+         * Used to work around a Mockito/ART bug. If you remove any of these, tests will fail.
+         */
     };
 
     public class FakeAudioManager extends AudioManager {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
new file mode 100644
index 0000000..faeb34f
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.tests;
+
+import static android.Manifest.permission.CALL_PHONE;
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+import static android.Manifest.permission.READ_PHONE_STATE;
+import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+import com.android.internal.telecom.ITelecomService;
+import com.android.server.telecom.CallIntentProcessor;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.PhoneAccountRegistrar;
+import com.android.server.telecom.TelecomServiceImpl;
+import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.components.UserCallIntentProcessor;
+import com.android.server.telecom.components.UserCallIntentProcessorFactory;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class TelecomServiceImplTest extends TelecomTestCase {
+    public static class CallIntentProcessAdapterFake implements CallIntentProcessor.Adapter {
+        @Override
+        public void processOutgoingCallIntent(Context context, CallsManager callsManager,
+                Intent intent) {
+
+        }
+
+        @Override
+        public void processIncomingCallIntent(CallsManager callsManager, Intent intent) {
+
+        }
+
+        @Override
+        public void processUnknownCallIntent(CallsManager callsManager, Intent intent) {
+
+        }
+    }
+
+    public static class DefaultDialerManagerAdapterFake
+            implements TelecomServiceImpl.DefaultDialerManagerAdapter {
+        @Override
+        public String getDefaultDialerApplication(Context context) {
+            return null;
+        }
+
+        @Override
+        public boolean setDefaultDialerApplication(Context context, String packageName) {
+            return false;
+        }
+
+        @Override
+        public boolean isDefaultOrSystemDialer(Context context, String packageName) {
+            return false;
+        }
+    }
+
+    private static class AnyStringIn extends ArgumentMatcher<String> {
+        private Collection<String> mStrings;
+        public AnyStringIn(Collection<String> strings) {
+            this.mStrings = strings;
+        }
+
+        @Override
+        public boolean matches(Object string) {
+            return mStrings.contains(string);
+        }
+    }
+
+    private ITelecomService.Stub mTSIBinder;
+    private AppOpsManager mAppOpsManager;
+    private UserManager mUserManager;
+
+    @Mock private CallsManager mFakeCallsManager;
+    @Mock private PhoneAccountRegistrar mFakePhoneAccountRegistrar;
+    @Mock private TelecomManager mTelecomManager;
+    private CallIntentProcessor.Adapter mCallIntentProcessorAdapter =
+            spy(new CallIntentProcessAdapterFake());
+    private TelecomServiceImpl.DefaultDialerManagerAdapter mDefaultDialerManagerAdapter =
+            spy(new DefaultDialerManagerAdapterFake());
+    @Mock private UserCallIntentProcessor mUserCallIntentProcessor;
+
+    private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
+
+    private static final String DEFAULT_DIALER_PACKAGE = "com.google.android.dialer";
+    private static final UserHandle USER_HANDLE_16 = new UserHandle(16);
+    private static final UserHandle USER_HANDLE_17 = new UserHandle(17);
+    private static final PhoneAccountHandle TEL_PA_HANDLE_16 = new PhoneAccountHandle(
+            new ComponentName("test", "telComponentName"), "0", USER_HANDLE_16);
+    private static final PhoneAccountHandle SIP_PA_HANDLE_17 = new PhoneAccountHandle(
+            new ComponentName("test", "sipComponentName"), "1", USER_HANDLE_17);
+    private static final PhoneAccountHandle TEL_PA_HANDLE_CURRENT = new PhoneAccountHandle(
+            new ComponentName("test", "telComponentName"), "2", Binder.getCallingUserHandle());
+    private static final PhoneAccountHandle SIP_PA_HANDLE_CURRENT = new PhoneAccountHandle(
+            new ComponentName("test", "sipComponentName"), "3", Binder.getCallingUserHandle());
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
+        mComponentContextFixture.putBooleanResource(
+                com.android.internal.R.bool.config_voice_capable, true);
+
+        doReturn(mContext).when(mContext).getApplicationContext();
+        doNothing().when(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
+                anyString());
+        TelecomServiceImpl telecomServiceImpl = new TelecomServiceImpl(
+                mContext,
+                mFakeCallsManager,
+                mFakePhoneAccountRegistrar,
+                mCallIntentProcessorAdapter,
+                new UserCallIntentProcessorFactory() {
+                    @Override
+                    public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
+                        return mUserCallIntentProcessor;
+                    }
+                },
+                mDefaultDialerManagerAdapter,
+                mLock);
+        mTSIBinder = telecomServiceImpl.getBinder();
+        mComponentContextFixture.setTelecomManager(mTelecomManager);
+        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+        when(mTelecomManager.getSystemDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
+        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        doReturn(DEFAULT_DIALER_PACKAGE)
+                .when(mDefaultDialerManagerAdapter)
+                .getDefaultDialerApplication(any(Context.class));
+
+        doReturn(true)
+                .when(mDefaultDialerManagerAdapter)
+                .isDefaultOrSystemDialer(any(Context.class), eq(DEFAULT_DIALER_PACKAGE));
+    }
+
+    public void testGetDefaultOutgoingPhoneAccount() throws RemoteException {
+        when(mFakePhoneAccountRegistrar
+                .getOutgoingPhoneAccountForScheme(eq("tel"), any(UserHandle.class)))
+                .thenReturn(TEL_PA_HANDLE_16);
+        when(mFakePhoneAccountRegistrar
+                .getOutgoingPhoneAccountForScheme(eq("sip"), any(UserHandle.class)))
+                .thenReturn(SIP_PA_HANDLE_17);
+        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
+
+        PhoneAccountHandle returnedHandleTel
+                = mTSIBinder.getDefaultOutgoingPhoneAccount("tel", DEFAULT_DIALER_PACKAGE);
+        assertEquals(TEL_PA_HANDLE_16, returnedHandleTel);
+
+        PhoneAccountHandle returnedHandleSip
+                = mTSIBinder.getDefaultOutgoingPhoneAccount("sip", DEFAULT_DIALER_PACKAGE);
+        assertEquals(SIP_PA_HANDLE_17, returnedHandleSip);
+    }
+
+    public void testGetDefaultOutgoingPhoneAccountFailure() throws RemoteException {
+        // make sure that the list of user profiles doesn't include anything the PhoneAccountHandles
+        // are associated with
+
+        when(mFakePhoneAccountRegistrar
+                .getOutgoingPhoneAccountForScheme(eq("tel"), any(UserHandle.class)))
+                .thenReturn(TEL_PA_HANDLE_16);
+        when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(TEL_PA_HANDLE_16)).thenReturn(
+                makePhoneAccount(TEL_PA_HANDLE_16).build());
+        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_READ_PHONE_STATE), anyInt(), anyString()))
+                .thenReturn(AppOpsManager.MODE_IGNORED);
+        doThrow(new SecurityException()).when(mContext)
+                .enforceCallingOrSelfPermission(eq(READ_PRIVILEGED_PHONE_STATE), anyString());
+
+        PhoneAccountHandle returnedHandleTel
+                = mTSIBinder.getDefaultOutgoingPhoneAccount("tel", "");
+        assertNull(returnedHandleTel);
+    }
+
+    public void testGetUserSelectedOutgoingPhoneAccount() throws RemoteException {
+        when(mFakePhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(any(UserHandle.class)))
+                .thenReturn(TEL_PA_HANDLE_16);
+        when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(TEL_PA_HANDLE_16)).thenReturn(
+                makeMultiUserPhoneAccount(TEL_PA_HANDLE_16).build());
+
+        PhoneAccountHandle returnedHandle
+                = mTSIBinder.getUserSelectedOutgoingPhoneAccount();
+        assertEquals(TEL_PA_HANDLE_16, returnedHandle);
+    }
+
+    public void testSetUserSelectedOutgoingPhoneAccount() throws RemoteException {
+        mTSIBinder.setUserSelectedOutgoingPhoneAccount(TEL_PA_HANDLE_16);
+        verify(mFakePhoneAccountRegistrar)
+                .setUserSelectedOutgoingPhoneAccount(eq(TEL_PA_HANDLE_16), any(UserHandle.class));
+    }
+
+    public void testSetUserSelectedOutgoingPhoneAccountFailure() throws RemoteException {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                anyString(), anyString());
+        try {
+            mTSIBinder.setUserSelectedOutgoingPhoneAccount(TEL_PA_HANDLE_16);
+        } catch (SecurityException e) {
+            // desired result
+        }
+        verify(mFakePhoneAccountRegistrar, never())
+                .setUserSelectedOutgoingPhoneAccount(
+                        any(PhoneAccountHandle.class), any(UserHandle.class));
+    }
+
+    public void testGetCallCapablePhoneAccounts() throws RemoteException {
+        List<PhoneAccountHandle> fullPHList = new ArrayList<PhoneAccountHandle>() {{
+            add(TEL_PA_HANDLE_16);
+            add(SIP_PA_HANDLE_17);
+        }};
+
+        List<PhoneAccountHandle> smallPHList = new ArrayList<PhoneAccountHandle>() {{
+            add(SIP_PA_HANDLE_17);
+        }};
+        // Returns all phone accounts when getCallCapablePhoneAccounts is called.
+        when(mFakePhoneAccountRegistrar
+                .getCallCapablePhoneAccounts(anyString(), eq(true), any(UserHandle.class)))
+                .thenReturn(fullPHList);
+        // Returns only enabled phone accounts when getCallCapablePhoneAccounts is called.
+        when(mFakePhoneAccountRegistrar
+                .getCallCapablePhoneAccounts(anyString(), eq(false), any(UserHandle.class)))
+                .thenReturn(smallPHList);
+        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
+
+        assertEquals(fullPHList,
+                mTSIBinder.getCallCapablePhoneAccounts(true, DEFAULT_DIALER_PACKAGE));
+        assertEquals(smallPHList,
+                mTSIBinder.getCallCapablePhoneAccounts(false, DEFAULT_DIALER_PACKAGE));
+    }
+
+    public void testGetCallCapablePhoneAccountsFailure() throws RemoteException {
+        List<String> enforcedPermissions = new ArrayList<String>() {{
+            add(READ_PHONE_STATE);
+            add(READ_PRIVILEGED_PHONE_STATE);
+        }};
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                argThat(new AnyStringIn(enforcedPermissions)), anyString());
+
+        List<PhoneAccountHandle> result = null;
+        try {
+            result = mTSIBinder.getCallCapablePhoneAccounts(true, "");
+        } catch (SecurityException e) {
+            // intended behavior
+        }
+        assertNull(result);
+        verify(mFakePhoneAccountRegistrar, never())
+                .getCallCapablePhoneAccounts(anyString(), anyBoolean(), any(UserHandle.class));
+    }
+
+    public void testGetPhoneAccountsSupportingScheme() throws RemoteException {
+        List<PhoneAccountHandle> sipPHList = new ArrayList<PhoneAccountHandle>() {{
+            add(SIP_PA_HANDLE_17);
+        }};
+
+        List<PhoneAccountHandle> telPHList = new ArrayList<PhoneAccountHandle>() {{
+            add(TEL_PA_HANDLE_16);
+        }};
+        when(mFakePhoneAccountRegistrar
+                .getCallCapablePhoneAccounts(eq("tel"), anyBoolean(), any(UserHandle.class)))
+                .thenReturn(telPHList);
+        when(mFakePhoneAccountRegistrar
+                .getCallCapablePhoneAccounts(eq("sip"), anyBoolean(), any(UserHandle.class)))
+                .thenReturn(sipPHList);
+        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
+
+        assertEquals(telPHList,
+                mTSIBinder.getPhoneAccountsSupportingScheme("tel", DEFAULT_DIALER_PACKAGE));
+        assertEquals(sipPHList,
+                mTSIBinder.getPhoneAccountsSupportingScheme("sip", DEFAULT_DIALER_PACKAGE));
+    }
+
+    public void testGetPhoneAccountsForPackage() throws RemoteException {
+        List<PhoneAccountHandle> phoneAccountHandleList = new ArrayList<PhoneAccountHandle>() {{
+            add(TEL_PA_HANDLE_16);
+            add(SIP_PA_HANDLE_17);
+        }};
+        when(mFakePhoneAccountRegistrar
+                .getPhoneAccountsForPackage(anyString(), any(UserHandle.class)))
+                .thenReturn(phoneAccountHandleList);
+        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
+        assertEquals(phoneAccountHandleList,
+                mTSIBinder.getPhoneAccountsForPackage(
+                        TEL_PA_HANDLE_16.getComponentName().getPackageName()));
+    }
+
+    public void testGetPhoneAccount() throws RemoteException {
+        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
+        assertEquals(TEL_PA_HANDLE_16, mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16)
+                .getAccountHandle());
+        assertEquals(SIP_PA_HANDLE_17, mTSIBinder.getPhoneAccount(SIP_PA_HANDLE_17)
+                .getAccountHandle());
+    }
+
+    public void testGetAllPhoneAccounts() throws RemoteException {
+        List<PhoneAccount> phoneAccountList = new ArrayList<PhoneAccount>() {{
+            add(makePhoneAccount(TEL_PA_HANDLE_16).build());
+            add(makePhoneAccount(SIP_PA_HANDLE_17).build());
+        }};
+        when(mFakePhoneAccountRegistrar.getAllPhoneAccounts(any(UserHandle.class)))
+                .thenReturn(phoneAccountList);
+
+        assertEquals(2, mTSIBinder.getAllPhoneAccounts().size());
+    }
+
+    public void testRegisterPhoneAccount() throws RemoteException {
+        String packageNameToUse = "com.android.officialpackage";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
+        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+
+        registerPhoneAccountTestHelper(phoneAccount, true);
+    }
+
+    public void testRegisterPhoneAccountWithoutModifyPermission() throws RemoteException {
+        // tests the case where the package does not have MODIFY_PHONE_STATE but is
+        // registering its own phone account as a third-party connection service
+        String packageNameToUse = "com.thirdparty.connectionservice";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
+        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
+
+        doReturn(PackageManager.PERMISSION_DENIED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+        PackageManager pm = mContext.getPackageManager();
+        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(true);
+
+        registerPhoneAccountTestHelper(phoneAccount, true);
+    }
+
+    public void testRegisterPhoneAccountWithoutModifyPermissionFailure() throws RemoteException {
+        // tests the case where the third party package should not be allowed to register a phone
+        // account due to the lack of modify permission.
+        String packageNameToUse = "com.thirdparty.connectionservice";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
+        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
+
+        doReturn(PackageManager.PERMISSION_DENIED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+        PackageManager pm = mContext.getPackageManager();
+        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(false);
+
+        registerPhoneAccountTestHelper(phoneAccount, false);
+    }
+
+    public void testRegisterPhoneAccountWithoutSimSubscriptionPermissionFailure()
+            throws RemoteException {
+        String packageNameToUse = "com.thirdparty.connectionservice";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
+        PhoneAccount phoneAccount = makePhoneAccount(phHandle)
+                .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION).build();
+
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+        doThrow(new SecurityException())
+                .when(mContext)
+                .enforceCallingOrSelfPermission(eq(REGISTER_SIM_SUBSCRIPTION), anyString());
+
+        registerPhoneAccountTestHelper(phoneAccount, false);
+    }
+
+    public void testRegisterPhoneAccountWithoutMultiUserPermissionFailure()
+            throws Exception {
+        String packageNameToUse = "com.thirdparty.connectionservice";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
+        PhoneAccount phoneAccount = makeMultiUserPhoneAccount(phHandle).build();
+
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+
+        PackageManager packageManager = mContext.getPackageManager();
+        when(packageManager.getApplicationInfo(packageNameToUse, PackageManager.GET_META_DATA))
+                .thenReturn(new ApplicationInfo());
+
+        registerPhoneAccountTestHelper(phoneAccount, false);
+    }
+
+    private void registerPhoneAccountTestHelper(PhoneAccount testPhoneAccount,
+            boolean shouldSucceed) throws RemoteException {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        boolean didExceptionOccur = false;
+        try {
+            mTSIBinder.registerPhoneAccount(testPhoneAccount);
+        } catch (Exception e) {
+            didExceptionOccur = true;
+        }
+
+        if (shouldSucceed) {
+            assertFalse(didExceptionOccur);
+            verify(mFakePhoneAccountRegistrar).registerPhoneAccount(testPhoneAccount);
+            verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
+                    anyString());
+
+            Intent capturedIntent = intentCaptor.getValue();
+            assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED,
+                    capturedIntent.getAction());
+            Bundle intentExtras = capturedIntent.getExtras();
+            assertEquals(1, intentExtras.size());
+            assertEquals(testPhoneAccount.getAccountHandle(),
+                    intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
+        } else {
+            assertTrue(didExceptionOccur);
+            verify(mFakePhoneAccountRegistrar, never())
+                    .registerPhoneAccount(any(PhoneAccount.class));
+            verify(mContext, never())
+                    .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
+        }
+    }
+
+    public void testUnregisterPhoneAccount() throws RemoteException {
+        String packageNameToUse = "com.android.officialpackage";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+
+        mTSIBinder.unregisterPhoneAccount(phHandle);
+        verify(mFakePhoneAccountRegistrar).unregisterPhoneAccount(phHandle);
+        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
+                anyString());
+        Intent capturedIntent = intentCaptor.getValue();
+        assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED,
+                capturedIntent.getAction());
+        Bundle intentExtras = capturedIntent.getExtras();
+        assertEquals(1, intentExtras.size());
+        assertEquals(phHandle, intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
+    }
+
+    public void testUnregisterPhoneAccountFailure() throws RemoteException {
+        String packageNameToUse = "com.thirdparty.connectionservice";
+        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
+                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
+
+        doReturn(PackageManager.PERMISSION_DENIED)
+                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
+        PackageManager pm = mContext.getPackageManager();
+        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(false);
+
+        try {
+            mTSIBinder.unregisterPhoneAccount(phHandle);
+        } catch (UnsupportedOperationException e) {
+            // expected behavior
+        }
+        verify(mFakePhoneAccountRegistrar, never())
+                .unregisterPhoneAccount(any(PhoneAccountHandle.class));
+        verify(mContext, never())
+                .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
+    }
+
+    public void testAddNewIncomingCall() throws Exception {
+        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
+        Bundle extras = createSampleExtras();
+
+        mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, extras);
+
+        addCallTestHelper(TelecomManager.ACTION_INCOMING_CALL,
+                CallIntentProcessor.KEY_IS_INCOMING_CALL, extras, false);
+    }
+
+    public void testAddNewIncomingCallFailure() throws Exception {
+        try {
+            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_16, null);
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
+
+        try {
+            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, null);
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        // Verify that neither of these attempts got through
+        verify(mCallIntentProcessorAdapter, never())
+                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
+    }
+
+    public void testAddNewUnknownCall() throws Exception {
+        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
+        Bundle extras = createSampleExtras();
+
+        mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, extras);
+
+        addCallTestHelper(TelecomManager.ACTION_NEW_UNKNOWN_CALL,
+                CallIntentProcessor.KEY_IS_UNKNOWN_CALL, extras, true);
+    }
+
+    public void testAddNewUnknownCallFailure() throws Exception {
+        try {
+            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_16, null);
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
+
+        try {
+            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, null);
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        // Verify that neither of these attempts got through
+        verify(mCallIntentProcessorAdapter, never())
+                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
+    }
+
+    private void addCallTestHelper(String expectedAction, String extraCallKey,
+            Bundle expectedExtras, boolean isUnknown) {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        if (isUnknown) {
+            verify(mCallIntentProcessorAdapter).processUnknownCallIntent(any(CallsManager.class),
+                    intentCaptor.capture());
+        } else {
+            verify(mCallIntentProcessorAdapter).processIncomingCallIntent(any(CallsManager.class),
+                    intentCaptor.capture());
+        }
+        Intent capturedIntent = intentCaptor.getValue();
+        assertEquals(expectedAction, capturedIntent.getAction());
+        Bundle intentExtras = capturedIntent.getExtras();
+        assertEquals(TEL_PA_HANDLE_CURRENT,
+                intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
+        assertTrue(intentExtras.getBoolean(extraCallKey));
+
+        if (isUnknown) {
+            for (String expectedKey : expectedExtras.keySet()) {
+                assertTrue(intentExtras.containsKey(expectedKey));
+                assertEquals(expectedExtras.get(expectedKey), intentExtras.get(expectedKey));
+            }
+        }
+        else {
+            assertTrue(areBundlesEqual(expectedExtras,
+                    (Bundle) intentExtras.get(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS)));
+        }
+    }
+
+    public void testPlaceCallWithNonEmergencyPermission() throws Exception {
+        Uri handle = Uri.parse("tel:6505551234");
+        Bundle extras = createSampleExtras();
+
+        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
+                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingPermission(CALL_PHONE);
+
+        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
+        placeCallTestHelper(handle, extras, true);
+    }
+
+    public void testPlaceCallWithAppOpsOff() throws Exception {
+        Uri handle = Uri.parse("tel:6505551234");
+        Bundle extras = createSampleExtras();
+
+        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
+                .thenReturn(AppOpsManager.MODE_IGNORED);
+        doReturn(PackageManager.PERMISSION_GRANTED)
+                .when(mContext).checkCallingPermission(CALL_PHONE);
+
+        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
+        placeCallTestHelper(handle, extras, false);
+    }
+
+    public void testPlaceCallWithNoCallingPermission() throws Exception {
+        Uri handle = Uri.parse("tel:6505551234");
+        Bundle extras = createSampleExtras();
+
+        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
+                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        doReturn(PackageManager.PERMISSION_DENIED)
+                .when(mContext).checkCallingPermission(CALL_PHONE);
+
+        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
+        placeCallTestHelper(handle, extras, false);
+    }
+
+    private void placeCallTestHelper(Uri expectedHandle, Bundle expectedExtras,
+            boolean shouldNonEmergencyBeAllowed) {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mUserCallIntentProcessor).processIntent(intentCaptor.capture(), anyString(),
+                eq(shouldNonEmergencyBeAllowed));
+        Intent capturedIntent = intentCaptor.getValue();
+        assertEquals(Intent.ACTION_CALL, capturedIntent.getAction());
+        assertEquals(expectedHandle, capturedIntent.getData());
+        assertTrue(areBundlesEqual(expectedExtras, capturedIntent.getExtras()));
+    }
+
+    public void testPlaceCallFailure() throws Exception {
+        Uri handle = Uri.parse("tel:6505551234");
+        Bundle extras = createSampleExtras();
+
+        doThrow(new SecurityException())
+                .when(mContext).enforceCallingOrSelfPermission(eq(CALL_PHONE), anyString());
+
+        try {
+            mTSIBinder.placeCall(handle, extras, "arbitrary_package_name");
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        verify(mUserCallIntentProcessor, never())
+                .processIntent(any(Intent.class), anyString(), anyBoolean());
+    }
+
+    public void testSetDefaultDialer() throws Exception {
+        String packageName = "sample.package";
+
+        doReturn(true)
+                .when(mDefaultDialerManagerAdapter)
+                .setDefaultDialerApplication(any(Context.class), eq(packageName));
+
+        mTSIBinder.setDefaultDialer(packageName);
+
+        verify(mDefaultDialerManagerAdapter).setDefaultDialerApplication(any(Context.class),
+                eq(packageName));
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), any(UserHandle.class));
+        Intent capturedIntent = intentCaptor.getValue();
+        assertEquals(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED, capturedIntent.getAction());
+        String packageNameExtra = capturedIntent.getStringExtra(
+                TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME);
+        assertEquals(packageName, packageNameExtra);
+    }
+
+    public void testSetDefaultDialerNoModifyPhoneStatePermission() throws Exception {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                eq(MODIFY_PHONE_STATE), anyString());
+        setDefaultDialerFailureTestHelper();
+    }
+
+    public void testSetDefaultDialerNoWriteSecureSetingsPermission() throws Exception {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                eq(WRITE_SECURE_SETTINGS), anyString());
+        setDefaultDialerFailureTestHelper();
+    }
+
+    private void setDefaultDialerFailureTestHelper() throws Exception {
+        boolean exceptionThrown = false;
+        try {
+            mTSIBinder.setDefaultDialer(DEFAULT_DIALER_PACKAGE);
+        } catch (SecurityException e) {
+            exceptionThrown = true;
+        }
+        assertTrue(exceptionThrown);
+        verify(mDefaultDialerManagerAdapter, never()).setDefaultDialerApplication(
+                any(Context.class), anyString());
+        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
+    }
+
+    /**
+     * Register phone accounts for the supplied PhoneAccountHandles to make them
+     * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
+     * @param handles the handles for which phone accounts should be created for.
+     */
+    private void makeAccountsVisibleToAllUsers(PhoneAccountHandle... handles) {
+        for (PhoneAccountHandle ph : handles) {
+            when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(eq(ph))).thenReturn(
+                    makeMultiUserPhoneAccount(ph).build());
+            when(mFakePhoneAccountRegistrar
+                    .getPhoneAccount(eq(ph), any(UserHandle.class), anyBoolean()))
+                    .thenReturn(makeMultiUserPhoneAccount(ph).build());
+        }
+    }
+
+    private PhoneAccount.Builder makeMultiUserPhoneAccount(PhoneAccountHandle paHandle) {
+        PhoneAccount.Builder paBuilder = makePhoneAccount(paHandle);
+        paBuilder.setCapabilities(PhoneAccount.CAPABILITY_MULTI_USER);
+        return paBuilder;
+    }
+
+    private PhoneAccount.Builder makePhoneAccount(PhoneAccountHandle paHandle) {
+        return new PhoneAccount.Builder(paHandle, "testLabel");
+    }
+
+    private Bundle createSampleExtras() {
+        Bundle extras = new Bundle();
+        extras.putString("test_key", "test_value");
+        return extras;
+    }
+
+    private static boolean areBundlesEqual(Bundle b1, Bundle b2) {
+        for (String key1 : b1.keySet()) {
+            if (!b1.get(key1).equals(b2.get(key1))) {
+                return false;
+            }
+        }
+
+        for (String key2 : b2.keySet()) {
+            if (!b2.get(key2).equals(b1.get(key2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 39aeb5d..7ebbb63 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -208,6 +208,8 @@
 
     TelecomSystem mTelecomSystem;
 
+    Context mSpyContext;
+
     private int mNumOutgoingCallsMade;
 
     class IdPair {
@@ -223,6 +225,9 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
+        mSpyContext = mComponentContextFixture.getTestDouble().getApplicationContext();
+        doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
+
         mNumOutgoingCallsMade = 0;
 
         // First set up information about the In-Call services in the mock Context, since
@@ -405,9 +410,6 @@
         verify(localAppContext).sendBroadcastAsUser(actionCallIntent, UserHandle.SYSTEM);
         mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
 
-        assertEquals(userHandle,
-                actionCallIntent.getParcelableExtra(CallIntentProcessor.KEY_INITIATING_USER));
-
         if (!hasInCallAdapter) {
             verify(mInCallServiceFixtureX.getTestDouble())
                     .setInCallAdapter(
diff --git a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
index 9c9d0d8..ee4b72e 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
@@ -33,6 +33,7 @@
         Log.setTag(TESTING_TAG);
         mMockitoHelper.setUp(getContext(), getClass());
         mComponentContextFixture = new ComponentContextFixture();
+        Log.setContext(mComponentContextFixture.getTestDouble().getApplicationContext());
         MockitoAnnotations.initMocks(this);
     }
 
