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);