Merge "Ims: Add support for Adhoc Conference calls"
diff --git a/src/com/android/server/telecom/BluetoothAdapterProxy.java b/src/com/android/server/telecom/BluetoothAdapterProxy.java
index 72962b8..41b4faa 100644
--- a/src/com/android/server/telecom/BluetoothAdapterProxy.java
+++ b/src/com/android/server/telecom/BluetoothAdapterProxy.java
@@ -17,6 +17,7 @@
package com.android.server.telecom;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
@@ -37,4 +38,11 @@
}
return mBluetoothAdapter.getProfileProxy(context, listener, profile);
}
+
+ public boolean setActiveDevice(BluetoothDevice device, int profiles) {
+ if (mBluetoothAdapter == null) {
+ return false;
+ }
+ return mBluetoothAdapter.setActiveDevice(device, profiles);
+ }
}
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index a52f662..e158230 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -137,6 +137,7 @@
void onPhoneAccountChanged(Call call);
void onConferenceableCallsChanged(Call call);
void onConferenceStateChanged(Call call, boolean isConference);
+ void onCdmaConferenceSwap(Call call);
boolean onCanceledViaNewOutgoingCallBroadcast(Call call, long disconnectionTimeout);
void onHoldToneRequested(Call call);
void onCallHoldFailed(Call call);
@@ -209,6 +210,8 @@
@Override
public void onConferenceStateChanged(Call call, boolean isConference) {}
@Override
+ public void onCdmaConferenceSwap(Call call) {}
+ @Override
public boolean onCanceledViaNewOutgoingCallBroadcast(Call call, long disconnectionTimeout) {
return false;
}
@@ -2507,6 +2510,9 @@
mConferenceLevelActiveCall = null;
break;
}
+ for (Listener l : mListeners) {
+ l.onCdmaConferenceSwap(this);
+ }
}
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 8d79ef2..024a863 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -53,7 +53,6 @@
import android.os.PersistableBundle;
import android.os.Process;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.SystemVibrator;
import android.os.Trace;
import android.os.UserHandle;
@@ -62,6 +61,7 @@
import android.provider.BlockedNumberContract.SystemContract;
import android.provider.CallLog.Calls;
import android.provider.Settings;
+import android.sysprop.TelephonyProperties;
import android.telecom.CallAudioState;
import android.telecom.Conference;
import android.telecom.Connection;
@@ -85,8 +85,6 @@
import com.android.internal.annotations.VisibleForTesting;
import android.telecom.CallerInfo;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
@@ -167,6 +165,7 @@
void onDisconnectedTonePlaying(boolean isTonePlaying);
void onConnectionTimeChanged(Call call);
void onConferenceStateChanged(Call call, boolean isConference);
+ void onCdmaConferenceSwap(Call call);
}
/** Interface used to define the action which is executed delay under some condition. */
@@ -242,15 +241,15 @@
public static final String TELECOM_CALL_ID_PREFIX = "TC@";
- // Maps call technologies in PhoneConstants to those in Analytics.
+ // Maps call technologies in TelephonyManager to those in Analytics.
private static final Map<Integer, Integer> sAnalyticsTechnologyMap;
static {
sAnalyticsTechnologyMap = new HashMap<>(5);
- sAnalyticsTechnologyMap.put(PhoneConstants.PHONE_TYPE_CDMA, Analytics.CDMA_PHONE);
- sAnalyticsTechnologyMap.put(PhoneConstants.PHONE_TYPE_GSM, Analytics.GSM_PHONE);
- sAnalyticsTechnologyMap.put(PhoneConstants.PHONE_TYPE_IMS, Analytics.IMS_PHONE);
- sAnalyticsTechnologyMap.put(PhoneConstants.PHONE_TYPE_SIP, Analytics.SIP_PHONE);
- sAnalyticsTechnologyMap.put(PhoneConstants.PHONE_TYPE_THIRD_PARTY,
+ sAnalyticsTechnologyMap.put(TelephonyManager.PHONE_TYPE_CDMA, Analytics.CDMA_PHONE);
+ sAnalyticsTechnologyMap.put(TelephonyManager.PHONE_TYPE_GSM, Analytics.GSM_PHONE);
+ sAnalyticsTechnologyMap.put(TelephonyManager.PHONE_TYPE_IMS, Analytics.IMS_PHONE);
+ sAnalyticsTechnologyMap.put(TelephonyManager.PHONE_TYPE_SIP, Analytics.SIP_PHONE);
+ sAnalyticsTechnologyMap.put(TelephonyManager.PHONE_TYPE_THIRD_PARTY,
Analytics.THIRD_PARTY_PHONE);
}
@@ -930,6 +929,14 @@
}
@Override
+ public void onCdmaConferenceSwap(Call call) {
+ // SWAP was executed on a CDMA conference
+ for (CallsManagerListener listener : mListeners) {
+ listener.onCdmaConferenceSwap(call);
+ }
+ }
+
+ @Override
public void onIsVoipAudioModeChanged(Call call) {
for (CallsManagerListener listener : mListeners) {
listener.onIsVoipAudioModeChanged(call);
@@ -1225,8 +1232,10 @@
}
}
- if (extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, false)) {
- Log.i(this, "Incoming call requesting RTT");
+ boolean isRttSettingOn = isRttSettingOn(phoneAccountHandle);
+ if (isRttSettingOn ||
+ extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, false)) {
+ Log.i(this, "Incoming call requesting RTT, rtt setting is %b", isRttSettingOn);
call.createRttStreams();
// Even if the phone account doesn't support RTT yet, the connection manager might
// change that. Set this to check it later.
@@ -1700,9 +1709,12 @@
boolean isVoicemail = isVoicemail(callToUse.getHandle(), accountToUse);
- if (!isVoicemail && extras != null
- && extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, false)) {
- Log.d(this, "Outgoing call requesting RTT");
+ boolean isRttSettingOn = isRttSettingOn(phoneAccountHandle);
+ if (!isVoicemail && (isRttSettingOn || (extras != null
+ && extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT,
+ false)))) {
+ Log.d(this, "Outgoing call requesting RTT, rtt setting is %b",
+ isRttSettingOn);
if (callToUse.isEmergencyCall() || (accountToUse != null
&& accountToUse.hasCapabilities(PhoneAccount.CAPABILITY_RTT))) {
// If the call requested RTT and it's an emergency call, ignore the
@@ -2092,7 +2104,10 @@
// Auto-enable speakerphone if the originating intent specified to do so, if the call
// is a video call, of if using speaker when docked
- call.setStartWithSpeakerphoneOn(speakerphoneOn || useSpeakerForVideoCall
+ PhoneAccount account = mPhoneAccountRegistrar.getPhoneAccount(
+ call.getTargetPhoneAccount(), call.getInitiatingUser());
+ boolean allowVideo = account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING);
+ call.setStartWithSpeakerphoneOn(speakerphoneOn || (useSpeakerForVideoCall && allowVideo)
|| (useSpeakerWhenDocked && useSpeakerForDock));
call.setVideoState(videoState);
@@ -2326,9 +2341,9 @@
* @return {@code true} if the speakerphone should automatically be enabled.
*/
private static boolean isSpeakerEnabledForVideoCalls() {
- return (SystemProperties.getInt(TelephonyProperties.PROPERTY_VIDEOCALL_AUDIO_OUTPUT,
- PhoneConstants.AUDIO_OUTPUT_DEFAULT) ==
- PhoneConstants.AUDIO_OUTPUT_ENABLE_SPEAKER);
+ return TelephonyProperties.videocall_audio_output()
+ .orElse(TelecomManager.AUDIO_OUTPUT_DEFAULT)
+ == TelecomManager.AUDIO_OUTPUT_ENABLE_SPEAKER;
}
/**
@@ -2641,6 +2656,24 @@
mProximitySensorManager.turnOff(screenOnImmediately);
}
+ private boolean isRttSettingOn(PhoneAccountHandle handle) {
+ boolean isRttModeSettingOn = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.RTT_CALLING_MODE, 0) != 0;
+ // If the carrier config says that we should ignore the RTT mode setting from the user,
+ // assume that it's off (i.e. only make an RTT call if it's requested through the extra).
+ boolean shouldIgnoreRttModeSetting = getCarrierConfigForPhoneAccount(handle)
+ .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL, false);
+ return isRttModeSettingOn && !shouldIgnoreRttModeSetting;
+ }
+
+ private PersistableBundle getCarrierConfigForPhoneAccount(PhoneAccountHandle handle) {
+ int subscriptionId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(handle);
+ CarrierConfigManager carrierConfigManager =
+ mContext.getSystemService(CarrierConfigManager.class);
+ PersistableBundle result = carrierConfigManager.getConfigForSubId(subscriptionId);
+ return result == null ? new PersistableBundle() : result;
+ }
+
void phoneAccountSelected(Call call, PhoneAccountHandle account, boolean setDefault) {
if (!mCalls.contains(call)) {
Log.i(this, "Attempted to add account to unknown call %s", call);
diff --git a/src/com/android/server/telecom/CallsManagerListenerBase.java b/src/com/android/server/telecom/CallsManagerListenerBase.java
index 4fa2ee5..e0d2831 100644
--- a/src/com/android/server/telecom/CallsManagerListenerBase.java
+++ b/src/com/android/server/telecom/CallsManagerListenerBase.java
@@ -100,4 +100,8 @@
@Override
public void onConferenceStateChanged(Call call, boolean isConference) {
}
+
+ @Override
+ public void onCdmaConferenceSwap(Call call) {
+ }
}
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 9fc06e4..b18c6ff 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -865,7 +865,7 @@
info.isExternalCallsSupported(), includeRttCall,
info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
try {
- inCallService.addCall(parcelableCall);
+ inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
}
@@ -929,7 +929,7 @@
info.isExternalCallsSupported(), includeRttCall,
info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
try {
- inCallService.addCall(parcelableCall);
+ inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
}
@@ -961,7 +961,8 @@
);
try {
- inCallService.updateCall(parcelableCall);
+ inCallService.updateCall(
+ sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
}
@@ -1046,6 +1047,12 @@
updateCall(call);
}
+ @Override
+ public void onCdmaConferenceSwap(Call call) {
+ Log.d(this, "onCdmaConferenceSwap %s", call);
+ updateCall(call);
+ }
+
void bringToForeground(boolean showDialpad) {
if (!mInCallServices.isEmpty()) {
for (IInCallService inCallService : mInCallServices.values()) {
@@ -1446,13 +1453,14 @@
// Track the call if we don't already know about it.
addCall(call);
numCallsSent += 1;
- inCallService.addCall(ParcelableCallUtils.toParcelableCall(
+ ParcelableCall parcelableCall = ParcelableCallUtils.toParcelableCall(
call,
true /* includeVideoProvider */,
mCallsManager.getPhoneAccountRegistrar(),
info.isExternalCallsSupported(),
includeRttCall,
- info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI));
+ info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
}
@@ -1522,7 +1530,8 @@
componentsUpdated.add(componentName);
try {
- inCallService.updateCall(parcelableCall);
+ inCallService.updateCall(
+ sanitizeParcelableCallForService(info, parcelableCall));
} catch (RemoteException ignored) {
}
}
@@ -1654,6 +1663,21 @@
return childCalls;
}
+ private ParcelableCall sanitizeParcelableCallForService(
+ InCallServiceInfo info, ParcelableCall parcelableCall) {
+ ParcelableCall.ParcelableCallBuilder builder =
+ ParcelableCall.ParcelableCallBuilder.fromParcelableCall(parcelableCall);
+ // Check for contacts permission. If it's not there, remove the contactsDisplayName.
+ PackageManager pm = mContext.getPackageManager();
+ if (pm.checkPermission(Manifest.permission.READ_CONTACTS,
+ info.getComponentName().getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+ builder.setContactDisplayName(null);
+ }
+
+ // TODO: move all the other service-specific sanitizations in here
+ return builder.createParcelableCall();
+ }
+
@VisibleForTesting
public Handler getHandler() {
return mHandler;
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index 3a366aa..d1d8f0d 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -29,14 +29,10 @@
import android.telecom.TelecomManager;
import android.text.TextUtils;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
/**
* Utilities dealing with {@link ParcelableCall}.
@@ -224,6 +220,11 @@
callDirection = DIRECTION_OUTGOING;
}
+ String activeChildCallId = null;
+ if (call.getConferenceLevelActiveCall() != null) {
+ activeChildCallId = call.getConferenceLevelActiveCall().getId();
+ }
+
Bundle extras;
if (isForSystemDialer) {
extras = call.getExtras();
@@ -231,35 +232,38 @@
extras = sanitizeExtras(call.getExtras());
}
- return new ParcelableCall(
- call.getId(),
- state,
- call.getDisconnectCause(),
- call.getCannedSmsResponses(),
- capabilities,
- properties,
- supportedAudioRoutes,
- connectTimeMillis,
- handle,
- call.getHandlePresentation(),
- callerDisplayName,
- call.getCallerDisplayNamePresentation(),
- call.getGatewayInfo(),
- call.getTargetPhoneAccount(),
- includeVideoProvider,
- includeVideoProvider ? call.getVideoProvider() : null,
- includeRttCall,
- rttCall,
- parentCallId,
- childCallIds,
- call.getStatusHints(),
- call.getVideoState(),
- conferenceableCallIds,
- call.getIntentExtras(),
- extras,
- call.getCreationTimeMillis(),
- callDirection,
- call.getCallerNumberVerificationStatus());
+ return new ParcelableCall.ParcelableCallBuilder()
+ .setId(call.getId())
+ .setState(state)
+ .setDisconnectCause(call.getDisconnectCause())
+ .setCannedSmsResponses(call.getCannedSmsResponses())
+ .setCapabilities(capabilities)
+ .setProperties(properties)
+ .setSupportedAudioRoutes(supportedAudioRoutes)
+ .setConnectTimeMillis(connectTimeMillis)
+ .setHandle(handle)
+ .setHandlePresentation(call.getHandlePresentation())
+ .setCallerDisplayName(callerDisplayName)
+ .setCallerDisplayNamePresentation(call.getCallerDisplayNamePresentation())
+ .setGatewayInfo(call.getGatewayInfo())
+ .setAccountHandle(call.getTargetPhoneAccount())
+ .setIsVideoCallProviderChanged(includeVideoProvider)
+ .setVideoCallProvider(includeVideoProvider ? call.getVideoProvider() : null)
+ .setIsRttCallChanged(includeRttCall)
+ .setRttCall(rttCall)
+ .setParentCallId(parentCallId)
+ .setChildCallIds(childCallIds)
+ .setStatusHints(call.getStatusHints())
+ .setVideoState(call.getVideoState())
+ .setConferenceableCallIds(conferenceableCallIds)
+ .setIntentExtras(call.getIntentExtras())
+ .setExtras(extras)
+ .setCreationTimeMillis(call.getCreationTimeMillis())
+ .setCallDirection(callDirection)
+ .setCallerNumberVerificationStatus(call.getCallerNumberVerificationStatus())
+ .setContactDisplayName(call.getName())
+ .setActiveChildCallId(activeChildCallId)
+ .createParcelableCall();
}
/**
@@ -303,35 +307,38 @@
callExtras = new Bundle();
}
- return new ParcelableCall(
- call.getId(),
- getParcelableState(call, false /* supportsExternalCalls */),
- new DisconnectCause(DisconnectCause.UNKNOWN),
- null, /* cannedSmsResponses */
- 0, /* capabilities */
- 0, /* properties */
- 0, /* supportedAudioRoutes */
- call.getConnectTimeMillis(),
- handle,
- call.getHandlePresentation(),
- null, /* callerDisplayName */
- 0 /* callerDisplayNamePresentation */,
- null, /* gatewayInfo */
- null, /* targetPhoneAccount */
- false, /* includeVideoProvider */
- null, /* videoProvider */
- false, /* includeRttCall */
- null, /* rttCall */
- null, /* parentCallId */
- null, /* childCallIds */
- null, /* statusHints */
- 0, /* videoState */
- Collections.emptyList(), /* conferenceableCallIds */
- null, /* intentExtras */
- callExtras, /* callExtras */
- call.getCreationTimeMillis(),
- callDirection,
- call.getCallerNumberVerificationStatus());
+ return new ParcelableCall.ParcelableCallBuilder()
+ .setId(call.getId())
+ .setState(getParcelableState(call, false /* supportsExternalCalls */))
+ .setDisconnectCause(new DisconnectCause(DisconnectCause.UNKNOWN))
+ .setCannedSmsResponses(null)
+ .setCapabilities(0)
+ .setProperties(0)
+ .setSupportedAudioRoutes(0)
+ .setConnectTimeMillis(call.getConnectTimeMillis())
+ .setHandle(handle)
+ .setHandlePresentation(call.getHandlePresentation())
+ .setCallerDisplayName(null)
+ .setCallerDisplayNamePresentation(0)
+ .setGatewayInfo(null)
+ .setAccountHandle(null)
+ .setIsVideoCallProviderChanged(false)
+ .setVideoCallProvider(null)
+ .setIsRttCallChanged(false)
+ .setRttCall(null)
+ .setParentCallId(null)
+ .setChildCallIds(null)
+ .setStatusHints(null)
+ .setVideoState(0)
+ .setConferenceableCallIds(Collections.emptyList())
+ .setIntentExtras(null)
+ .setExtras(callExtras)
+ .setCreationTimeMillis(call.getCreationTimeMillis())
+ .setCallDirection(callDirection)
+ .setCallerNumberVerificationStatus(call.getCallerNumberVerificationStatus())
+ .setContactDisplayName(null)
+ .setActiveChildCallId(null)
+ .createParcelableCall();
}
/**
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
index 92de536..7fd600c 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
@@ -16,6 +16,7 @@
package com.android.server.telecom.bluetooth;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
@@ -119,9 +120,11 @@
private BluetoothHeadsetProxy mBluetoothHeadsetService;
private BluetoothHearingAid mBluetoothHearingAidService;
private BluetoothDevice mBluetoothHearingAidActiveDeviceCache;
+ private BluetoothAdapterProxy mBluetoothAdapterProxy;
public BluetoothDeviceManager(Context context, BluetoothAdapterProxy bluetoothAdapter) {
if (bluetoothAdapter != null) {
+ mBluetoothAdapterProxy = bluetoothAdapter;
bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
BluetoothProfile.HEADSET);
bluetoothAdapter.getProfileProxy(context, mBluetoothProfileServiceListener,
@@ -246,7 +249,8 @@
} else {
for (BluetoothDevice device : mBluetoothHearingAidService.getActiveDevices()) {
if (device != null) {
- mBluetoothHearingAidService.setActiveDevice(null);
+ mBluetoothAdapterProxy.setActiveDevice(null,
+ BluetoothAdapter.ACTIVE_DEVICE_ALL);
}
}
}
@@ -269,15 +273,17 @@
Log.w(this, "Attempting to turn on audio when the hearing aid service is null");
return false;
}
- return mBluetoothHearingAidService.setActiveDevice(
- mHearingAidDevicesByAddress.get(address));
+ return mBluetoothAdapterProxy.setActiveDevice(
+ mHearingAidDevicesByAddress.get(address),
+ BluetoothAdapter.ACTIVE_DEVICE_ALL);
} else if (mHfpDevicesByAddress.containsKey(address)) {
BluetoothDevice device = mHfpDevicesByAddress.get(address);
if (mBluetoothHeadsetService == null) {
Log.w(this, "Attempting to turn on audio when the headset service is null");
return false;
}
- boolean success = mBluetoothHeadsetService.setActiveDevice(device);
+ boolean success = mBluetoothAdapterProxy.setActiveDevice(device,
+ BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL);
if (!success) {
Log.w(this, "Couldn't set active device to %s", address);
return false;
@@ -304,7 +310,9 @@
public void restoreHearingAidDevice() {
if (mBluetoothHearingAidActiveDeviceCache != null && mBluetoothHearingAidService != null) {
- mBluetoothHearingAidService.setActiveDevice(mBluetoothHearingAidActiveDeviceCache);
+ mBluetoothAdapterProxy.setActiveDevice(
+ mBluetoothHearingAidActiveDeviceCache,
+ BluetoothAdapter.ACTIVE_DEVICE_ALL);
mBluetoothHearingAidActiveDeviceCache = null;
}
}
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
index 7671abd..8a14cbd 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
@@ -146,6 +146,10 @@
if (device == null) {
mBluetoothRouteManager.sendMessage(BT_AUDIO_LOST, args);
} else {
+ if (!mIsInCall) {
+ Log.i(LOG_TAG, "Ignoring hearing aid audio on since we're not in a call");
+ return;
+ }
args.arg2 = device.getAddress();
mBluetoothRouteManager.sendMessage(BT_AUDIO_IS_ON, args);
}
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
index 63ff962..bfa7a75 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
@@ -16,6 +16,7 @@
package com.android.server.telecom.tests;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
@@ -59,7 +60,7 @@
BluetoothDeviceManager mBluetoothDeviceManager;
BluetoothProfile.ServiceListener serviceListenerUnderTest;
- BroadcastReceiver receiverUnderTest;
+ BluetoothStateReceiver receiverUnderTest;
private BluetoothDevice device1;
private BluetoothDevice device2;
@@ -90,8 +91,7 @@
serviceCaptor.capture(), eq(BluetoothProfile.HEADSET));
serviceListenerUnderTest = serviceCaptor.getValue();
- receiverUnderTest = new BluetoothStateReceiver(mBluetoothDeviceManager,
- null /* route mgr not needed here */);
+ receiverUnderTest = new BluetoothStateReceiver(mBluetoothDeviceManager, mRouteManager);
mBluetoothDeviceManager.setHeadsetServiceForTesting(mHeadsetProxy);
mBluetoothDeviceManager.setHearingAidServiceForTesting(mBluetoothHearingAid);
@@ -198,15 +198,28 @@
@SmallTest
@Test
+ public void testHearingAidChangesIgnoredWhenNotInCall() {
+ receiverUnderTest.setIsInCall(false);
+ receiverUnderTest.onReceive(mContext,
+ buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, true));
+ Intent activeDeviceChangedIntent =
+ new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
+ activeDeviceChangedIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device2);
+ receiverUnderTest.onReceive(mContext, activeDeviceChangedIntent);
+
+ verify(mRouteManager).onActiveDeviceChanged(device2, true);
+ verify(mRouteManager, never()).sendMessage(BluetoothRouteManager.BT_AUDIO_IS_ON);
+ }
+
+ @SmallTest
+ @Test
public void testConnectDisconnectAudioHeadset() {
receiverUnderTest.onReceive(mContext,
buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, false));
- when(mHeadsetProxy.setActiveDevice(nullable(BluetoothDevice.class))).thenReturn(true);
+ when(mAdapterProxy.setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true);
mBluetoothDeviceManager.connectAudio(device1.getAddress());
- verify(mHeadsetProxy).setActiveDevice(device1);
- verify(mHeadsetProxy).connectAudio();
- verify(mBluetoothHearingAid, never()).setActiveDevice(nullable(BluetoothDevice.class));
-
+ verify(mAdapterProxy).setActiveDevice(device1, BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL);
+ verify(mAdapterProxy, never()).setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_ALL));
mBluetoothDeviceManager.disconnectAudio();
verify(mHeadsetProxy).disconnectAudio();
}
@@ -217,14 +230,14 @@
receiverUnderTest.onReceive(mContext,
buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, true));
mBluetoothDeviceManager.connectAudio(device2.getAddress());
- verify(mBluetoothHearingAid).setActiveDevice(device2);
+ verify(mAdapterProxy).setActiveDevice(device2, BluetoothAdapter.ACTIVE_DEVICE_ALL);
verify(mHeadsetProxy, never()).connectAudio();
- verify(mHeadsetProxy, never()).setActiveDevice(nullable(BluetoothDevice.class));
+ verify(mAdapterProxy, never()).setActiveDevice(nullable(BluetoothDevice.class), eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL));
when(mBluetoothHearingAid.getActiveDevices()).thenReturn(Arrays.asList(device2, null));
mBluetoothDeviceManager.disconnectAudio();
- verify(mBluetoothHearingAid).setActiveDevice(null);
+ verify(mAdapterProxy).setActiveDevice(null, BluetoothAdapter.ACTIVE_DEVICE_ALL);
verify(mHeadsetProxy).disconnectAudio();
}
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index ef294bd..e6fa1d0 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -42,9 +42,9 @@
import android.os.Bundle;
import android.os.Process;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.telecom.CallerInfo;
import android.telecom.Connection;
-import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -1195,6 +1195,22 @@
assertTrue(ongoingCall.isVideoCallingSupportedByPhoneAccount());
}
+ /**
+ * Verifies that speakers is disabled when there's no video capabilities, even if a video call
+ * tried to place.
+ * @throws Exception
+ */
+ @SmallTest
+ @Test
+ public void testSpeakerDisabledWhenNoVideoCapabilities() throws Exception {
+ Call outgoingCall = addSpyCall(CallState.NEW);
+ when(mPhoneAccountRegistrar.getPhoneAccount(
+ any(PhoneAccountHandle.class), any(UserHandle.class))).thenReturn(SIM_1_ACCOUNT);
+ mCallsManager.placeOutgoingCall(outgoingCall, TEST_ADDRESS, null, true,
+ VideoProfile.STATE_TX_ENABLED);
+ assertFalse(outgoingCall.getStartWithSpeakerphoneOn());
+ }
+
private Call addSpyCall() {
return addSpyCall(SIM_2_HANDLE, CallState.ACTIVE);
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index ed36d29..23d22e9 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -625,6 +625,44 @@
verifyBinding(bindIntentCaptor, 0, DEF_PKG, DEF_CLASS);
}
+ @MediumTest
+ @Test
+ public void testSanitizeContactName() throws Exception {
+ setupMocks(false /* isExternalCall */);
+ setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
+ when(mMockPackageManager.checkPermission(
+ matches(Manifest.permission.READ_CONTACTS),
+ matches(DEF_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
+ when(mMockCall.getName()).thenReturn("evil");
+
+ mInCallController.bindToServices(mMockCall);
+
+ // Bind InCallServices
+ ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
+ ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
+ ArgumentCaptor.forClass(ServiceConnection.class);
+ verify(mMockContext, times(1)).bindServiceAsUser(
+ bindIntentCaptor.capture(),
+ serviceConnectionCaptor.capture(),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
+ eq(UserHandle.CURRENT));
+ assertEquals(1, bindIntentCaptor.getAllValues().size());
+ verifyBinding(bindIntentCaptor, 0, DEF_PKG, DEF_CLASS);
+
+ IInCallService.Stub mockInCallServiceStub = mock(IInCallService.Stub.class);
+ IInCallService mockInCallService = mock(IInCallService.class);
+ when(mockInCallServiceStub.queryLocalInterface(anyString())).thenReturn(mockInCallService);
+ serviceConnectionCaptor.getValue().onServiceConnected(new ComponentName(DEF_PKG, DEF_CLASS),
+ mockInCallServiceStub);
+
+ mInCallController.onCallAdded(mMockCall);
+ ArgumentCaptor<ParcelableCall> parcelableCallCaptor =
+ ArgumentCaptor.forClass(ParcelableCall.class);
+ verify(mockInCallService).addCall(parcelableCallCaptor.capture());
+ assertTrue(TextUtils.isEmpty(parcelableCallCaptor.getValue().getContactDisplayName()));
+ }
+
/**
* Ensures that the {@link InCallController} will bind to a higher priority car mode service
* when one becomes available.