Merge "Update ringer to take BT device into account"
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index fc22127..e89075d 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -122,6 +122,30 @@
 
     private static final String TAG = "CallsManager";
 
+    /**
+     * Call filter specifier used with
+     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate only
+     * self-managed calls should be included.
+     */
+    private static final int CALL_FILTER_SELF_MANAGED = 1;
+
+    /**
+     * Call filter specifier used with
+     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate only
+     * managed calls should be included.
+     */
+    private static final int CALL_FILTER_MANAGED = 2;
+
+    /**
+     * Call filter specifier used with
+     * {@link #getNumCallsWithState(int, Call, PhoneAccountHandle, int...)} to indicate both managed
+     * and self-managed calls should be included.
+     */
+    private static final int CALL_FILTER_ALL = 3;
+
+    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
+            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
+
     private static final int HANDLER_WAIT_TIMEOUT = 10000;
     private static final int MAXIMUM_LIVE_CALLS = 1;
     private static final int MAXIMUM_HOLD_CALLS = 1;
@@ -135,10 +159,25 @@
             {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                     CallState.PULLING};
 
+    /**
+     * These states are used by {@link #makeRoomForOutgoingCall(Call, boolean)} to determine which
+     * call should be ended first to make room for a new outgoing call.
+     */
     private static final int[] LIVE_CALL_STATES =
             {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                     CallState.PULLING, CallState.ACTIVE};
 
