Merge ab/7061308 into stage.
Bug: 180401296
Merged-In: I1f3c96de396b9bfbdee7496ae8e4e6691b7f9a8a
Change-Id: I47955dade0e6fa63283bfea5ef28e563a3fdcf44
diff --git a/Android.bp b/Android.bp
index 0d89b00..b7eb450 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
genrule {
name: "statslog-telecom-java-gen",
tools: ["stats-log-api-gen"],
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 8b7c37d..d6780ed 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -548,17 +548,19 @@
private String getInCallServicesString() {
StringBuilder s = new StringBuilder();
s.append("[\n");
- for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) {
- s.append(" ");
- s.append("name: ");
- s.append(service.getInCallServiceName());
- s.append(" type: ");
- s.append(service.getInCallServiceType());
- s.append(" is crashed: ");
- s.append(service.getIsNullBinding());
- s.append(" service last time in ms: ");
- s.append(service.getBoundDurationMillis());
- s.append("\n");
+ if (inCallServiceInfos != null) {
+ for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) {
+ s.append(" ");
+ s.append("name: ");
+ s.append(service.getInCallServiceName());
+ s.append(" type: ");
+ s.append(service.getInCallServiceType());
+ s.append(" is crashed: ");
+ s.append(service.getIsNullBinding());
+ s.append(" service last time in ms: ");
+ s.append(service.getBoundDurationMillis());
+ s.append("\n");
+ }
}
s.append("]");
return s.toString();
@@ -631,7 +633,7 @@
}
public static CallInfo initiateCallAnalytics(String callId, int direction) {
- Log.d(TAG, "Starting analytics for call " + callId);
+ Log.i(TAG, "Starting analytics for call " + callId);
CallInfoImpl callInfo = new CallInfoImpl(callId, direction);
synchronized (sLock) {
while (sActiveCallIds.size() >= MAX_NUM_CALLS_TO_STORE) {
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index ffcdca9..c5f3bde 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -44,6 +44,7 @@
import android.telecom.ConnectionService;
import android.telecom.DisconnectCause;
import android.telecom.GatewayInfo;
+import android.telecom.InCallService;
import android.telecom.Log;
import android.telecom.Logging.EventManager;
import android.telecom.ParcelableConference;
@@ -58,6 +59,7 @@
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
@@ -510,6 +512,15 @@
private boolean mIsSelfManaged = false;
/**
+ * Indicates whether the {@link PhoneAccount} associated with an self-managed call want to
+ * expose the call to an {@link android.telecom.InCallService} which declares the metadata
+ * {@link TelecomManager#METADATA_INCLUDE_SELF_MANAGED_CALLS},
+ * For calls that {@link #mIsSelfManaged} is {@code false}, this value should be {@code false}
+ * as well.
+ */
+ private boolean mVisibleToInCallService = false;
+
+ /**
* Indicates whether the {@link PhoneAccount} associated with this call supports video calling.
* {@code True} if the phone account supports video calling, {@code false} otherwise.
*/
@@ -624,6 +635,18 @@
private long mStartRingTime;
/**
+ * The package name of the call screening service that silence this call. If the call is not
+ * silenced, this field will be null.
+ */
+ private CharSequence mCallScreeningAppName;
+
+ /**
+ * The component name of the call screening service that silence this call. If the call is not
+ * silenced, this field will be null.
+ */
+ private String mCallScreeningComponentName;
+
+ /**
* Persists the specified parameters and initializes the new instance.
* @param context The context.
* @param repository The connection service repository.
@@ -1616,6 +1639,14 @@
setConnectionProperties(getConnectionProperties());
}
+ public boolean visibleToInCallService() {
+ return mVisibleToInCallService;
+ }
+
+ public void setVisibleToInCallService(boolean visibleToInCallService) {
+ mVisibleToInCallService = visibleToInCallService;
+ }
+
public void markFinishedHandoverStateAndCleanup(int handoverState) {
if (mHandoverSourceCall != null) {
mHandoverSourceCall.setHandoverState(handoverState);
@@ -3906,6 +3937,10 @@
mMissedReason = missedReason;
}
+ public void setUserMissed(long code) {
+ mMissedReason |= code;
+ }
+
public long getStartRingTime() {
return mStartRingTime;
}
@@ -3913,4 +3948,33 @@
public void setStartRingTime(long startRingTime) {
mStartRingTime = startRingTime;
}
+
+ public CharSequence getCallScreeningAppName() {
+ return mCallScreeningAppName;
+ }
+
+ public void setCallScreeningAppName(CharSequence callScreeningAppName) {
+ mCallScreeningAppName = callScreeningAppName;
+ }
+
+ public String getCallScreeningComponentName() {
+ return mCallScreeningComponentName;
+ }
+
+ public void setCallScreeningComponentName(String callScreeningComponentName) {
+ mCallScreeningComponentName = callScreeningComponentName;
+ }
+
+ public void maybeOnInCallServiceTrackingChanged(boolean isTracking, boolean hasUi) {
+ if (mConnectionService == null) {
+ Log.w(this, "maybeOnInCallServiceTrackingChanged() request on a call"
+ + " without a connection service.");
+ } else {
+ if (hasUi) {
+ mConnectionService.onUsingAlternativeUi(this, isTracking);
+ } else if (isTracking) {
+ mConnectionService.onTrackedByNonUiService(this, isTracking);
+ }
+ }
+ }
}
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 69a870f..bcfdedf 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -1272,6 +1272,7 @@
return HANDLED;
case SWITCH_FOCUS:
if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
+ setSpeakerphoneOn(true);
transitionTo(mActiveSpeakerRoute);
}
return HANDLED;
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 7305ab9..7f864b8 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -141,6 +141,23 @@
clientExtras.putString(TelecomManager.EXTRA_CALL_SUBJECT, callsubject);
}
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_PRIORITY)) {
+ clientExtras.putInt(android.telecom.TelecomManager.EXTRA_PRIORITY, intent.getIntExtra(
+ android.telecom.TelecomManager.EXTRA_PRIORITY,
+ android.telecom.TelecomManager.PRIORITY_NORMAL));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_LOCATION)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_LOCATION,
+ intent.getParcelableExtra(android.telecom.TelecomManager.EXTRA_LOCATION));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE,
+ intent.getParcelableExtra(
+ android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE));
+ }
+
final int videoState = intent.getIntExtra( TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
VideoProfile.STATE_AUDIO_ONLY);
clientExtras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index cedd41c..3cec618 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -358,8 +358,10 @@
call.wasVolte());
if (result == null) {
- // Call auto missed before filtered
- result = new CallFilteringResult.Builder().build();
+ result = new CallFilteringResult.Builder()
+ .setCallScreeningAppName(call.getCallScreeningAppName())
+ .setCallScreeningComponentName(call.getCallScreeningComponentName())
+ .build();
}
if (callLogType == Calls.BLOCKED_TYPE || callLogType == Calls.MISSED_TYPE) {
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 6b99633..5b3c2f7 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -31,6 +31,8 @@
import static android.provider.CallLog.Calls.AUTO_MISSED_EMERGENCY_CALL;
import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_DIALING;
import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_RINGING;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
import android.Manifest;
import android.annotation.NonNull;
@@ -106,7 +108,6 @@
import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
import com.android.server.telecom.callfiltering.DirectToVoicemailFilter;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
@@ -356,7 +357,6 @@
private final DisconnectedCallNotifier mDisconnectedCallNotifier;
private IncomingCallNotifier mIncomingCallNotifier;
private final CallerInfoLookupHelper mCallerInfoLookupHelper;
- private final IncomingCallFilter.Factory mIncomingCallFilterFactory;
private final DefaultDialerCache mDefaultDialerCache;
private final Timeouts.Adapter mTimeoutsAdapter;
private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
@@ -488,7 +488,6 @@
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
InCallControllerFactory inCallControllerFactory,
RoleManagerAdapter roleManagerAdapter,
- IncomingCallFilter.Factory incomingCallFilterFactory,
ToastFactory toastFactory) {
mContext = context;
mLock = lock;
@@ -506,7 +505,6 @@
mTimeoutsAdapter = timeoutsAdapter;
mEmergencyCallHelper = emergencyCallHelper;
mCallerInfoLookupHelper = callerInfoLookupHelper;
- mIncomingCallFilterFactory = incomingCallFilterFactory;
mDtmfLocalTonePlayer =
new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
@@ -673,7 +671,7 @@
.setShouldReject(false)
.setShouldAddToCallLog(true)
.setShouldShowNotification(true)
- .build());
+ .build(), false);
incomingCall.setIsUsingCallFiltering(false);
return;
}
@@ -739,13 +737,19 @@
}
@Override
- public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {
+ public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result,
+ boolean timeout) {
// Only set the incoming call as ringing if it isn't already disconnected. It is possible
// that the connection service disconnected the call before it was even added to Telecom, in
// which case it makes no sense to set it back to a ringing state.
Log.i(this, "onCallFilteringComplete");
mGraphHandlerThreads.clear();
+ if (timeout) {
+ Log.i(this, "onCallFilteringCompleted: Call filters timeout!");
+ incomingCall.setUserMissed(USER_MISSED_CALL_FILTERS_TIMEOUT);
+ }
+
if (incomingCall.getState() != CallState.DISCONNECTED &&
incomingCall.getState() != CallState.DISCONNECTING) {
setCallState(incomingCall, CallState.RINGING,
@@ -759,6 +763,7 @@
incomingCall.setPostCallPackageName(
getRoleManagerAdapter().getDefaultCallScreeningApp());
+ Log.i(this, "onCallFilteringComplete: allow call.");
if (hasMaximumManagedRingingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
incomingCall.silence();
@@ -767,6 +772,7 @@
"Exceeds maximum number of ringing calls.");
incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING);
autoMissCallAndLog(incomingCall, result);
+ return;
}
} else if (hasMaximumManagedDialingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
@@ -776,6 +782,7 @@
"dialing calls.");
incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_DIALING);
autoMissCallAndLog(incomingCall, result);
+ return;
}
} else if (result.shouldScreenViaAudio) {
Log.i(this, "onCallFilteringCompleted: starting background audio processing");
@@ -784,6 +791,9 @@
} else if (result.shouldSilence) {
Log.i(this, "onCallFilteringCompleted: setting the call to silent ringing state");
incomingCall.setSilentRingingRequested(true);
+ incomingCall.setUserMissed(USER_MISSED_CALL_SCREENING_SERVICE_SILENCED);
+ incomingCall.setCallScreeningAppName(result.mCallScreeningAppName);
+ incomingCall.setCallScreeningComponentName(result.mCallScreeningComponentName);
addCall(incomingCall);
} else {
addCall(incomingCall);
@@ -1227,10 +1237,14 @@
PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
phoneAccountHandle);
if (phoneAccount != null) {
+ Bundle phoneAccountExtras = phoneAccount.getExtras();
call.setIsSelfManaged(phoneAccount.isSelfManaged());
if (call.isSelfManaged()) {
// Self managed calls will always be voip audio mode.
call.setIsVoipAudioMode(true);
+ call.setVisibleToInCallService(phoneAccountExtras != null
+ && phoneAccountExtras.getBoolean(
+ PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true));
} else {
// Incoming call is managed, the active call is self-managed and can't be held.
// We need to set extras on it to indicate whether answering will cause a
@@ -1249,7 +1263,6 @@
}
}
- Bundle phoneAccountExtras = phoneAccount.getExtras();
if (phoneAccountExtras != null
&& phoneAccountExtras.getBoolean(
PhoneAccount.EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE)) {
@@ -1353,6 +1366,7 @@
// call UI during an emergency call. In this case, log the call as missed instead of
// rejected since the user did not explicitly reject.
call.setMissedReason(AUTO_MISSED_EMERGENCY_CALL);
+ call.getAnalytics().setMissedReason(call.getMissedReason());
mCallLogManager.logCall(call, Calls.MISSED_TYPE,
true /*showNotificationForMissedCall*/, null /*CallFilteringResult*/);
if (isConference) {
@@ -1463,6 +1477,7 @@
PhoneAccount account =
mPhoneAccountRegistrar.getPhoneAccount(requestedAccountHandle, initiatingUser);
+ Bundle phoneAccountExtra = account != null ? account.getExtras() : null;
boolean isSelfManaged = account != null && account.isSelfManaged();
// Create a call with original handle. The handle may be changed when the call is attached
@@ -1493,6 +1508,9 @@
if (isSelfManaged) {
// Self-managed calls will ALWAYS use voip audio mode.
call.setIsVoipAudioMode(true);
+ call.setVisibleToInCallService(phoneAccountExtra != null
+ && phoneAccountExtra.getBoolean(
+ PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true));
}
call.setInitiatingUser(initiatingUser);
isReusedCall = false;
@@ -3017,9 +3035,10 @@
*
* @param disconnectCause The disconnect cause, see {@link android.telecom.DisconnectCause}.
*/
- void markCallAsDisconnected(Call call, DisconnectCause disconnectCause) {
- int oldState = call.getState();
- if (call.getState() == CallState.SIMULATED_RINGING
+ @VisibleForTesting
+ public void markCallAsDisconnected(Call call, DisconnectCause disconnectCause) {
+ int oldState = call.getState();
+ if (call.getState() == CallState.SIMULATED_RINGING
&& disconnectCause.getCode() == DisconnectCause.REMOTE) {
// If the remote end hangs up while in SIMULATED_RINGING, the call should
// be marked as missed.
@@ -3487,7 +3506,7 @@
@VisibleForTesting
public void addCall(Call call) {
Trace.beginSection("addCall");
- Log.v(this, "addCall(%s)", call);
+ Log.i(this, "addCall(%s)", call);
call.addListener(this);
mCalls.add(call);
@@ -3599,10 +3618,14 @@
(newState == CallState.DISCONNECTED)) {
maybeSendPostCallScreenIntent(call);
}
- if (((newState == CallState.ABORTED) || (newState == CallState.DISCONNECTED))
- && (call.getDisconnectCause().getCode() != DisconnectCause.MISSED)) {
+ int disconnectCode = call.getDisconnectCause().getCode();
+ if ((newState == CallState.ABORTED || newState == CallState.DISCONNECTED)
+ && ((disconnectCode != DisconnectCause.MISSED)
+ && (disconnectCode != DisconnectCause.CANCELED))) {
call.setMissedReason(MISSED_REASON_NOT_MISSED);
}
+ call.getAnalytics().setMissedReason(call.getMissedReason());
+
maybeShowErrorDialogOnDisconnect(call);
Trace.beginSection("onCallStateChanged");
@@ -4724,6 +4747,9 @@
extras.putLong(TelecomManager.EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS,
SystemClock.elapsedRealtime());
+ if (call.visibleToInCallService()) {
+ extras.putBoolean(PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
+ }
call.setIntentExtras(extras);
}
@@ -4759,7 +4785,6 @@
* @param call The {@link Call} which could not be added.
*/
private void notifyCreateConnectionFailed(PhoneAccountHandle phoneAccountHandle, Call call) {
- call.getAnalytics().setMissedReason(call.getMissedReason());
if (phoneAccountHandle == null) {
return;
}
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 72c3f24..1cb3957 100755
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -1573,6 +1573,34 @@
}
}
+ /** @see IConnectionService#onUsingAlternativeUi(String, boolean, Session.Info) */
+ @VisibleForTesting
+ public void onUsingAlternativeUi(Call activeCall, boolean isUsingAlternativeUi) {
+ final String callId = mCallIdMapper.getCallId(activeCall);
+ if (callId != null && isServiceValid("onUsingAlternativeUi")) {
+ try {
+ logOutgoing("onUsingAlternativeUi %s", isUsingAlternativeUi);
+ mServiceInterface.onUsingAlternativeUi(callId, isUsingAlternativeUi,
+ Log.getExternalSession(TELECOM_ABBREVIATION));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see IConnectionService#onTrackedByNonUiService(String, boolean, Session.Info) */
+ @VisibleForTesting
+ public void onTrackedByNonUiService(Call activeCall, boolean isTracked) {
+ final String callId = mCallIdMapper.getCallId(activeCall);
+ if (callId != null && isServiceValid("onTrackedByNonUiService")) {
+ try {
+ logOutgoing("onTrackedByNonUiService %s", isTracked);
+ mServiceInterface.onTrackedByNonUiService(callId, isTracked,
+ Log.getExternalSession(TELECOM_ABBREVIATION));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
/** @see IConnectionService#disconnect(String, Session.Info) */
void disconnect(Call call) {
final String callId = mCallIdMapper.getCallId(call);
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 954aa44..e46d377 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -113,7 +113,7 @@
public Call mCall;
}
- private class InCallServiceInfo {
+ public static class InCallServiceInfo {
private final ComponentName mComponentName;
private boolean mIsExternalCallsSupported;
private boolean mIsSelfManagedCallsSupported;
@@ -279,7 +279,8 @@
}
if (call != null && call.isSelfManaged() &&
- !mInCallServiceInfo.isSelfManagedCallsSupported()) {
+ (!mInCallServiceInfo.isSelfManagedCallsSupported()
+ || !call.visibleToInCallService())) {
Log.i(this, "Skipping binding to %s - doesn't support self-mgd calls",
mInCallServiceInfo);
mIsConnected = false;
@@ -342,6 +343,7 @@
mInCallServiceInfo.getType(),
mInCallServiceInfo.getDisconnectTime()
- mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
+ updateCallTracking(mCall, mInCallServiceInfo, false /* isAdd */);
}
InCallController.this.onDisconnected(mInCallServiceInfo);
@@ -748,6 +750,10 @@
newConnection.connect(callToConnectWith);
}
}
+
+ public List<InCallServiceBindingConnection> getSubConnections() {
+ return mSubConnections;
+ }
}
private final Call.Listener mCallListener = new Call.ListenerBase() {
@@ -915,12 +921,12 @@
@Override
public void onPackageUninstalled(String packageName) {
mCarModeTracker.forceExitCarMode(packageName);
- updateCarModeForSwitchingConnection();
+ updateCarModeForConnections();
}
};
private static final int IN_CALL_SERVICE_TYPE_INVALID = 0;
- private static final int IN_CALL_SERVICE_TYPE_DIALER_UI = 1;
+ private static final int IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI = 1;
private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
@@ -967,10 +973,9 @@
private boolean mIsCallUsingMicrophone = false;
public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager,
- SystemStateHelper systemStateHelper,
- DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
- EmergencyCallHelper emergencyCallHelper, CarModeTracker carModeTracker,
- ClockProxy clockProxy) {
+ SystemStateHelper systemStateHelper, DefaultDialerCache defaultDialerCache,
+ Timeouts.Adapter timeoutsAdapter, EmergencyCallHelper emergencyCallHelper,
+ CarModeTracker carModeTracker, ClockProxy clockProxy) {
mContext = context;
mAppOpsManager = context.getSystemService(AppOpsManager.class);
mLock = lock;
@@ -1013,12 +1018,16 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && (!call.visibleToInCallService()
+ || !info.isSelfManagedCallsSupported())) {
continue;
}
// Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ boolean includeRttCall = false;
+ if (mInCallServiceConnection != null) {
+ includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ }
componentsUpdated.add(info.getComponentName());
IInCallService inCallService = entry.getValue();
@@ -1030,6 +1039,7 @@
info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1079,7 +1089,8 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && !call.visibleToInCallService()
+ && !info.isSelfManagedCallsSupported()) {
continue;
}
@@ -1096,6 +1107,7 @@
info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
try {
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1356,7 +1368,8 @@
/**
* Binds to all the UI-providing InCallService as well as system-implemented non-UI
- * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()} before invoking.
+ * InCallServices. Method-invoker must check {@link #isBoundAndConnectedToServices()}
+ * before invoking.
*
* @param call The newly added call that triggered the binding to the in-call services.
*/
@@ -1393,11 +1406,12 @@
mInCallServiceConnection.chooseInitialInCallService(shouldUseCarModeUI());
- // Actually try binding to the UI InCallService. If the response
+ // Actually try binding to the UI InCallService.
if (mInCallServiceConnection.connect(call) ==
- InCallServiceConnection.CONNECTION_SUCCEEDED) {
+ InCallServiceConnection.CONNECTION_SUCCEEDED || call.isSelfManaged()) {
// Only connect to the non-ui InCallServices if we actually connected to the main UI
- // one.
+ // one, or if the call is self-managed (in which case we'd still want to keep Wear, BT,
+ // etc. informed.
connectToNonUiInCallServices(call);
mBindingFuture = new CompletableFuture<Boolean>().completeOnTimeout(false,
mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
@@ -1408,7 +1422,7 @@
}
}
- private void connectToNonUiInCallServices(Call call) {
+ private void updateNonUiInCallServices() {
List<InCallServiceInfo> nonUIInCallComponents =
getInCallServiceComponents(IN_CALL_SERVICE_TYPE_NON_UI);
List<InCallServiceBindingConnection> nonUIInCalls = new LinkedList<>();
@@ -1418,7 +1432,7 @@
List<String> callCompanionApps = mCallsManager
.getRoleManagerAdapter().getCallCompanionApps();
if (callCompanionApps != null && !callCompanionApps.isEmpty()) {
- for(String pkg : callCompanionApps) {
+ for (String pkg : callCompanionApps) {
InCallServiceInfo info = getInCallServiceComponent(pkg,
IN_CALL_SERVICE_TYPE_COMPANION);
if (info != null) {
@@ -1426,7 +1440,14 @@
}
}
}
- mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
+ mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(
+ nonUIInCalls);
+ }
+
+ private void connectToNonUiInCallServices(Call call) {
+ if (mNonUIInCallServiceConnections == null) {
+ updateNonUiInCallServices();
+ }
mNonUIInCallServiceConnections.connect(call);
IntentFilter packageChangedFilter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
@@ -1443,7 +1464,7 @@
InCallServiceInfo defaultDialerComponent =
(systemPackageName != null && systemPackageName.equals(packageName))
? getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_SYSTEM_UI)
- : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DIALER_UI);
+ : getInCallServiceComponent(packageName, IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI);
/* TODO: in Android 12 re-enable this an InCallService is required by the dialer role.
if (packageName != null && defaultDialerComponent == null) {
// The in call service of default phone app is disabled, send notification.
@@ -1493,7 +1514,6 @@
private List<InCallServiceInfo> getInCallServiceComponents(String packageName,
ComponentName componentName, int requestedType) {
-
List<InCallServiceInfo> retval = new LinkedList<>();
Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE);
@@ -1525,13 +1545,19 @@
if (requestedType == IN_CALL_SERVICE_TYPE_NON_UI) {
mKnownNonUiInCallServices.add(foundComponentName);
}
- if (serviceInfo.enabled && (requestedType == 0 || requestedType == currentType)) {
- retval.add(new InCallServiceInfo(foundComponentName,
- isExternalCallsSupported, isSelfManageCallsSupported, requestedType));
+
+ boolean isRequestedType;
+ if (requestedType == IN_CALL_SERVICE_TYPE_INVALID) {
+ isRequestedType = true;
+ } else {
+ isRequestedType = requestedType == currentType;
+ }
+ if (serviceInfo.enabled && isRequestedType) {
+ retval.add(new InCallServiceInfo(foundComponentName, isExternalCallsSupported,
+ isSelfManageCallsSupported, requestedType));
}
}
}
-
return retval;
}
@@ -1597,7 +1623,7 @@
mDefaultDialerCache.getDefaultDialerApplication(
mCallsManager.getCurrentUserHandle().getIdentifier()));
if (isDefaultDialerPackage && isUIService) {
- return IN_CALL_SERVICE_TYPE_DIALER_UI;
+ return IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
}
// Also allow any in-call service that has the control-experience permission (to ensure
@@ -1636,7 +1662,7 @@
if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
|| info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || info.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ || info.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
trackCallingUserInterfaceStarted(info);
}
IInCallService inCallService = IInCallService.Stub.asInterface(service);
@@ -1662,13 +1688,17 @@
int numCallsSent = 0;
for (Call call : calls) {
try {
- if ((call.isSelfManaged() && !info.isSelfManagedCallsSupported()) ||
+ if ((call.isSelfManaged() && (!info.isSelfManagedCallsSupported()
+ || !call.visibleToInCallService())) ||
(call.isExternalCall() && !info.isExternalCallsSupported())) {
continue;
}
// Only send the RTT call if it's a UI in-call service
- boolean includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ boolean includeRttCall = false;
+ if (mInCallServiceConnection != null) {
+ includeRttCall = info.equals(mInCallServiceConnection.getInfo());
+ }
// Track the call if we don't already know about it.
addCall(call);
@@ -1682,6 +1712,7 @@
info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI ||
info.getType() == IN_CALL_SERVICE_TYPE_NON_UI);
inCallService.addCall(sanitizeParcelableCallForService(info, parcelableCall));
+ updateCallTracking(call, info, true /* isAdd */);
} catch (RemoteException ignored) {
}
}
@@ -1708,7 +1739,7 @@
Log.i(this, "onDisconnected from %s", disconnectedInfo.getComponentName());
if (disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
|| disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
- || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI) {
trackCallingUserInterfaceStopped(disconnectedInfo);
}
mInCallServices.remove(disconnectedInfo);
@@ -1742,7 +1773,8 @@
continue;
}
- if (call.isSelfManaged() && !info.isSelfManagedCallsSupported()) {
+ if (call.isSelfManaged() && (!call.visibleToInCallService()
+ || !info.isSelfManagedCallsSupported())) {
continue;
}
@@ -1823,7 +1855,7 @@
*/
private ComponentName getConnectedUi() {
InCallServiceInfo connectedUi = mInCallServices.keySet().stream().filter(
- i -> i.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI
+ i -> i.getType() == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI
|| i.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI)
.findAny()
.orElse(null);
@@ -1941,13 +1973,13 @@
mCarModeTracker.handleExitCarMode(priority, packageName);
}
- updateCarModeForSwitchingConnection();
+ updateCarModeForConnections();
}
- public void updateCarModeForSwitchingConnection() {
+ public void updateCarModeForConnections() {
+ Log.i(this, "updateCarModeForConnections: car mode apps: %s",
+ mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
if (mInCallServiceConnection != null) {
- Log.i(this, "updateCarModeForSwitchingConnection: car mode apps: %s",
- mCarModeTracker.getCarModeApps().stream().collect(Collectors.joining(", ")));
if (shouldUseCarModeUI()) {
mInCallServiceConnection.changeCarModeApp(
mCarModeTracker.getCurrentCarModePackage());
@@ -2057,4 +2089,11 @@
notificationManager.notify(NOTIFICATION_TAG, IN_CALL_SERVICE_NOTIFICATION_ID,
builder.build());
}
+
+ private void updateCallTracking(Call call, InCallServiceInfo info, boolean isAdd) {
+ int type = info.getType();
+ boolean hasUi = type == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
+ || type == IN_CALL_SERVICE_TYPE_DEFAULT_DIALER_UI;
+ call.maybeOnInCallServiceTrackingChanged(isAdd, hasUi);
+ }
}
diff --git a/src/com/android/server/telecom/RoleManagerAdapterImpl.java b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
index eb216d0..4a98d7b 100644
--- a/src/com/android/server/telecom/RoleManagerAdapterImpl.java
+++ b/src/com/android/server/telecom/RoleManagerAdapterImpl.java
@@ -85,8 +85,11 @@
@Override
public void observeDefaultDialerApp(Executor executor, IntConsumer observer) {
- mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) ->
- observer.accept(user.getIdentifier()), UserHandle.ALL);
+ mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) -> {
+ if (ROLE_DIALER.equals(roleName)) {
+ observer.accept(user.getIdentifier());
+ }
+ }, UserHandle.ALL);
}
@Override
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 72c372a..8928e76 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -20,7 +20,6 @@
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.AudioProcessingNotification;
@@ -202,7 +201,6 @@
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
ClockProxy clockProxy,
RoleManagerAdapter roleManagerAdapter,
- IncomingCallFilter.Factory incomingCallFilterFactory,
ContactsAsyncHelper.Factory contactsAsyncHelperFactory,
DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
mContext = context.getApplicationContext();
@@ -306,7 +304,6 @@
callAudioModeStateMachineFactory,
inCallControllerFactory,
roleManagerAdapter,
- incomingCallFilterFactory,
toastFactory);
mIncomingCallNotifier = incomingCallNotifier;
diff --git a/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java b/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
index 052ce57..1043774 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
@@ -18,5 +18,5 @@
import com.android.server.telecom.Call;
public interface CallFilterResultCallback {
- void onCallFilteringComplete(Call call, CallFilteringResult result);
+ void onCallFilteringComplete(Call call, CallFilteringResult result, boolean timeout);
}
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
deleted file mode 100644
index 860de1f..0000000
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.callfiltering;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.telecom.Log;
-import android.telecom.Logging.Runnable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.telecom.Call;
-import com.android.server.telecom.LogUtils;
-import com.android.server.telecom.TelecomSystem;
-import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
-
-import java.util.List;
-
-public class IncomingCallFilter implements CallFilterResultCallback {
-
- public static class Factory {
- public IncomingCallFilter create(Context context, CallFilterResultCallback listener,
- Call call, TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<CallFilter> filters) {
- return new IncomingCallFilter(context, listener, call, lock, timeoutsAdapter, filters,
- new Handler(Looper.getMainLooper()));
- }
- }
-
- public interface CallFilter {
- void startFilterLookup(Call call, CallFilterResultCallback listener);
- }
-
- private final TelecomSystem.SyncRoot mTelecomLock;
- private final Context mContext;
- private final Handler mHandler;
- private final List<CallFilter> mFilters;
- private final Call mCall;
- private final CallFilterResultCallback mListener;
- private final Timeouts.Adapter mTimeoutsAdapter;
-
- private CallFilteringResult mResult = new Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .build();
-
- private boolean mIsPending = true;
- private int mNumPendingFilters;
-
- public IncomingCallFilter(Context context, CallFilterResultCallback listener, Call call,
- TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<CallFilter> filters, Handler handler) {
- mContext = context;
- mListener = listener;
- mCall = call;
- mTelecomLock = lock;
- mFilters = filters;
- mNumPendingFilters = filters.size();
- mTimeoutsAdapter = timeoutsAdapter;
- mHandler = handler;
- }
-
- public void performFiltering() {
- Log.addEvent(mCall, LogUtils.Events.FILTERING_INITIATED);
- for (CallFilter filter : mFilters) {
- filter.startFilterLookup(mCall, this);
- }
- // synchronized to prevent a race on mResult and to enter into Telecom.
- mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { // performFiltering time-out
- @Override
- public void loggedRun() {
- if (mIsPending) {
- Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
- Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
- mListener.onCallFilteringComplete(mCall, mResult);
- mIsPending = false;
- }
- }
- }.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));
- }
-
- public void onCallFilteringComplete(Call call, CallFilteringResult result) {
- synchronized (mTelecomLock) { // synchronizing to prevent race on mResult
- mNumPendingFilters--;
- mResult = result.combine(mResult);
- if (mNumPendingFilters == 0) {
- // synchronized on mTelecomLock to enter into Telecom.
- mHandler.post(new Runnable("ICF.oCFC", mTelecomLock) {
- @Override
- public void loggedRun() {
- if (mIsPending) {
- Log.addEvent(mCall, LogUtils.Events.FILTERING_COMPLETED, mResult);
- mListener.onCallFilteringComplete(mCall, mResult);
- mIsPending = false;
- }
- }
- }.prepare());
- }
- }
- }
-
- /**
- * Returns the handler, for testing purposes.
- */
- @VisibleForTesting
- public Handler getHandler() {
- return mHandler;
- }
-}
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
index 1543270..e3c68c9 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
@@ -73,7 +73,7 @@
if (mFilter.equals(mDummyComplete)) {
synchronized (mLock) {
mFinished = true;
- mListener.onCallFilteringComplete(mCall, result);
+ mListener.onCallFilteringComplete(mCall, result, false);
Log.addEvent(mCall, LogUtils.Events.FILTERING_COMPLETED, result);
}
mHandlerThread.quit();
@@ -122,7 +122,7 @@
if (!mFinished) {
Log.i(this, "Graph timed out when performing filtering.");
Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
- mListener.onCallFilteringComplete(mCall, mCurrentResult);
+ mListener.onCallFilteringComplete(mCall, mCurrentResult, true);
mFinished = true;
mHandlerThread.quit();
}
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index 682990f..9ad0da4 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -57,7 +57,6 @@
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.TelecomWakeLock;
import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl;
import com.android.server.telecom.ui.NotificationChannelManager;
@@ -191,7 +190,6 @@
},
new RoleManagerAdapterImpl(context,
(RoleManager) context.getSystemService(Context.ROLE_SERVICE)),
- new IncomingCallFilter.Factory(),
new ContactsAsyncHelper.Factory(),
internalServiceRetriever.getDeviceIdleController()));
}
diff --git a/testapps/Android.bp b/testapps/Android.bp
index 26347fe..11ea474 100644
--- a/testapps/Android.bp
+++ b/testapps/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_test {
name: "TelecomTestApps",
static_libs: [
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 9c461ca..891a7a7 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -70,6 +70,8 @@
android:exported="true">
<meta-data android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true"/>
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
diff --git a/testapps/carmodedialer/Android.bp b/testapps/carmodedialer/Android.bp
index 7179b1f..9f65b8c 100644
--- a/testapps/carmodedialer/Android.bp
+++ b/testapps/carmodedialer/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
android_test {
name: "TelecomCarModeApp",
static_libs: [
diff --git a/testapps/carmodedialer/AndroidManifest.xml b/testapps/carmodedialer/AndroidManifest.xml
index f237211..239726c 100644
--- a/testapps/carmodedialer/AndroidManifest.xml
+++ b/testapps/carmodedialer/AndroidManifest.xml
@@ -37,8 +37,10 @@
<service android:name="com.android.server.telecom.carmodedialer.CarModeInCallServiceImpl"
android:permission="android.permission.BIND_INCALL_SERVICE"
android:exported="true">
- <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
- android:value="true"/>
+ <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
+ android:value="true"/>
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true"/>
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
diff --git a/testapps/res/layout/self_managed_sample_main.xml b/testapps/res/layout/self_managed_sample_main.xml
index 28f4473..d26d629 100644
--- a/testapps/res/layout/self_managed_sample_main.xml
+++ b/testapps/res/layout/self_managed_sample_main.xml
@@ -90,7 +90,6 @@
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
-
<Button
android:id="@+id/placeOutgoingCallButton"
android:layout_width="wrap_content"
@@ -113,6 +112,35 @@
android:text="Req CallScreen Role"/>
</LinearLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/placeSelfManagedOutgoingCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SelfManagedOutgoing"/>
+ <Button
+ android:id="@+id/placeSelfManagedIncomingCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SelfManagedIncoming"/>
+ </LinearLayout>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/enableCarMode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Enable car mode"/>
+ <Button
+ android:id="@+id/disableCarMode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Disable car mode"/>
+ </LinearLayout>
<ListView
android:id="@+id/callList"
android:layout_width="match_parent"
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
index 4b5fa57..d4661ff 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
@@ -46,8 +46,10 @@
public static String SELF_MANAGED_ACCOUNT_1 = "1";
public static String SELF_MANAGED_ACCOUNT_2 = "2";
+ public static String SELF_MANAGED_ACCOUNT_3 = "3";
public static String SELF_MANAGED_NAME_1 = "SuperCall";
public static String SELF_MANAGED_NAME_2 = "Mega Call";
+ public static String SELF_MANAGED_NAME_3 = "SM Call";
public static String CUSTOM_URI_SCHEME = "custom";
private static SelfManagedCallList sInstance;
@@ -99,6 +101,8 @@
SELF_MANAGED_NAME_1, true /* areCallsLogged */);
registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_2, SELF_MANAGED_ADDRESS_2,
SELF_MANAGED_NAME_2, false /* areCallsLogged */);
+ registerPhoneAccount(context, SELF_MANAGED_ACCOUNT_3, SELF_MANAGED_ADDRESS_1,
+ SELF_MANAGED_NAME_3, true /* areCallsLogged */);
}
public void registerPhoneAccount(Context context, String id, Uri address, String name,
@@ -110,6 +114,9 @@
if (areCallsLogged) {
extras.putBoolean(PhoneAccount.EXTRA_LOG_SELF_MANAGED_CALLS, true);
}
+ if (id.equals(SELF_MANAGED_ACCOUNT_3)) {
+ extras.putBoolean(PhoneAccount.EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE, true);
+ }
PhoneAccount.Builder builder = PhoneAccount.builder(handle, name)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
index fd12a2e..44410d2 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallingActivity.java
@@ -16,9 +16,12 @@
package com.android.server.telecom.testapps;
+import static android.app.UiModeManager.DEFAULT_PRIORITY;
+
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
+import android.app.UiModeManager;
import android.app.role.RoleManager;
import android.content.Intent;
import android.media.AudioAttributes;
@@ -54,9 +57,13 @@
private SelfManagedCallList mCallList = SelfManagedCallList.getInstance();
private CheckBox mCheckIfPermittedBeforeCalling;
private Button mPlaceOutgoingCallButton;
+ private Button mPlaceSelfManagedOutgoingCallButton;
+ private Button mPlaceSelfManagedIncomingCallButton;
private Button mPlaceIncomingCallButton;
private Button mHandoverFrom;
private Button mRequestCallScreeningRole;
+ private Button mEnableCarMode;
+ private Button mDisableCarMode;
private RadioButton mUseAcct1Button;
private RadioButton mUseAcct2Button;
private CheckBox mHoldableCheckbox;
@@ -119,6 +126,20 @@
placeOutgoingCall();
}
});
+ mPlaceSelfManagedOutgoingCallButton = (Button) findViewById(
+ R.id.placeSelfManagedOutgoingCallButton);
+ mPlaceSelfManagedOutgoingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ placeSelfManagedOutgoingCall();
+ }
+ });
+ mPlaceSelfManagedIncomingCallButton = (Button) findViewById(
+ R.id.placeSelfManagedIncomingCallButton);
+ mPlaceSelfManagedIncomingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) { placeSelfManagedIncomingCall(); }
+ });
mPlaceIncomingCallButton = (Button) findViewById(R.id.placeIncomingCallButton);
mPlaceIncomingCallButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -134,7 +155,14 @@
mRequestCallScreeningRole.setOnClickListener((v -> {
requestCallScreeningRole();
}));
-
+ mEnableCarMode = (Button) findViewById(R.id.enableCarMode);
+ mEnableCarMode.setOnClickListener((v -> {
+ enableCarMode();
+ }));
+ mDisableCarMode = (Button) findViewById(R.id.disableCarMode);
+ mDisableCarMode.setOnClickListener((v -> {
+ disableCarMode();
+ }));
mUseAcct1Button = findViewById(R.id.useAcct1Button);
mUseAcct2Button = findViewById(R.id.useAcct2Button);
mHasFocus = findViewById(R.id.hasFocus);
@@ -184,6 +212,25 @@
tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
}
+ private void placeSelfManagedOutgoingCall() {
+ TelecomManager tm = TelecomManager.from(this);
+ PhoneAccountHandle phoneAccountHandle = mCallList.getPhoneAccountHandle(
+ SelfManagedCallList.SELF_MANAGED_ACCOUNT_3);
+
+ if (mCheckIfPermittedBeforeCalling.isChecked()) {
+ Toast.makeText(this, R.string.outgoingCallNotPermitted, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
+ if (mVideoCallCheckbox.isChecked()) {
+ extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
+ VideoProfile.STATE_BIDIRECTIONAL);
+ }
+ tm.placeCall(Uri.parse(mNumber.getText().toString()), extras);
+ }
+
private void initiateHandover() {
TelecomManager tm = TelecomManager.from(this);
PhoneAccountHandle phoneAccountHandle = getSelectedPhoneAccountHandle();
@@ -214,6 +261,37 @@
tm.addNewIncomingCall(getSelectedPhoneAccountHandle(), extras);
}
+ private void placeSelfManagedIncomingCall() {
+ TelecomManager tm = TelecomManager.from(this);
+ PhoneAccountHandle phoneAccountHandle = mCallList.getPhoneAccountHandle(
+ SelfManagedCallList.SELF_MANAGED_ACCOUNT_3);
+
+ if (mCheckIfPermittedBeforeCalling.isChecked()) {
+ if (!tm.isIncomingCallPermitted(phoneAccountHandle)) {
+ Toast.makeText(this, R.string.incomingCallNotPermitted , Toast.LENGTH_SHORT).show();
+ return;
+ }
+ }
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
+ Uri.parse(mNumber.getText().toString()));
+ tm.addNewIncomingCall(phoneAccountHandle, extras);
+ }
+
+ private void enableCarMode() {
+ UiModeManager uiModeManager = getSystemService(UiModeManager.class);
+ uiModeManager.enableCarMode(0);
+ Toast.makeText(this, "Enabling car mode with priority " + DEFAULT_PRIORITY,
+ Toast.LENGTH_LONG).show();
+ }
+
+ private void disableCarMode() {
+ UiModeManager uiModeManager = getSystemService(UiModeManager.class);
+ uiModeManager.disableCarMode(0);
+ Toast.makeText(this, "Disabling car mode", Toast.LENGTH_LONG).show();
+ }
+
private void configureNotificationChannel() {
NotificationChannel channel = new NotificationChannel(
SelfManagedConnection.INCOMING_CALL_CHANNEL_ID, "Incoming Calls",
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 24476f0..5592cf4 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -455,6 +455,37 @@
@SmallTest
@Test
+ public void testFocusChangeFromQuiescentSpeaker() {
+ CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
+ mContext,
+ mockCallsManager,
+ mockBluetoothRouteManager,
+ mockWiredHeadsetManager,
+ mockStatusBarNotifier,
+ mAudioServiceFactory,
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
+ stateMachine.setCallAudioManager(mockCallAudioManager);
+
+ when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
+
+ CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
+ CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);
+ stateMachine.initialize(initState);
+
+ // Switch to active, pretending that a call came in.
+ stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
+ CallAudioRouteStateMachine.ACTIVE_FOCUS);
+ waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
+
+ // Make sure that we've successfully switched to the active speaker route and that we've
+ // called setSpeakerOn
+ assertTrue(stateMachine.isInActiveState());
+ verify(mockAudioManager).setSpeakerphoneOn(true);
+ }
+
+ @SmallTest
+ @Test
public void testFocusChangeWithAlreadyActiveBtDevice() {
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
diff --git a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
index 953c711..dfc3258 100644
--- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
@@ -60,6 +60,7 @@
import androidx.test.filters.FlakyTest;
+import com.android.server.telecom.Analytics;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallLogManager;
import com.android.server.telecom.CallState;
@@ -89,6 +90,7 @@
private PhoneAccountHandle mOtherUserAccountHandle;
private PhoneAccountHandle mManagedProfileAccountHandle;
private PhoneAccountHandle mSelfManagedAccountHandle;
+ private Analytics.CallInfo mCallInfo;
private static final Uri TEL_PHONEHANDLE = Uri.parse("tel:5555551234");
@@ -148,6 +150,7 @@
TEST_SELF_MGD_PHONE_ACCOUNT_ID,
UserHandle.of(CURRENT_USER_ID)
);
+ mCallInfo = new Analytics.CallInfo();
// Since we can't mock ContentResolver directly, use a ContentProvider
when(mContext.getContentResolver()).thenReturn(ContentResolver.wrap(mContentProvider));
@@ -1006,6 +1009,7 @@
when(fakeCall.getParentCall()).thenReturn(null);
when(fakeCall.hadChildren()).thenReturn(true);
when(fakeCall.hasProperty(eq(Connection.PROPERTY_REMOTELY_HOSTED))).thenReturn(false);
+ when(fakeCall.getAnalytics()).thenReturn(mCallInfo);
return fakeCall;
}
diff --git a/tests/src/com/android/server/telecom/tests/CallTest.java b/tests/src/com/android/server/telecom/tests/CallTest.java
index 541d278..d326a29 100644
--- a/tests/src/com/android/server/telecom/tests/CallTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallTest.java
@@ -19,13 +19,17 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import android.content.ComponentName;
import android.net.Uri;
@@ -34,6 +38,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
import android.widget.Toast;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -44,6 +49,8 @@
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceWrapper;
+import com.android.server.telecom.InCallController;
+import com.android.server.telecom.InCallController.InCallServiceInfo;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapter;
import com.android.server.telecom.TelecomSystem;
@@ -54,17 +61,23 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
@RunWith(AndroidJUnit4.class)
public class CallTest extends TelecomTestCase {
private static final Uri TEST_ADDRESS = Uri.parse("tel:555-1212");
+ private static final ComponentName COMPONENT_NAME_1 = ComponentName
+ .unflattenFromString("com.foo/.Blah");
+ private static final ComponentName COMPONENT_NAME_2 = ComponentName
+ .unflattenFromString("com.bar/.Blah");
private static final PhoneAccountHandle SIM_1_HANDLE = new PhoneAccountHandle(
- ComponentName.unflattenFromString("com.foo/.Blah"), "Sim1");
+ COMPONENT_NAME_1, "Sim1");
private static final PhoneAccount SIM_1_ACCOUNT = new PhoneAccount.Builder(SIM_1_HANDLE, "Sim1")
.setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
| PhoneAccount.CAPABILITY_CALL_PROVIDER)
.setIsEnabled(true)
.build();
+ private static final long TIMEOUT_MILLIS = 1000;
@Mock private CallsManager mMockCallsManager;
@Mock private CallerInfoLookupHelper mMockCallerInfoLookupHelper;
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 3fd5e60..8378e3b 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -96,7 +96,6 @@
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import com.android.server.telecom.callfiltering.CallFilteringResult;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.DisconnectedCallNotifier;
import com.android.server.telecom.ui.ToastFactory;
@@ -111,8 +110,6 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -201,8 +198,6 @@
@Mock private CallAudioModeStateMachine.Factory mCallAudioModeStateMachineFactory;
@Mock private BluetoothStateReceiver mBluetoothStateReceiver;
@Mock private RoleManagerAdapter mRoleManagerAdapter;
- @Mock private IncomingCallFilter.Factory mIncomingCallFilterFactory;
- @Mock private IncomingCallFilter mIncomingCallFilter;
@Mock private ToastFactory mToastFactory;
@Mock private Toast mToast;
@@ -225,8 +220,6 @@
anyInt())).thenReturn(mCallAudioRouteStateMachine);
when(mCallAudioModeStateMachineFactory.create(any(), any()))
.thenReturn(mCallAudioModeStateMachine);
- when(mIncomingCallFilterFactory.create(any(), any(), any(), any(), any(), any()))
- .thenReturn(mIncomingCallFilter);
when(mClockProxy.currentTimeMillis()).thenReturn(System.currentTimeMillis());
when(mClockProxy.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
when(mConnSvrFocusManagerFactory.create(any())).thenReturn(mConnectionSvrFocusMgr);
@@ -261,7 +254,6 @@
mCallAudioModeStateMachineFactory,
mInCallControllerFactory,
mRoleManagerAdapter,
- mIncomingCallFilterFactory,
mToastFactory);
when(mPhoneAccountRegistrar.getPhoneAccount(
@@ -1338,6 +1330,8 @@
@Test
public void testHandleSilenceVsBackgroundScreeningOrdering() throws Exception {
Call screenedCall = mock(Call.class);
+ Bundle extra = new Bundle();
+ when(screenedCall.getIntentExtras()).thenReturn(extra);
String appName = "blah";
CallFilteringResult result = new CallFilteringResult.Builder()
.setShouldAllowCall(true)
@@ -1348,7 +1342,7 @@
.setShouldShowNotification(true)
.setCallScreeningAppName(appName)
.build();
- mCallsManager.onCallFilteringComplete(screenedCall, result);
+ mCallsManager.onCallFilteringComplete(screenedCall, result, false);
verify(mConnectionSvrFocusMgr).requestFocus(eq(screenedCall),
nullable(ConnectionServiceFocusManager.RequestFocusCallback.class));
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 26f24ef..5b4e800 100755
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -342,6 +342,14 @@
throws RemoteException { }
@Override
+ public void onUsingAlternativeUi(String activeCallId, boolean usingAlternativeUi,
+ Session.Info info) throws RemoteException { }
+
+ @Override
+ public void onTrackedByNonUiService(String activeCallId, boolean isTracked,
+ Session.Info info) throws RemoteException { }
+
+ @Override
public void playDtmfTone(String callId, char digit,
Session.Info info) throws RemoteException { }
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index 6a6b9f3..0b926fe 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -876,6 +876,36 @@
verifyBinding(bindIntentCaptor, 1, APPOP_NONUI_PKG, APPOP_NONUI_CLASS);
}
+ /**
+ * Ensures that the {@link InCallController} will bind to a non-ui service even if no ui service
+ * is bound if the call is self managed.
+ */
+ @MediumTest
+ @Test
+ public void testBindToService_NonUiSelfManaged() throws Exception {
+ setupMocks(false /* isExternalCall */, true);
+ setupMockPackageManager(false /* default */, true/* nonui */, true /* appop_nonui */,
+ true /* system */, false /* external calls */, false /* self mgd in default */,
+ false /* self mgd in car*/, true /* self managed in nonui */);
+
+ // we should bind to only the non ui app.
+ mInCallController.bindToServices(mMockCall);
+
+ // Bind InCallServices
+ ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockContext, times(1)).bindServiceAsUser(
+ bindIntentCaptor.capture(),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
+ eq(UserHandle.CURRENT));
+
+ // Verify bind
+ assertEquals(1, bindIntentCaptor.getAllValues().size());
+
+ // Should have bound to the third party non ui app.
+ verifyBinding(bindIntentCaptor, 0, NONUI_PKG, NONUI_CLASS);
+ }
@MediumTest
@Test
@@ -1160,6 +1190,7 @@
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
when(mMockCall.isSelfManaged()).thenReturn(isSelfManagedCall);
+ when(mMockCall.visibleToInCallService()).thenReturn(isSelfManagedCall);
}
private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls,
@@ -1238,7 +1269,7 @@
}};
}
- private ResolveInfo getNonUiResolveinfo() {
+ private ResolveInfo getNonUiResolveinfo(boolean supportsSelfManaged) {
return new ResolveInfo() {{
serviceInfo = new ServiceInfo();
serviceInfo.packageName = NONUI_PKG;
@@ -1247,6 +1278,11 @@
serviceInfo.applicationInfo.uid = NONUI_UID;
serviceInfo.enabled = true;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
+ serviceInfo.metaData = new Bundle();
+ if (supportsSelfManaged) {
+ serviceInfo.metaData.putBoolean(
+ TelecomManager.METADATA_INCLUDE_SELF_MANAGED_CALLS, true);
+ }
}};
}
@@ -1282,6 +1318,18 @@
final boolean useSystemDialer, final boolean includeExternalCalls,
final boolean includeSelfManagedCallsInDefaultDialer,
final boolean includeSelfManagedCallsInCarModeDialer) {
+ setupMockPackageManager(useDefaultDialer, useNonUiInCalls/* nonui */,
+ useAppOpNonUiInCalls/* appop_nonui */,
+ useSystemDialer, includeExternalCalls, includeSelfManagedCallsInDefaultDialer,
+ includeSelfManagedCallsInCarModeDialer, false);
+ }
+
+ private void setupMockPackageManager(final boolean useDefaultDialer,
+ final boolean useNonUiInCalls, final boolean useAppOpNonUiInCalls,
+ final boolean useSystemDialer, final boolean includeExternalCalls,
+ final boolean includeSelfManagedCallsInDefaultDialer,
+ final boolean includeSelfManagedCallsInCarModeDialer,
+ final boolean includeSelfManagedCallsInNonUi) {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -1319,7 +1367,7 @@
} else {
// InCallController uses a blank package name when querying for non-ui incalls
if (useNonUiInCalls) {
- resolveInfo.add(getNonUiResolveinfo());
+ resolveInfo.add(getNonUiResolveinfo(includeSelfManagedCallsInNonUi));
}
// InCallController uses a blank package name when querying for App Op non-ui incalls
if (useAppOpNonUiInCalls) {
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
index 8c0adfb..9269836 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterGraphTest.java
@@ -112,7 +112,7 @@
@Test
public void testEmptyGraph() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -125,7 +125,7 @@
@Test
public void testFiltersPerformOrder() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -143,7 +143,7 @@
@Test
public void testFiltersPerformInParallel() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
@@ -162,7 +162,7 @@
@Test
public void testFiltersTimeout() throws Exception {
CompletableFuture<CallFilteringResult> testResult = new CompletableFuture<>();
- CallFilterResultCallback listener = (call, result) -> testResult.complete(result);
+ CallFilterResultCallback listener = (call, result, timeout) -> testResult.complete(result);
IncomingCallFilterGraph graph = new IncomingCallFilterGraph(mCall, listener, mContext,
mTimeoutsAdapter, mLock);
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
deleted file mode 100644
index 8e2d11e..0000000
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.telecom.tests;
-
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.CallLog.Calls;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.server.telecom.Call;
-import com.android.server.telecom.Timeouts;
-import com.android.server.telecom.callfiltering.CallFilterResultCallback;
-import com.android.server.telecom.callfiltering.CallFilteringResult;
-import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
-import com.android.server.telecom.TelecomSystem;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atMost;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(JUnit4.class)
-public class IncomingCallFilterTest extends TelecomTestCase {
- @Mock private CallFilterResultCallback mResultCallback;
- @Mock private Call mCall;
- private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
-
- @Mock private IncomingCallFilter.CallFilter mFilter1;
- @Mock private IncomingCallFilter.CallFilter mFilter2;
- @Mock private IncomingCallFilter.CallFilter mFilter3;
- @Mock private IncomingCallFilter.CallFilter mFilter4;
-
- @Mock private Timeouts.Adapter mTimeoutsAdapter;
-
- private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
- private static final long LONG_TIMEOUT = 1000000;
- private static final long SHORT_TIMEOUT = 100;
-
- private static final CallFilteringResult PASS_CALL_RESULT =
- new Builder()
- .setShouldAllowCall(true)
- .setShouldReject(false)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .build();
-
- private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(false)
- .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build();
-
- private static final CallFilteringResult DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(true)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build();
-
- private static final CallFilteringResult CALL_SCREENING_SERVICE_BLOCK_RESULT =
- new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
- .setCallScreeningAppName("com.android.thirdparty")
- .setCallScreeningComponentName(
- "com.android.thirdparty/"
- + "com.android.thirdparty.callscreeningserviceimpl")
- .build();
-
- private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
- private Handler mHandler = new Handler(Looper.getMainLooper());
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
- when(mCall.getHandle()).thenReturn(TEST_HANDLE);
- setTimeoutLength(LONG_TIMEOUT);
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- mHandler.removeCallbacksAndMessages(null);
- waitForHandlerAction(mHandler, 1000);
- super.tearDown();
- }
-
- @SmallTest
- @Test
- public void testAsyncBlockCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (ASYNC_BLOCK_CHECK_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testDirectToVoiceMailCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testCallScreeningServiceBlockCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
- (CALL_SCREENING_SERVICE_BLOCK_RESULT));
- }
-
- @SmallTest
- @Test
- public void testPassCallResultFilter() {
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(PASS_CALL_RESULT));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForAsyncBlockCheckFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- add(mFilter3);
- add(mFilter4);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
- verify(mFilter3).startFilterLookup(mCall, testFilter);
- verify(mFilter4).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(false)
- .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build()));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForDirectToVoicemailCallFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- add(mFilter3);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
- verify(mFilter3).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
- .setCallScreeningAppName(null)
- .setCallScreeningComponentName(null)
- .build()));
- }
-
- @SmallTest
- @Test
- public void testMultipleFiltersForCallScreeningServiceFilter() {
- List<IncomingCallFilter.CallFilter> filters =
- new ArrayList<IncomingCallFilter.CallFilter>() {{
- add(mFilter1);
- add(mFilter2);
- }};
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters, mHandler);
- testFilter.performFiltering();
- verify(mFilter1).startFilterLookup(mCall, testFilter);
- verify(mFilter2).startFilterLookup(mCall, testFilter);
-
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
- .setShouldAllowCall(false)
- .setShouldReject(true)
- .setShouldAddToCallLog(false)
- .setShouldShowNotification(true)
- .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
- .setCallScreeningAppName("com.android.thirdparty")
- .setCallScreeningComponentName(
- "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl")
- .build()));
- }
-
- @SmallTest
- @Test
- public void testFilterTimeout() throws Exception {
- setTimeoutLength(SHORT_TIMEOUT);
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- verify(mResultCallback, timeout((int) SHORT_TIMEOUT * 2)).onCallFilteringComplete(eq(mCall),
- eq(DEFAULT_RESULT));
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- // verify that we don't report back again with the result
- verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
- any(CallFilteringResult.class));
- }
-
- @SmallTest
- @Test
- public void testFilterTimeoutDoesntTrip() throws Exception {
- setTimeoutLength(SHORT_TIMEOUT);
- IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
- testFilter.performFiltering();
- testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
- waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- Thread.sleep(SHORT_TIMEOUT);
- verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
- any(CallFilteringResult.class));
- }
-
- @SmallTest
- @Test
- public void testToString() {
- assertEquals("[Allow, logged, notified]", PASS_CALL_RESULT.toString());
- assertEquals("[Reject, notified, mCallBlockReason = 1, mCallScreeningAppName = com" +
- ".android.thirdparty, mCallScreeningComponentName = com.android.thirdparty/com" +
- ".android.thirdparty.callscreeningserviceimpl]",
- CALL_SCREENING_SERVICE_BLOCK_RESULT.toString());
- assertEquals("[Reject, logged, mCallBlockReason = 3]",
- ASYNC_BLOCK_CHECK_BLOCK_RESULT.toString());
- }
-
- private void setTimeoutLength(long length) throws Exception {
- when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
- .thenReturn(length);
- }
-}
diff --git a/tests/src/com/android/server/telecom/tests/MissedInformationTest.java b/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
index d2c832a..a8e1c5f 100644
--- a/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
+++ b/tests/src/com/android/server/telecom/tests/MissedInformationTest.java
@@ -20,11 +20,14 @@
import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_DIALING;
import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_RINGING;
import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -44,6 +47,8 @@
import com.android.server.telecom.CallIntentProcessor;
import com.android.server.telecom.CallState;
import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult;
import org.junit.After;
import org.junit.Before;
@@ -58,10 +63,14 @@
private static final String TEST_NUMBER = "650-555-1212";
private static final String TEST_NUMBER_1 = "7";
private static final String PACKAGE_NAME = "com.android.server.telecom.tests";
+ private static final String CALL_SCREENING_SERVICE_PACKAGE_NAME = "testapp";
+ private static final String CALL_SCREENING_COMPONENT_NAME = "testapp";
+
@Mock ContentResolver mContentResolver;
@Mock IContentProvider mContentProvider;
@Mock Call mEmergencyCall;
@Mock Analytics.CallInfo mCallInfo;
+ @Mock Call mIncomingCall;
private CallsManager mCallsManager;
private CallIntentProcessor.AdapterImpl mAdapter;
@@ -98,7 +107,8 @@
Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
Analytics.CallInfoImpl callAnalytics = analyticsMap.get(testCall.mCallId);
assertEquals(MISSED_REASON_NOT_MISSED, callAnalytics.missedReason);
- assertEquals(MISSED_REASON_NOT_MISSED, (int) values.getAsInteger(CallLog.Calls.MISSED_REASON));
+ assertEquals(MISSED_REASON_NOT_MISSED,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
}
@Test
@@ -116,11 +126,11 @@
ContentValues values = verifyInsertionWithCapture();
Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
+ assertEquals(AUTO_MISSED_EMERGENCY_CALL,
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
for (Analytics.CallInfoImpl ci : analyticsMap.values()) {
assertEquals(AUTO_MISSED_EMERGENCY_CALL, ci.missedReason);
}
- assertEquals(AUTO_MISSED_EMERGENCY_CALL,
- (int) values.getAsInteger(CallLog.Calls.MISSED_REASON));
}
@Test
@@ -146,7 +156,7 @@
assertEquals(AUTO_MISSED_MAXIMUM_DIALING, analyticsMap.get(callId).missedReason);
}
assertEquals(AUTO_MISSED_MAXIMUM_DIALING,
- (int) values.getAsInteger(CallLog.Calls.MISSED_REASON));
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
}
@Test
@@ -172,7 +182,49 @@
assertEquals(AUTO_MISSED_MAXIMUM_RINGING, analyticsMap.get(callId).missedReason);
}
assertEquals(AUTO_MISSED_MAXIMUM_RINGING,
- (int) values.getAsInteger(CallLog.Calls.MISSED_REASON));
+ (long) values.getAsLong(CallLog.Calls.MISSED_REASON));
+ }
+
+ @Test
+ public void testCallFiltersTimeout() throws Exception {
+ setUpIncomingCall();
+ CallFilteringResult result = new CallFilteringResult.Builder()
+ .setShouldAllowCall(true)
+ .build();
+ mCallsManager.onCallFilteringComplete(mIncomingCall, result, true);
+ mCallsManager.markCallAsDisconnected(mIncomingCall,
+ new DisconnectCause(DisconnectCause.MISSED));
+ ContentValues values = verifyInsertionWithCapture();
+
+ long missedReason = values.getAsLong(CallLog.Calls.MISSED_REASON);
+ assertTrue((missedReason & USER_MISSED_CALL_FILTERS_TIMEOUT) > 0);
+ missedReason = ((Analytics.CallInfoImpl) mIncomingCall.getAnalytics()).missedReason;
+ assertTrue((missedReason & USER_MISSED_CALL_FILTERS_TIMEOUT) > 0);
+ }
+
+ @Test
+ public void testCallScreeningServiceSilence() throws Exception {
+ setUpIncomingCall();
+ CallFilteringResult result = new CallFilteringResult.Builder()
+ .setShouldAllowCall(true)
+ .setShouldSilence(true)
+ .setCallScreeningAppName(CALL_SCREENING_SERVICE_PACKAGE_NAME)
+ .setCallScreeningComponentName(CALL_SCREENING_COMPONENT_NAME)
+ .build();
+ mCallsManager.onCallFilteringComplete(mIncomingCall, result, false);
+ assertTrue(mIncomingCall.isIncoming());
+ mCallsManager.markCallAsDisconnected(mIncomingCall,
+ new DisconnectCause(DisconnectCause.MISSED));
+ ContentValues values = verifyInsertionWithCapture();
+
+ long missedReason = values.getAsLong(CallLog.Calls.MISSED_REASON);
+ assertTrue((missedReason & USER_MISSED_CALL_SCREENING_SERVICE_SILENCED) > 0);
+ assertEquals(CALL_SCREENING_COMPONENT_NAME,
+ values.getAsString(CallLog.Calls.CALL_SCREENING_COMPONENT_NAME));
+ assertEquals(CALL_SCREENING_SERVICE_PACKAGE_NAME,
+ values.getAsString(CallLog.Calls.CALL_SCREENING_APP_NAME));
+ missedReason = ((Analytics.CallInfoImpl) mIncomingCall.getAnalytics()).missedReason;
+ assertTrue((missedReason & USER_MISSED_CALL_SCREENING_SERVICE_SILENCED) > 0);
}
private ContentValues verifyInsertionWithCapture() {
@@ -190,4 +242,16 @@
when(mEmergencyCall.getContext()).thenReturn(mSpyContext);
when(mEmergencyCall.getHandle()).thenReturn(Uri.parse("tel:" + TEST_NUMBER));
}
+
+ private void setUpIncomingCall() throws Exception {
+ mIncomingCall = spy(new Call("0", mSpyContext, mCallsManager,
+ (TelecomSystem.SyncRoot) mTelecomSystem.getLock(),
+ null, mCallsManager.getPhoneNumberUtilsAdapter(), null,
+ null, null, mPhoneAccountA0.getAccountHandle(),
+ Call.CALL_DIRECTION_INCOMING, false, false,
+ mClockProxy, null));
+ mIncomingCall.initAnalytics();
+ when(mIncomingCall.getIntentExtras()).thenReturn(new Bundle());
+ when(mIncomingCall.getViaNumber()).thenReturn(TEST_NUMBER);
+ }
}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index ab7693a..5c1cdc4 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -95,8 +95,6 @@
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.WiredHeadsetManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
-import com.android.server.telecom.callfiltering.CallFilterResultCallback;
-import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.ui.IncomingCallNotifier;
@@ -522,16 +520,6 @@
},
mClockProxy,
mRoleManagerAdapter,
- new IncomingCallFilter.Factory() {
- @Override
- public IncomingCallFilter create(Context context,
- CallFilterResultCallback listener, com.android.server.telecom.Call call,
- TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<IncomingCallFilter.CallFilter> filters) {
- return new IncomingCallFilter(context, listener, call, lock,
- timeoutsAdapter, filters, mHandlerThread.getThreadHandler());
- }
- },
new ContactsAsyncHelper.Factory() {
@Override
public ContactsAsyncHelper create(