+    /**
+     * These states determine which calls will cause {@link TelecomManager#isInCall()} or
+     * {@link TelecomManager#isInManagedCall()} to return true.
+     *
+     * See also {@link PhoneStateBroadcaster}, which considers a similar set of states as being
+     * off-hook.
+     */
+    public static final int[] ONGOING_CALL_STATES =
+            {CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING, CallState.PULLING, CallState.ACTIVE,
+                    CallState.ON_HOLD, CallState.RINGING};
+
     private static final int[] ANY_CALL_STATE =
             {CallState.NEW, CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
                     CallState.RINGING, CallState.ACTIVE, CallState.ON_HOLD, CallState.DISCONNECTED,
@@ -225,6 +264,21 @@
     private Runnable mStopTone;
 
     /**
+     * Listener to PhoneAccountRegistrar events.
+     */
+    private PhoneAccountRegistrar.Listener mPhoneAccountListener =
+            new PhoneAccountRegistrar.Listener() {
+        public void onPhoneAccountRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {
+            broadcastRegisterIntent(handle);
+        }
+        public void onPhoneAccountUnRegistered(PhoneAccountRegistrar registrar,
+                                               PhoneAccountHandle handle) {
+            broadcastUnregisterIntent(handle);
+        }
+    };
+
+    /**
      * Initializes the required Telecom components.
      */
     CallsManager(
@@ -252,6 +306,7 @@
         mContactsAsyncHelper = contactsAsyncHelper;
         mCallerInfoAsyncQueryFactory = callerInfoAsyncQueryFactory;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
+        mPhoneAccountRegistrar.addListener(mPhoneAccountListener);
         mMissedCallNotifier = missedCallNotifier;
         StatusBarNotifier statusBarNotifier = new StatusBarNotifier(context, this);
         mWiredHeadsetManager = wiredHeadsetManager;
@@ -2105,16 +2160,40 @@
 
     @VisibleForTesting
     public int getNumCallsWithState(final boolean isSelfManaged, Call excludeCall,
-                                     PhoneAccountHandle phoneAccountHandle, int... states) {
+                                    PhoneAccountHandle phoneAccountHandle, int... states) {
+        return getNumCallsWithState(isSelfManaged ? CALL_FILTER_SELF_MANAGED : CALL_FILTER_MANAGED,
+                excludeCall, phoneAccountHandle, states);
+    }
+
+    /**
+     * Determines the number of calls matching the specified criteria.
+     * @param callFilter indicates whether to include just managed calls
+     *                   ({@link #CALL_FILTER_MANAGED}), self-managed calls
+     *                   ({@link #CALL_FILTER_SELF_MANAGED}), or all calls
+     *                   ({@link #CALL_FILTER_ALL}).
+     * @param excludeCall Where {@code non-null}, this call is excluded from the count.
+     * @param phoneAccountHandle Where {@code non-null}, calls for this {@link PhoneAccountHandle}
+     *                           are excluded from the count.
+     * @param states The list of {@link CallState}s to include in the count.
+     * @return Count of calls matching criteria.
+     */
+    @VisibleForTesting
+    public int getNumCallsWithState(final int callFilter, Call excludeCall,
+                                    PhoneAccountHandle phoneAccountHandle, int... states) {
 
         Set<Integer> desiredStates = IntStream.of(states).boxed().collect(Collectors.toSet());
 
         Stream<Call> callsStream = mCalls.stream()
                 .filter(call -> desiredStates.contains(call.getState()) &&
-                        call.getParentCall() == null && !call.isExternalCall() &&
-                        call.isSelfManaged() == isSelfManaged);
+                        call.getParentCall() == null && !call.isExternalCall());
 
-        // If a call to exclude was specifeid, filter it out.
+        if (callFilter == CALL_FILTER_MANAGED) {
+            callsStream = callsStream.filter(call -> !call.isSelfManaged());
+        } else if (callFilter == CALL_FILTER_SELF_MANAGED) {
+            callsStream = callsStream.filter(call -> call.isSelfManaged());
+        }
+
+        // If a call to exclude was specified, filter it out.
         if (excludeCall != null) {
             callsStream = callsStream.filter(call -> call != excludeCall);
         }
@@ -2205,18 +2284,31 @@
     }
 
     /**
+     * Determines if there are any ongoing managed or self-managed calls.
+     * Note: The {@link #ONGOING_CALL_STATES} are
+     * @return {@code true} if there are ongoing managed or self-managed calls, {@code false}
+     *      otherwise.
+     */
+    public boolean hasOngoingCalls() {
+        return getNumCallsWithState(
+                CALL_FILTER_ALL, null /* excludeCall */,
+                null /* phoneAccountHandle */,
+                ONGOING_CALL_STATES) > 0;
+    }
+
+    /**
      * Determines if there are any ongoing managed calls.
      * @return {@code true} if there are ongoing managed calls, {@code false} otherwise.
      */
     public boolean hasOngoingManagedCalls() {
         return getNumCallsWithState(
-                false /* isSelfManaged */, null /* excludeCall */,
+                CALL_FILTER_MANAGED, null /* excludeCall */,
                 null /* phoneAccountHandle */,
-                LIVE_CALL_STATES) > 0;
+                ONGOING_CALL_STATES) > 0;
     }
 
     /**
-     * Deteremines if the system incoming call UI should be shown.
+     * Determines if the system incoming call UI should be shown.
      * The system incoming call UI will be shown if the new incoming call is self-managed, and there
      * are ongoing calls for another PhoneAccount.
      * @param incomingCall The incoming call.
@@ -2664,4 +2756,48 @@
             service.createConnectionFailed(call);
         }
     }
+
+    private void broadcastUnregisterIntent(PhoneAccountHandle accountHandle) {
+        Intent intent =
+                new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED);
+        intent.putExtra(
+                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+        Log.i(this, "Sending phone-account %s unregistered intent as user", accountHandle);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+
+        String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
+                getCurrentUserHandle().getIdentifier());
+        if (!TextUtils.isEmpty(dialerPackage)) {
+            Intent directedIntent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED)
+                    .setPackage(dialerPackage);
+            directedIntent.putExtra(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+            Log.i(this, "Sending phone-account unregistered intent to default dialer");
+            mContext.sendBroadcastAsUser(directedIntent, UserHandle.ALL, null);
+        }
+        return ;
+    }
+
+    private void broadcastRegisterIntent(PhoneAccountHandle accountHandle) {
+        Intent intent = new Intent(
+                TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
+        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+                accountHandle);
+        Log.i(this, "Sending phone-account %s registered intent as user", accountHandle);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+
+        String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
+                getCurrentUserHandle().getIdentifier());
+        if (!TextUtils.isEmpty(dialerPackage)) {
+            Intent directedIntent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED)
+                    .setPackage(dialerPackage);
+            directedIntent.putExtra(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+            Log.i(this, "Sending phone-account registered intent to default dialer");
+            mContext.sendBroadcastAsUser(directedIntent, UserHandle.ALL, null);
+        }
+        return ;
+    }
 }
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index af633fb..8cdec30 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -120,6 +120,10 @@
         public void onAccountsChanged(PhoneAccountRegistrar registrar) {}
         public void onDefaultOutgoingChanged(PhoneAccountRegistrar registrar) {}
         public void onSimCallManagerChanged(PhoneAccountRegistrar registrar) {}
+        public void onPhoneAccountRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {}
+        public void onPhoneAccountUnRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {}
     }
 
     /**
@@ -652,14 +656,17 @@
         // !!! IMPORTANT !!! It is important that we do not read the enabled state that the
         // source app provides or else an third party app could enable itself.
         boolean isEnabled = false;
+        boolean isNewAccount;
 
         PhoneAccount oldAccount = getPhoneAccountUnchecked(account.getAccountHandle());
         if (oldAccount != null) {
             mState.accounts.remove(oldAccount);
             isEnabled = oldAccount.isEnabled();
-            Log.i(this, getAccountDiffString(account, oldAccount));
+            Log.i(this, "Modify account: %s", getAccountDiffString(account, oldAccount));
+            isNewAccount = false;
         } else {
             Log.i(this, "New phone account registered: " + account);
+            isNewAccount = true;
         }
 
         // When registering a self-managed PhoneAccount we enforce the rule that the label that the
@@ -695,6 +702,9 @@
 
         write();
         fireAccountsChanged();
+        if (isNewAccount) {
+            fireAccountRegistered(account.getAccountHandle());
+        }
     }
 
     public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
@@ -703,6 +713,7 @@
             if (mState.accounts.remove(account)) {
                 write();
                 fireAccountsChanged();
+                fireAccountUnRegistered(accountHandle);
             }
         }
     }
@@ -748,6 +759,18 @@
         }
     }
 
+    private void fireAccountRegistered(PhoneAccountHandle handle) {
+        for (Listener l : mListeners) {
+            l.onPhoneAccountRegistered(this, handle);
+        }
+    }
+
+    private void fireAccountUnRegistered(PhoneAccountHandle handle) {
+        for (Listener l : mListeners) {
+            l.onPhoneAccountUnRegistered(this, handle);
+        }
+    }
+
     private void fireAccountsChanged() {
         for (Listener l : mListeners) {
             l.onAccountsChanged(this);
@@ -771,7 +794,6 @@
                 Log.piiHandle(account2.getAddress()));
         appendDiff(sb, "cap", account1.getCapabilities(), account2.getCapabilities());
         appendDiff(sb, "hl", account1.getHighlightColor(), account2.getHighlightColor());
-        appendDiff(sb, "icon", account1.getIcon(), account2.getIcon());
         appendDiff(sb, "lbl", account1.getLabel(), account2.getLabel());
         appendDiff(sb, "desc", account1.getShortDescription(), account2.getShortDescription());
         appendDiff(sb, "subAddr", Log.piiHandle(account1.getSubscriptionAddress()),
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index ae80350..d4e1096 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -48,6 +48,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.EventLog;
 
 // TODO: Needed for move to system service: import com.android.internal.R;
@@ -78,8 +79,6 @@
         }
     }
 
-    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
-            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
     private static final int DEFAULT_VIDEO_STATE = -1;
 
     private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
@@ -401,19 +400,6 @@
                         }
                         enforceUserHandleMatchesCaller(account.getAccountHandle());
                         mPhoneAccountRegistrar.registerPhoneAccount(account);
-                        // Broadcast an intent indicating the phone account which was registered.
-                        long token = Binder.clearCallingIdentity();
-                        try {
-                            Intent intent = new Intent(
-                                    TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
-                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
-                                    account.getAccountHandle());
-                            Log.i(this, "Sending phone-account registered intent as user");
-                            mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                                    PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
-                        } finally {
-                            Binder.restoreCallingIdentity(token);
-                        }
                     } catch (Exception e) {
                         Log.e(this, e, "registerPhoneAccount %s", account);
                         throw e;
@@ -433,20 +419,6 @@
                             accountHandle.getComponentName().getPackageName());
                     enforceUserHandleMatchesCaller(accountHandle);
                     mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
-
-                    // Broadcast an intent indicating the phone account which was unregistered.
-                    long token = Binder.clearCallingIdentity();
-                    try {
-                        Intent intent =
-                                new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED);
-                        intent.putExtra(
-                                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
-                        Log.i(this, "Sending phone-account unregistered intent as user");
-                        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
-                    } finally {
-                        Binder.restoreCallingIdentity(token);
-                    }
                 } catch (Exception e) {
                     Log.e(this, e, "unregisterPhoneAccount %s", accountHandle);
                     throw e;
@@ -667,9 +639,7 @@
                 }
 
                 synchronized (mLock) {
-                    final int callState = mCallsManager.getCallState();
-                    return callState == TelephonyManager.CALL_STATE_OFFHOOK
-                            || callState == TelephonyManager.CALL_STATE_RINGING;
+                    return mCallsManager.hasOngoingCalls();
                 }
             } finally {
                 Log.endSession();
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
index 494089b..e3d99d9 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
@@ -29,6 +29,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.IState;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.server.telecom.BluetoothHeadsetProxy;
@@ -43,6 +44,8 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 public class BluetoothRouteManager extends StateMachine {
     private static final String LOG_TAG = BluetoothRouteManager.class.getSimpleName();
@@ -581,8 +584,27 @@
         return mDeviceManager.getNumConnectedDevices() > 0;
     }
 
+    /**
+     * This method needs be synchronized with the local looper because getCurrentState() depends
+     * on the internal state of the state machine being consistent. Therefore, there may be a
+     * delay when calling this method.
+     * @return
+     */
     public boolean isBluetoothAudioConnectedOrPending() {
-        return getCurrentState() != mAudioOffState;
+        IState[] state = new IState[] {null};
+        CountDownLatch latch = new CountDownLatch(1);
+        Runnable r = () -> {
+            state[0] = getCurrentState();
+            latch.countDown();
+        };
+        sendMessage(RUN_RUNNABLE, r);
+        try {
+            latch.await(1000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Log.w(LOG_TAG, "isBluetoothAudioConnectedOrPending -- interrupted getting state");
+            return false;
+        }
+        return (state[0] != null) && (state[0] != mAudioOffState);
     }
 
     /**
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index ec49696..bfe8d0d 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -66,7 +66,8 @@
             <intent-filter>
                 <action android:name="android.server.telecom.testapps.ACTION_SEND_UPDATE_REQUEST_FROM_TEST_INCALL_SERVICE"/>
                 <action android:name="android.server.telecom.testapps.ACTION_SEND_UPGRADE_RESPONSE"/>
-                <data android:scheme="int" />
+                <action android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED"/>
+                <action android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED"/>
             </intent-filter>
         </receiver>
 
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
index b6902bf..3371060 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
@@ -19,6 +19,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.telecom.TelecomManager;
 import android.util.Log;
 
 /**
@@ -56,6 +57,12 @@
         } else if (ACTION_SEND_UPGRADE_RESPONSE.equals(action)) {
             final int videoState = Integer.parseInt(intent.getData().getSchemeSpecificPart());
             TestCallList.getInstance().sendUpgradeToVideoResponse(videoState);
+        } else if (TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED.equals(action)) {
+            Log.i(TAG, "onReceive: registered " + intent.getExtras().get(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
+        } else if (TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED.equals(action)) {
+            Log.i(TAG, "onReceive: unregistered " + intent.getExtras().get(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
         }
     }
 }
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
index bba7c5a..300415a 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
@@ -48,6 +48,7 @@
 import java.util.ArrayList;
 import java.util.LinkedList;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyChar;
@@ -190,7 +191,7 @@
         Call mockCall = createForegroundCall();
         PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
         when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
-                any(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
+                nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
 
         String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
 
@@ -211,7 +212,7 @@
         Call mockCall = createForegroundCall();
         PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
         when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
-                any(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
+                nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
 
         String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
 
@@ -223,9 +224,9 @@
         Call mockCall = createForegroundCall();
         String fakeNumber = "8675309";
         when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
-                any(PhoneAccountHandle.class))).thenReturn(null);
+                nullable(PhoneAccountHandle.class))).thenReturn(null);
         when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(
-                any(PhoneAccountHandle.class))).thenReturn(null);
+                nullable(PhoneAccountHandle.class))).thenReturn(null);
         when(TelephonyManager.from(mContext).getLine1Number()).thenReturn(fakeNumber);
 
         String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
@@ -297,7 +298,7 @@
         mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
         // Make sure the call has only occurred collectively 2 times (not on the third)
         verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
-                any(int.class), any(int.class), any(String.class), any(int.class));
+                any(int.class), any(int.class), nullable(String.class), any(int.class));
     }
 
     @MediumTest
@@ -401,7 +402,7 @@
                 "5550000", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
         verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), anyString(), anyInt());
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
     }
 
     @MediumTest
@@ -416,7 +417,7 @@
         mBluetoothPhoneService.mBinder.listCurrentCalls();
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
         verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), anyString(), anyInt());
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
     }
 
     @MediumTest
@@ -436,7 +437,7 @@
                 "5550000", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
         verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), anyString(), anyInt());
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
     }
 
     @MediumTest
@@ -490,7 +491,7 @@
                 "5550000", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
         verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), anyString(), anyInt());
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
     }
 
     @MediumTest
@@ -519,7 +520,7 @@
                 "5550001", PhoneNumberUtils.TOA_Unknown);
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
         verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
-                anyInt(), anyInt(), anyInt(), anyBoolean(), anyString(), anyInt());
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
     }
 
     @MediumTest
@@ -607,7 +608,7 @@
 
         boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
 
-        verify(mMockCallsManager).rejectCall(eq(ringingCall), eq(false), any(String.class));
+        verify(mMockCallsManager).rejectCall(eq(ringingCall), eq(false), nullable(String.class));
         assertEquals(didProcess, true);
     }
 
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
index e6cb7bf..9b94f63 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
@@ -39,9 +39,8 @@
 import java.util.List;
 import java.util.Objects;
 
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -228,7 +227,7 @@
                 BluetoothRouteManager.AUDIO_OFF_STATE_NAME, null);
         setupConnectedDevices(new BluetoothDevice[]{device1}, null);
         when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
-                any(ContentResolver.class))).thenReturn(0L);
+                nullable(ContentResolver.class))).thenReturn(0L);
         when(mHeadsetProxy.connectAudio()).thenReturn(false);
         executeRoutingAction(sm, BluetoothRouteManager.CONNECT_HFP, null);
         // Wait 3 times: for the first connection attempt, the retry attempt, and once more to
@@ -249,7 +248,7 @@
                 BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, device1);
         setupConnectedDevices(new BluetoothDevice[]{device1, device2}, null);
         when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
-                any(ContentResolver.class))).thenReturn(0L);
+                nullable(ContentResolver.class))).thenReturn(0L);
         when(mHeadsetProxy.connectAudio()).thenReturn(false);
         executeRoutingAction(sm, BluetoothRouteManager.CONNECT_HFP, device2.getAddress());
         // Wait 3 times: the first connection attempt is accounted for in executeRoutingAction,
@@ -426,7 +425,7 @@
             BluetoothDevice first = getFirstExcluding(devices,
                     (String) invocation.getArguments()[0]);
             return first == null ? null : first.getAddress();
-        }).when(mDeviceManager).getMostRecentlyConnectedDevice(anyString());
+        }).when(mDeviceManager).getMostRecentlyConnectedDevice(nullable(String.class));
     }
 
     private void executeRoutingAction(BluetoothRouteManager brm, int message, String device) {
@@ -457,9 +456,9 @@
         when(mDeviceManager.getHeadsetService()).thenReturn(mHeadsetProxy);
         when(mHeadsetProxy.connectAudio()).thenReturn(true);
         when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
-                any(ContentResolver.class))).thenReturn(100000L);
+                nullable(ContentResolver.class))).thenReturn(100000L);
         when(mTimeoutsAdapter.getBluetoothPendingTimeoutMillis(
-                any(ContentResolver.class))).thenReturn(100000L);
+                nullable(ContentResolver.class))).thenReturn(100000L);
     }
 
     private static BluetoothDevice getFirstExcluding(
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index 3767914..6782d52 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -48,6 +48,7 @@
 
 import java.util.Collections;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
@@ -110,11 +111,11 @@
 
         when(mDefaultDialerCache.getDefaultDialerApplication(eq(UserHandle.USER_CURRENT)))
                 .thenReturn(PKG_NAME);
-        when(mPackageManager.queryIntentServicesAsUser(any(Intent.class), anyInt(), anyInt()))
+        when(mPackageManager.queryIntentServicesAsUser(nullable(Intent.class), anyInt(), anyInt()))
                 .thenReturn(Collections.singletonList(mResolveInfo));
         when(mParcelableCallUtilsConverter.toParcelableCall(
                 eq(mCall), anyBoolean(), eq(mPhoneAccountRegistrar))).thenReturn(null);
-        when(mContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
+        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
                 anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
     }
 
@@ -128,7 +129,7 @@
 
     @SmallTest
     public void testNoResolveEntries() {
-        when(mPackageManager.queryIntentServicesAsUser(any(Intent.class), anyInt(), anyInt()))
+        when(mPackageManager.queryIntentServicesAsUser(nullable(Intent.class), anyInt(), anyInt()))
                 .thenReturn(Collections.emptyList());
         mFilter.startFilterLookup(mCall, mCallback);
         verify(mCallback).onCallFilteringComplete(eq(mCall), eq(PASS_RESULT));
@@ -150,7 +151,7 @@
 
     @SmallTest
     public void testContextFailToBind() {
-        when(mContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
+        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
                 anyInt(), eq(UserHandle.CURRENT))).thenReturn(false);
         mFilter.startFilterLookup(mCall, mCallback);
         verify(mCallback).onCallFilteringComplete(eq(mCall), eq(PASS_RESULT));
@@ -159,7 +160,7 @@
     @SmallTest
     public void testExceptionInScreeningService() throws Exception {
         doThrow(new RemoteException()).when(mCallScreeningService).screenCall(
-                any(ICallScreeningAdapter.class), any(ParcelableCall.class));
+                nullable(ICallScreeningAdapter.class), nullable(ParcelableCall.class));
         mFilter.startFilterLookup(mCall, mCallback);
         ServiceConnection serviceConnection = verifyBindingIntent();
         serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
@@ -214,7 +215,7 @@
     private ICallScreeningAdapter getCallScreeningAdapter() throws Exception {
         ArgumentCaptor<ICallScreeningAdapter> captor =
                 ArgumentCaptor.forClass(ICallScreeningAdapter.class);
-        verify(mCallScreeningService).screenCall(captor.capture(), any(ParcelableCall.class));
+        verify(mCallScreeningService).screenCall(captor.capture(), nullable(ParcelableCall.class));
         return captor.getValue();
     }
 }
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index fa5b6f0..255af74 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -37,6 +37,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -209,6 +210,11 @@
         }
 
         @Override
+        public ApplicationInfo getApplicationInfo() {
+            return mTestApplicationInfo;
+        }
+
+        @Override
         public ContentResolver getContentResolver() {
             return new ContentResolver(mApplicationContextSpy) {
                 @Override
@@ -423,6 +429,7 @@
     private final CountryDetector mCountryDetector = mock(CountryDetector.class);
     private final Map<String, IContentProvider> mIContentProviderByUri = new HashMap<>();
     private final Configuration mResourceConfiguration = new Configuration();
+    private final ApplicationInfo mTestApplicationInfo = new ApplicationInfo();
 
     private TelecomManager mTelecomManager = null;
 
diff --git a/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
index 0104172..350afa3 100644
--- a/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
+++ b/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
@@ -39,6 +39,7 @@
 
 import java.util.ArrayList;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -242,7 +243,7 @@
         // Put in a regular phone account to be sure it doesn't call that
         PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct");
         when(mMockAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
-                any(String.class))).thenReturn(pAHandle);
+                nullable(String.class))).thenReturn(pAHandle);
         // Include a normal Connection Manager to be sure it doesn't call that
         PhoneAccount callManagerPA = getNewConnectionManagerPhoneAccount("cm_acct", 0);
         // Include a connection Manager for the user with the capability to make calls
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index c44f92c..eb0c419 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -60,6 +60,7 @@
 import java.util.Collections;
 import java.util.LinkedList;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
@@ -406,11 +407,11 @@
         when(mMockCall.isIncoming()).thenReturn(true);
         when(mMockCall.isExternalCall()).thenReturn(false);
         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
-        when(mMockContext.bindServiceAsUser(
-                any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
+        when(mMockContext.bindServiceAsUser(nullable(Intent.class),
+                nullable(ServiceConnection.class), anyInt(), nullable(UserHandle.class)))
                 .thenReturn(true);
-        when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(any(ContentResolver.class)))
-                .thenReturn(500L);
+        when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
+                nullable(ContentResolver.class))).thenReturn(500L);
 
         when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
         setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
@@ -438,7 +439,7 @@
         when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
 
         serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
-        verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
+        verify(mockInCallService).setInCallAdapter(nullable(IInCallAdapter.class));
         verify(mMockContext, never()).unbindService(serviceConnection);
         verify(mockInCallService, never()).addCall(any(ParcelableCall.class));
 
diff --git a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
index 13a85af..0baad91 100644
--- a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
@@ -60,6 +60,7 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
@@ -207,9 +208,9 @@
         ArgumentCaptor<Integer> requestIdCaptor = ArgumentCaptor.forClass(
                 Integer.class);
         verify(mNotificationManager, times(2)).notifyAsUser(isNull(String.class),
-                requestIdCaptor.capture(), any(Notification.class), eq(userHandle));
-        verify(mNotificationManager).cancelAsUser(any(String.class), eq(requestIdCaptor.getValue()),
-                eq(userHandle));
+                requestIdCaptor.capture(), nullable(Notification.class), eq(userHandle));
+        verify(mNotificationManager).cancelAsUser(nullable(String.class),
+                eq(requestIdCaptor.getValue()), eq(userHandle));
 
         // Verify that the second call to showMissedCallNotification behaves like it were the first.
         verify(builder2).setContentText(CALLER_NAME);
@@ -423,15 +424,15 @@
                         CallLog.Calls.PRESENTATION_ALLOWED, CALL_TIMESTAMP)
                 .build();
 
-        when(cp.query(anyString(), eq(queryUri), any(String[].class), anyString(), any
-                (String[].class), anyString(), any(ICancellationSignal.class)))
+        when(cp.query(anyString(), eq(queryUri), nullable(String[].class), nullable(String.class),
+                nullable(String[].class), nullable(String.class), any(ICancellationSignal.class)))
                 .thenReturn(mockMissedCallsCursor);
 
         PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY);
         MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE,
                 CALLER_NAME, CALL_TIMESTAMP, phoneAccount.getAccountHandle());
-        when(mockCallInfoFactory.makeCallInfo(any(CallerInfo.class),
-                any(PhoneAccountHandle.class), any(Uri.class), eq(CALL_TIMESTAMP)))
+        when(mockCallInfoFactory.makeCallInfo(nullable(CallerInfo.class),
+                nullable(PhoneAccountHandle.class), nullable(Uri.class), eq(CALL_TIMESTAMP)))
                 .thenReturn(fakeCallInfo);
 
         Notification.Builder builder1 = makeNotificationBuilder("builder1");
@@ -491,15 +492,15 @@
                 PRIMARY_USER.getIdentifier());
         IContentProvider cp = getContentProviderForUser(PRIMARY_USER.getIdentifier());
 
-        when(cp.query(anyString(), eq(queryUri), any(String[].class), anyString(), any
-                (String[].class), anyString(), any(ICancellationSignal.class)))
+        when(cp.query(anyString(), eq(queryUri), nullable(String[].class), nullable(String.class),
+                nullable(String[].class), nullable(String.class), any(ICancellationSignal.class)))
                 .thenReturn(mockMissedCallsCursor);
 
         PhoneAccount phoneAccount = makePhoneAccount(PRIMARY_USER, NO_CAPABILITY);
         MissedCallNotifier.CallInfo fakeCallInfo = makeFakeCallInfo(TEL_CALL_HANDLE,
                 CALLER_NAME, CALL_TIMESTAMP, phoneAccount.getAccountHandle());
-        when(mockCallInfoFactory.makeCallInfo(any(CallerInfo.class),
-                any(PhoneAccountHandle.class), any(Uri.class), eq(CALL_TIMESTAMP)))
+        when(mockCallInfoFactory.makeCallInfo(nullable(CallerInfo.class),
+                nullable(PhoneAccountHandle.class), nullable(Uri.class), eq(CALL_TIMESTAMP)))
                 .thenReturn(fakeCallInfo);
 
         Notification.Builder builder1 = makeNotificationBuilder("builder1");
@@ -534,7 +535,7 @@
 
         // Verify that two notifications were generated, both with the same id.
         verify(mNotificationManager, times(2)).notifyAsUser(isNull(String.class), eq(1),
-                any(Notification.class), eq(PRIMARY_USER));
+                nullable(Notification.class), eq(PRIMARY_USER));
     }
 
     private Notification.Builder makeNotificationBuilder(String label) {
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 9b7dc37..b23664d 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -43,6 +43,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
@@ -100,7 +101,7 @@
 
         assertEquals(DisconnectCause.NOT_DISCONNECTED, result);
         verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(Uri.parse(voicemailNumber)),
-                any(GatewayInfo.class), eq(true), eq(VideoProfile.STATE_AUDIO_ONLY));
+                nullable(GatewayInfo.class), eq(true), eq(VideoProfile.STATE_AUDIO_ONLY));
     }
 
     @SmallTest
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 3d2a52e..fb4c118 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -64,6 +64,7 @@
 
 import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
@@ -253,7 +254,7 @@
     @SmallTest
     public void testSetUserSelectedOutgoingPhoneAccountFailure() throws RemoteException {
         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
-                anyString(), anyString());
+                anyString(), nullable(String.class));
         try {
             mTSIBinder.setUserSelectedOutgoingPhoneAccount(TEL_PA_HANDLE_16);
         } catch (SecurityException e) {
@@ -276,12 +277,12 @@
         }};
         // Returns all phone accounts when getCallCapablePhoneAccounts is called.
         when(mFakePhoneAccountRegistrar
-                .getCallCapablePhoneAccounts(anyString(), eq(true), any(UserHandle.class)))
-                .thenReturn(fullPHList);
+                .getCallCapablePhoneAccounts(nullable(String.class), eq(true),
+                        nullable(UserHandle.class))).thenReturn(fullPHList);
         // Returns only enabled phone accounts when getCallCapablePhoneAccounts is called.
         when(mFakePhoneAccountRegistrar
-                .getCallCapablePhoneAccounts(anyString(), eq(false), any(UserHandle.class)))
-                .thenReturn(smallPHList);
+                .getCallCapablePhoneAccounts(nullable(String.class), eq(false),
+                        nullable(UserHandle.class))).thenReturn(smallPHList);
         makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
 
         assertEquals(fullPHList,
@@ -428,7 +429,8 @@
                 .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
         doThrow(new SecurityException())
                 .when(mContext)
-                .enforceCallingOrSelfPermission(eq(REGISTER_SIM_SUBSCRIPTION), anyString());
+                .enforceCallingOrSelfPermission(eq(REGISTER_SIM_SUBSCRIPTION),
+                        nullable(String.class));
 
         registerPhoneAccountTestHelper(phoneAccount, false);
     }
@@ -722,14 +724,14 @@
     @SmallTest
     public void testSetDefaultDialerNoModifyPhoneStatePermission() throws Exception {
         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
-                eq(MODIFY_PHONE_STATE), anyString());
+                eq(MODIFY_PHONE_STATE), nullable(String.class));
         setDefaultDialerFailureTestHelper();
     }
 
     @SmallTest
     public void testSetDefaultDialerNoWriteSecureSettingsPermission() throws Exception {
         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
-                eq(WRITE_SECURE_SETTINGS), anyString());
+                eq(WRITE_SECURE_SETTINGS), nullable(String.class));
         setDefaultDialerFailureTestHelper();
     }
 
@@ -854,21 +856,19 @@
     @SmallTest
     public void testAcceptRingingCall() throws Exception {
         Call call = mock(Call.class);
-        when(mFakeCallsManager.getFirstCallWithState(any(int[].class)))
-                .thenReturn(call);
+        when(mFakeCallsManager.getFirstCallWithState(anyInt())).thenReturn(call);
         // Not intended to be a real video state. Here to ensure that the call will be answered
         // with whatever video state it's currently in.
         int fakeVideoState = 29578215;
         when(call.getVideoState()).thenReturn(fakeVideoState);
         mTSIBinder.acceptRingingCall();
-        verify(call).answer(fakeVideoState);
+        verify(call).answer(eq(fakeVideoState));
     }
 
     @SmallTest
     public void testAcceptRingingCallWithValidVideoState() throws Exception {
         Call call = mock(Call.class);
-        when(mFakeCallsManager.getFirstCallWithState(any(int[].class)))
-                .thenReturn(call);
+        when(mFakeCallsManager.getFirstCallWithState(anyInt())).thenReturn(call);
         // Not intended to be a real video state. Here to ensure that the call will be answered
         // with the video state passed in to acceptRingingCallWithVideoState
         int fakeVideoState = 29578215;
@@ -878,6 +878,56 @@
         verify(call).answer(realVideoState);
     }
 
+    @SmallTest
+    public void testIsInCall() throws Exception {
+        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(true);
+        assertTrue(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
+    }
+
+    @SmallTest
+    public void testNotIsInCall() throws Exception {
+        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(false);
+        assertFalse(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
+    }
+
+    @SmallTest
+    public void testIsInCallFail() throws Exception {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                anyString(), any());
+        try {
+            mTSIBinder.isInCall("blah");
+            fail();
+        } catch (SecurityException e) {
+            // desired result
+        }
+        verify(mFakeCallsManager, never()).hasOngoingCalls();
+    }
+
+    @SmallTest
+    public void testIsInManagedCall() throws Exception {
+        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(true);
+        assertTrue(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
+    }
+
+    @SmallTest
+    public void testNotIsInManagedCall() throws Exception {
+        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(false);
+        assertFalse(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
+    }
+
+    @SmallTest
+    public void testIsInManagedCallFail() throws Exception {
+        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+                anyString(), any());
+        try {
+            mTSIBinder.isInManagedCall("blah");
+            fail();
+        } catch (SecurityException e) {
+            // desired result
+        }
+        verify(mFakeCallsManager, never()).hasOngoingCalls();
+    }
+
     /**
      * Register phone accounts for the supplied PhoneAccountHandles to make them
      * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
@@ -888,10 +938,10 @@
             when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(eq(ph))).thenReturn(
                     makeMultiUserPhoneAccount(ph).build());
             when(mFakePhoneAccountRegistrar
-                    .getPhoneAccount(eq(ph), any(UserHandle.class), anyBoolean()))
+                    .getPhoneAccount(eq(ph), nullable(UserHandle.class), anyBoolean()))
                     .thenReturn(makeMultiUserPhoneAccount(ph).build());
             when(mFakePhoneAccountRegistrar
-                    .getPhoneAccount(eq(ph), any(UserHandle.class)))
+                    .getPhoneAccount(eq(ph), nullable(UserHandle.class)))
                     .thenReturn(makeMultiUserPhoneAccount(ph).build());
         }
     }
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 11e0dc5..c7cb941 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -17,6 +17,7 @@
 package com.android.server.telecom.tests;
 
 
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
@@ -662,10 +663,10 @@
                         anyString(),
                         anyInt(),
                         newOutgoingCallReceiver.capture(),
-                        any(Handler.class),
+                        nullable(Handler.class),
                         anyInt(),
                         anyString(),
-                        any(Bundle.class));
+                        nullable(Bundle.class));
 
         // Pass on the new outgoing call Intent
         // Set a dummy PendingResult so the BroadcastReceiver agrees to accept onReceive()
diff --git a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
index f6734c7..3234c1f 100644
--- a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
+++ b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
@@ -173,6 +173,8 @@
         doThrow(new SecurityException()).when(mContext)
                 .enforcePermission(anyString(), anyInt(), anyInt(), anyString());
 
+        // Set the target SDK version to to > N-MR1.
+        mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
         // Make a request to change the camera
         mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
         mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
@@ -199,6 +201,8 @@
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOpsManager).noteOp(anyInt(), anyInt(),
                 anyString());
 
+        // Set the target SDK version to > N-MR1.
+        mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
         // Make a request to change the camera
         mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
         mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
@@ -213,6 +217,36 @@
     }
 
     /**
+     * Tests the caller app ops check in {@link VideoCall#setCamera(String)} to ensure a camera
+     * change from a non-permitted caller is ignored. For < N-MR1, throw a CAMERA_FAILURE instead
+     * of a CAMERA_PERMISSION_ERROR.
+     */
+    @MediumTest
+    public void testCameraChangeAppOpsBelowNMR1Fail() throws Exception {
+        // Wait until the callback has been received before performing verification.
+        doAnswer(mVerification).when(mVideoCallCallback).onCallSessionEvent(anyInt());
+
+        // ensure app ops check fails.
+        doReturn(AppOpsManager.MODE_ERRORED).when(mAppOpsManager).noteOp(anyInt(), anyInt(),
+                anyString());
+
+        // Set the target SDK version to below N-MR1
+        mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.N);
+
+        // Make a request to change the camera
+        mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
+        mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
+
+        // Capture the session event reported via the callback.
+        ArgumentCaptor<Integer> sessionEventCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mVideoCallCallback, timeout(TEST_TIMEOUT)).onCallSessionEvent(
+                sessionEventCaptor.capture());
+
+        assertEquals(VideoProvider.SESSION_EVENT_CAMERA_FAILURE,
+                sessionEventCaptor.getValue().intValue());
+    }
+
+    /**
      * Tests the caller user handle check in {@link VideoCall#setCamera(String)} to ensure a camera
      * change from a background user is not permitted.
      */
@@ -224,6 +258,8 @@
         // Set a fake user to be the current foreground user.
         mTelecomSystem.getCallsManager().onUserSwitch(new UserHandle(1000));
 
+        // Set the target SDK version to > N-MR1
+        mVideoCallImpl.setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
         // Make a request to change the camera
         mVideoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
         mVerificationLock.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);