Merge "Speculative fix for BT race condition"
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 76eed40..1d5a24b 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -536,12 +536,12 @@
* @param handle The handle to dial.
* @param gatewayInfo Gateway information to use for the call.
* @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
-* This account must be one that was registered with the
-* {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
+ * This account must be one that was registered with the
+ * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
* @param targetPhoneAccountHandle Account information to use for the call. This account must be
-* one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
+ * one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
* @param callDirection one of CALL_DIRECTION_INCOMING, CALL_DIRECTION_OUTGOING,
-* or CALL_DIRECTION_UNKNOWN.
+ * or CALL_DIRECTION_UNKNOWN.
* @param shouldAttachToExistingConnection Set to true to attach the call to an existing
* @param clockProxy
*/
@@ -643,6 +643,10 @@
}
public void initAnalytics() {
+ initAnalytics(null);
+ }
+
+ public void initAnalytics(String callingPackage) {
int analyticsDirection;
switch (mCallDirection) {
case CALL_DIRECTION_OUTGOING:
@@ -658,7 +662,7 @@
}
mAnalytics = Analytics.initiateCallAnalytics(mId, analyticsDirection);
mAnalytics.setCallIsEmergency(mIsEmergencyCall);
- Log.addEvent(this, LogUtils.Events.CREATED);
+ Log.addEvent(this, LogUtils.Events.CREATED, callingPackage);
}
public Analytics.CallInfo getAnalytics() {
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index ff3b7b2..5213364 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -28,7 +28,7 @@
public class CallIntentProcessor {
public interface Adapter {
void processOutgoingCallIntent(Context context, CallsManager callsManager,
- Intent intent);
+ Intent intent, String callingPackage);
void processIncomingCallIntent(CallsManager callsManager, Intent intent);
void processUnknownCallIntent(CallsManager callsManager, Intent intent);
}
@@ -36,8 +36,9 @@
public static class AdapterImpl implements Adapter {
@Override
public void processOutgoingCallIntent(Context context, CallsManager callsManager,
- Intent intent) {
- CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent);
+ Intent intent, String callingPackage) {
+ CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent,
+ callingPackage);
}
@Override
@@ -73,7 +74,7 @@
this.mCallsManager = callsManager;
}
- public void processIntent(Intent intent) {
+ public void processIntent(Intent intent, String callingPackage) {
final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
Log.i(this, "onReceive - isUnknownCall: %s", isUnknownCall);
@@ -81,7 +82,7 @@
if (isUnknownCall) {
processUnknownCallIntent(mCallsManager, intent);
} else {
- processOutgoingCallIntent(mContext, mCallsManager, intent);
+ processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage);
}
Trace.endSection();
}
@@ -91,11 +92,13 @@
* Processes CALL, CALL_PRIVILEGED, and CALL_EMERGENCY intents.
*
* @param intent Call intent containing data about the handle to call.
+ * @param callingPackage The package which initiated the outgoing call (if known).
*/
static void processOutgoingCallIntent(
Context context,
CallsManager callsManager,
- Intent intent) {
+ Intent intent,
+ String callingPackage) {
Uri handle = intent.getData();
String scheme = handle.getScheme();
@@ -145,7 +148,7 @@
// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
Call call = callsManager
.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser,
- intent);
+ intent, callingPackage);
if (call != null) {
sendNewOutgoingCallIntent(context, call, callsManager, intent);
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 6e71b73..1d1a010 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -39,6 +39,7 @@
// TODO: Needed for move to system service: import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CallerInfo;
+import com.android.server.telecom.callfiltering.CallFilteringResult;
import java.util.Arrays;
import java.util.HashSet;
@@ -83,7 +84,8 @@
String postDialDigits, String viaNumber, int presentation, int callType,
int features, PhoneAccountHandle accountHandle, long creationDate,
long durationInMillis, Long dataUsage, UserHandle initiatingUser, boolean isRead,
- @Nullable LogCallCompletedListener logCallCompletedListener) {
+ @Nullable LogCallCompletedListener logCallCompletedListener, int callBlockReason,
+ String callScreeningAppName, String callScreeningComponentName) {
this.context = context;
this.callerInfo = callerInfo;
this.number = number;
@@ -99,6 +101,9 @@
this.initiatingUser = initiatingUser;
this.isRead = isRead;
this.logCallCompletedListener = logCallCompletedListener;
+ this.callBockReason = callBlockReason;
+ this.callScreeningAppName = callScreeningAppName;
+ this.callScreeningComponentName = callScreeningComponentName;
}
// Since the members are accessed directly, we don't use the
// mXxxx notation.
@@ -119,6 +124,10 @@
@Nullable
public final LogCallCompletedListener logCallCompletedListener;
+
+ public final int callBockReason;
+ public final String callScreeningAppName;
+ public final String callScreeningComponentName;
}
private static final String TAG = CallLogManager.class.getSimpleName();
@@ -182,22 +191,23 @@
// Always show the notification for managed calls. For self-managed calls, it is up to
// the app to show the notification, so suppress the notification when logging the call.
boolean showNotification = !call.isSelfManaged();
- logCall(call, type, showNotification);
+ logCall(call, type, showNotification, null /*result*/);
}
}
- void logCall(Call call, int type, boolean showNotificationForMissedCall) {
- if (type == Calls.MISSED_TYPE && showNotificationForMissedCall) {
- logCall(call, Calls.MISSED_TYPE,
- new LogCallCompletedListener() {
- @Override
- public void onLogCompleted(@Nullable Uri uri) {
- mMissedCallNotifier.showMissedCallNotification(
- new MissedCallNotifier.CallInfo(call));
- }
- });
+ void logCall(Call call, int type, boolean showNotificationForMissedCall, CallFilteringResult
+ result) {
+ if ((type == Calls.MISSED_TYPE || type == Calls.BLOCKED_TYPE) &&
+ showNotificationForMissedCall) {
+ logCall(call, type, new LogCallCompletedListener() {
+ @Override
+ public void onLogCompleted(@Nullable Uri uri) {
+ mMissedCallNotifier.showMissedCallNotification(
+ new MissedCallNotifier.CallInfo(call));
+ }
+ }, result);
} else {
- logCall(call, type, null);
+ logCall(call, type, null, result);
}
}
@@ -209,10 +219,13 @@
* {@link android.provider.CallLog.Calls#INCOMING_TYPE}
* {@link android.provider.CallLog.Calls#OUTGOING_TYPE}
* {@link android.provider.CallLog.Calls#MISSED_TYPE}
+ * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}
* @param logCallCompletedListener optional callback called after the call is logged.
+ * @param result is generated when call type is
+ * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}.
*/
void logCall(Call call, int callLogType,
- @Nullable LogCallCompletedListener logCallCompletedListener) {
+ @Nullable LogCallCompletedListener logCallCompletedListener, CallFilteringResult result) {
final long creationTime = call.getCreationTimeMillis();
final long age = call.getAgeMillis();
@@ -242,10 +255,22 @@
(call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING_USED) ==
Connection.PROPERTY_ASSISTED_DIALING_USED,
call.wasEverRttCall());
- logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
- call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
- creationTime, age, callDataUsage, call.isEmergencyCall(), call.getInitiatingUser(),
- call.isSelfManaged(), logCallCompletedListener);
+
+ if (callLogType == Calls.BLOCKED_TYPE) {
+ logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
+ call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
+ creationTime, age, callDataUsage, call.isEmergencyCall(),
+ call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
+ result.mCallBlockReason, result.mCallScreeningAppName,
+ result.mCallScreeningComponentName);
+ } else {
+ logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
+ call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
+ creationTime, age, callDataUsage, call.isEmergencyCall(),
+ call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
+ Calls.BLOCK_REASON_NOT_BLOCKED, null /*callScreeningAppName*/,
+ null /*callScreeningComponentName*/);
+ }
}
/**
@@ -265,6 +290,9 @@
* @param logCallCompletedListener optional callback called after the call is logged.
* @param initiatingUser The user the call was initiated under.
* @param isSelfManaged {@code true} if this is a self-managed call, {@code false} otherwise.
+ * @param callBlockReason The reason why the call is blocked.
+ * @param callScreeningAppName The call screening application name which block the call.
+ * @param callScreeningComponentName The call screening component name which block the call.
*/
private void logCall(
CallerInfo callerInfo,
@@ -281,7 +309,10 @@
boolean isEmergency,
UserHandle initiatingUser,
boolean isSelfManaged,
- @Nullable LogCallCompletedListener logCallCompletedListener) {
+ @Nullable LogCallCompletedListener logCallCompletedListener,
+ int callBlockReason,
+ String callScreeningAppName,
+ String callScreeningComponentName) {
// On some devices, to avoid accidental redialing of emergency numbers, we *never* log
// emergency calls to the Call Log. (This behavior is set on a per-product basis, based
@@ -314,7 +345,8 @@
}
AddCallArgs args = new AddCallArgs(mContext, callerInfo, number, postDialDigits,
viaNumber, presentation, callType, features, accountHandle, start, duration,
- dataUsage, initiatingUser, isRead, logCallCompletedListener);
+ dataUsage, initiatingUser, isRead, logCallCompletedListener, callBlockReason,
+ callScreeningAppName, callScreeningComponentName);
logCallAsync(args);
} else {
Log.d(TAG, "Not adding emergency call to call log.");
@@ -475,7 +507,8 @@
return Calls.addCall(c.callerInfo, c.context, c.number, c.postDialDigits, c.viaNumber,
c.presentation, c.callType, c.features, c.accountHandle, c.timestamp,
c.durationInSec, c.dataUsage, userToBeInserted == null,
- userToBeInserted, c.isRead);
+ userToBeInserted, c.isRead, c.callBockReason, c.callScreeningAppName,
+ c.callScreeningComponentName);
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 1733255..5635699 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -569,7 +569,8 @@
filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter(),
mCallerInfoLookupHelper, null));
filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,
- mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock));
+ mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock,
+ new TelecomServiceImpl.SettingsSecureAdapterImpl()));
new IncomingCallFilter(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}
@@ -595,7 +596,7 @@
} else {
Log.i(this, "onCallFilteringCompleted: Call rejected! " +
"Exceeds maximum number of ringing calls.");
- rejectCallAndLog(incomingCall);
+ rejectCallAndLog(incomingCall, result);
}
} else if (hasMaximumManagedDialingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
@@ -604,7 +605,7 @@
Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
"dialing calls.");
- rejectCallAndLog(incomingCall);
+ rejectCallAndLog(incomingCall, result);
}
} else {
addCall(incomingCall);
@@ -619,8 +620,8 @@
if (result.shouldShowNotification) {
Log.w(this, "onCallScreeningCompleted: blocked call, showing notification.");
}
- mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE,
- result.shouldShowNotification);
+ mCallLogManager.logCall(incomingCall, Calls.BLOCKED_TYPE,
+ result.shouldShowNotification, result);
} else if (result.shouldShowNotification) {
Log.i(this, "onCallScreeningCompleted: blocked call, showing notification.");
mMissedCallNotifier.showMissedCallNotification(
@@ -1163,10 +1164,11 @@
* @param extras The optional extras Bundle passed with the intent used for the incoming call.
* @param initiatingUser {@link UserHandle} of user that place the outgoing call.
* @param originalIntent
+ * @param callingPackage the package name of the app which initiated the outgoing call.
*/
@VisibleForTesting
public Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras,
- UserHandle initiatingUser, Intent originalIntent) {
+ UserHandle initiatingUser, Intent originalIntent, String callingPackage) {
boolean isReusedCall = true;
Call call = reuseOutgoingCall(handle);
@@ -1192,7 +1194,7 @@
false /* forceAttachToExistingConnection */,
false, /* isConference */
mClockProxy);
- call.initAnalytics();
+ call.initAnalytics(callingPackage);
// Ensure new calls related to self-managed calls/connections are set as such. This
// will be overridden when the actual connection is returned in startCreateConnection,
@@ -2442,7 +2444,7 @@
* Reject an incoming call and manually add it to the Call Log.
* @param incomingCall Incoming call that has been rejected
*/
- private void rejectCallAndLog(Call incomingCall) {
+ private void rejectCallAndLog(Call incomingCall, CallFilteringResult result) {
if (incomingCall.getConnectionService() != null) {
// Only reject the call if it has not already been destroyed. If a call ends while
// incoming call filtering is taking place, it is possible that the call has already
@@ -2457,7 +2459,7 @@
// call notifier and the call logger manually.
// Do we need missed call notification for direct to Voicemail calls?
mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE,
- true /*showNotificationForMissedCall*/);
+ true /*showNotificationForMissedCall*/, result);
}
/**
@@ -3323,7 +3325,7 @@
/**
* Used to confirm creation of an outgoing call which was marked as pending confirmation in
- * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
+ * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)}.
* Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
* {@link ConfirmCallDialogActivity}.
* @param callId The call ID of the call to confirm.
@@ -3348,7 +3350,7 @@
/**
* Used to cancel an outgoing call which was marked as pending confirmation in
- * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
+ * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)}.
* Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
* {@link ConfirmCallDialogActivity}.
* @param callId The call ID of the call to cancel.
@@ -3364,7 +3366,7 @@
}
/**
- * Called from {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)} when
+ * Called from {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)} when
* a managed call is added while there are ongoing self-managed calls. Starts
* {@link ConfirmCallDialogActivity} to prompt the user to see if they wish to place the
* outgoing call or not.
@@ -3595,7 +3597,8 @@
extras.putParcelable(TelecomManager.EXTRA_CALL_AUDIO_STATE,
mCallAudioManager.getCallAudioState());
Call handoverToCall = startOutgoingCall(handoverFromCall.getHandle(), handoverToHandle,
- extras, getCurrentUserHandle(), null /* originalIntent */);
+ extras, getCurrentUserHandle(), null /* originalIntent */,
+ null /* callingPackage */);
if (handoverToCall == null) {
handoverFromCall.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_FAILED, null);
return;
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index d9398e5..196b8ad 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -815,7 +815,7 @@
sb.append("[").append(account1.getAccountHandle());
appendDiff(sb, "addr", Log.piiHandle(account1.getAddress()),
Log.piiHandle(account2.getAddress()));
- appendDiff(sb, "cap", account1.getCapabilities(), account2.getCapabilities());
+ appendDiff(sb, "cap", account1.capabilitiesToString(), account2.capabilitiesToString());
appendDiff(sb, "hl", account1.getHighlightColor(), account2.getHighlightColor());
appendDiff(sb, "lbl", account1.getLabel(), account2.getLabel());
appendDiff(sb, "desc", account1.getShortDescription(), account2.getShortDescription());
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 892b5b0..2b2408e 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -1657,7 +1657,7 @@
try {
Log.i(this, "handleCallIntent: handling call intent");
mCallIntentProcessorAdapter.processOutgoingCallIntent(mContext,
- mCallsManager, intent);
+ mCallsManager, intent, null /* callingPackage */);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
index c63e57c..0abd15d 100644
--- a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
+++ b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
@@ -21,6 +21,7 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.BlockedNumberContract;
+import android.provider.CallLog;
import android.telecom.Log;
import android.telecom.Logging.Session;
import android.telecom.TelecomManager;
@@ -123,8 +124,11 @@
result = new CallFilteringResult(
false, // shouldAllowCall
true, //shouldReject
- false, //shouldAddToCallLog
- false // shouldShowNotification
+ true, //shouldAddToCallLog
+ false, // shouldShowNotification
+ convertBlockStatusToReason(), //callBlockReason
+ null, //callScreeningAppName
+ null //callScreeningComponentName
);
if (mCallBlockListener != null) {
String number = mIncomingCall.getHandle() == null ? null
@@ -148,4 +152,28 @@
Log.endSession();
}
}
+
+ private int convertBlockStatusToReason() {
+ switch (mBlockStatus) {
+ case BlockedNumberContract.STATUS_BLOCKED_IN_LIST:
+ return CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER;
+
+ case BlockedNumberContract.STATUS_BLOCKED_UNKNOWN_NUMBER:
+ return CallLog.Calls.BLOCK_REASON_UNKNOWN_NUMBER;
+
+ case BlockedNumberContract.STATUS_BLOCKED_RESTRICTED:
+ return CallLog.Calls.BLOCK_REASON_RESTRICTED_NUMBER;
+
+ case BlockedNumberContract.STATUS_BLOCKED_PAYPHONE:
+ return CallLog.Calls.BLOCK_REASON_PAY_PHONE;
+
+ case BlockedNumberContract.STATUS_BLOCKED_NOT_IN_CONTACTS:
+ return CallLog.Calls.BLOCK_REASON_NOT_IN_CONTACTS;
+
+ default:
+ Log.w(AsyncBlockCheckFilter.class.getSimpleName(),
+ "There's no call log block reason can be converted");
+ return CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER;
+ }
+ }
}
diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index 9e35d86..1213131 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -16,11 +16,18 @@
package com.android.server.telecom.callfiltering;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.text.TextUtils;
+
public class CallFilteringResult {
public boolean shouldAllowCall;
public boolean shouldReject;
public boolean shouldAddToCallLog;
public boolean shouldShowNotification;
+ public int mCallBlockReason = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
+ public String mCallScreeningAppName = null;
+ public String mCallScreeningComponentName = null;
public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
shouldAddToCallLog, boolean shouldShowNotification) {
@@ -30,22 +37,85 @@
this.shouldShowNotification = shouldShowNotification;
}
+ public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
+ shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason, String
+ callScreeningAppName, String callScreeningComponentName) {
+ this.shouldAllowCall = shouldAllowCall;
+ this.shouldReject = shouldReject;
+ this.shouldAddToCallLog = shouldAddToCallLog;
+ this.shouldShowNotification = shouldShowNotification;
+ this.mCallBlockReason = callBlockReason;
+ this.mCallScreeningAppName = callScreeningAppName;
+ this.mCallScreeningComponentName = callScreeningComponentName;
+ }
+
/**
- * Combine this CallFilteringResult with another, returning a CallFilteringResult with
- * the more restrictive properties of the two.
+ * Combine this CallFilteringResult with another, returning a CallFilteringResult with the more
+ * restrictive properties of the two. Where there are multiple call filtering components which
+ * block a call, the first filter from {@link AsyncBlockCheckFilter},
+ * {@link DirectToVoicemailCallFilter}, {@link CallScreeningServiceFilter} which blocked a call
+ * shall be used to populate the call block reason, component name, etc.
*/
public CallFilteringResult combine(CallFilteringResult other) {
if (other == null) {
return this;
}
+ if (isBlockedByProvider(mCallBlockReason)) {
+ return getCombinedCallFilteringResult(other, mCallBlockReason,
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ } else if (isBlockedByProvider(other.mCallBlockReason)) {
+ return getCombinedCallFilteringResult(other, other.mCallBlockReason,
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ }
+
+ if (mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL
+ || other.mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL) {
+ return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
+ null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+ }
+
+ if (shouldReject && mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) {
+ return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
+ mCallScreeningAppName, mCallScreeningComponentName);
+ } else if (other.shouldReject && other.mCallBlockReason == CallLog.Calls
+ .BLOCK_REASON_CALL_SCREENING_SERVICE) {
+ return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
+ other.mCallScreeningAppName, other.mCallScreeningComponentName);
+ }
+
return new CallFilteringResult(
- shouldAllowCall && other.shouldAllowCall,
- shouldReject || other.shouldReject,
- shouldAddToCallLog && other.shouldAddToCallLog,
- shouldShowNotification && other.shouldShowNotification);
+ shouldAllowCall && other.shouldAllowCall,
+ shouldReject || other.shouldReject,
+ shouldAddToCallLog && other.shouldAddToCallLog,
+ shouldShowNotification && other.shouldShowNotification);
}
+ private boolean isBlockedByProvider(int blockReason) {
+ if (blockReason == Calls.BLOCK_REASON_BLOCKED_NUMBER
+ || blockReason == Calls.BLOCK_REASON_UNKNOWN_NUMBER
+ || blockReason == Calls.BLOCK_REASON_RESTRICTED_NUMBER
+ || blockReason == Calls.BLOCK_REASON_PAY_PHONE
+ || blockReason == Calls.BLOCK_REASON_NOT_IN_CONTACTS) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other,
+ int callBlockReason, String callScreeningAppName, String callScreeningComponentName) {
+ return new CallFilteringResult(
+ shouldAllowCall && other.shouldAllowCall,
+ shouldReject || other.shouldReject,
+ shouldAddToCallLog && other.shouldAddToCallLog,
+ shouldShowNotification && other.shouldShowNotification,
+ callBlockReason,
+ callScreeningAppName,
+ callScreeningComponentName);
+ }
+
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -56,7 +126,24 @@
if (shouldAllowCall != that.shouldAllowCall) return false;
if (shouldReject != that.shouldReject) return false;
if (shouldAddToCallLog != that.shouldAddToCallLog) return false;
- return shouldShowNotification == that.shouldShowNotification;
+ if (shouldShowNotification != that.shouldShowNotification) return false;
+ if (mCallBlockReason != that.mCallBlockReason) return false;
+
+ if ((TextUtils.isEmpty(mCallScreeningAppName) &&
+ TextUtils.isEmpty(that.mCallScreeningAppName)) &&
+ (TextUtils.isEmpty(mCallScreeningComponentName) &&
+ TextUtils.isEmpty(that.mCallScreeningComponentName))) {
+ return true;
+ } else if (!TextUtils.isEmpty(mCallScreeningAppName) &&
+ !TextUtils.isEmpty(that.mCallScreeningAppName) &&
+ mCallScreeningAppName.equals(that.mCallScreeningAppName) &&
+ !TextUtils.isEmpty(mCallScreeningComponentName) &&
+ !TextUtils.isEmpty(that.mCallScreeningComponentName) &&
+ mCallScreeningComponentName.equals(that.mCallScreeningComponentName)) {
+ return true;
+ }
+
+ return false;
}
@Override
@@ -87,6 +174,21 @@
if (shouldShowNotification) {
sb.append(", notified");
}
+
+ if (mCallBlockReason != 0) {
+ sb.append(", mCallBlockReason = ");
+ sb.append(mCallBlockReason);
+ }
+
+ if (!TextUtils.isEmpty(mCallScreeningAppName)) {
+ sb.append(", mCallScreeningAppName = ");
+ sb.append(mCallScreeningAppName);
+ }
+
+ if (!TextUtils.isEmpty(mCallScreeningComponentName)) {
+ sb.append(", mCallScreeningComponentName = ");
+ sb.append(mCallScreeningComponentName);
+ }
sb.append("]");
return sb.toString();
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index 4830b31..c89a1a4 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -24,10 +24,15 @@
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.CallLog;
+import android.provider.Settings;
import android.telecom.CallScreeningService;
import android.telecom.Log;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
import com.android.internal.telecom.ICallScreeningAdapter;
@@ -39,6 +44,7 @@
import com.android.server.telecom.ParcelableCallUtils;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomServiceImpl;
+import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter;
import com.android.server.telecom.TelecomSystem;
import java.util.List;
@@ -108,20 +114,26 @@
String callId,
boolean shouldReject,
boolean shouldAddToCallLog,
- boolean shouldShowNotification) {
+ boolean shouldShowNotification,
+ ComponentName componentName) {
Log.startSession("CSCR.dC");
long token = Binder.clearCallingIdentity();
try {
synchronized (mTelecomLock) {
+ boolean isServiceRequestingLogging = isLoggable(componentName,
+ shouldAddToCallLog);
Log.i(this, "disallowCall(%s), shouldReject: %b, shouldAddToCallLog: %b, "
- + "shouldShowNotification: %b", callId, shouldReject,
- shouldAddToCallLog, shouldShowNotification);
+ + "shouldShowNotification: %b", callId, shouldReject,
+ isServiceRequestingLogging, shouldShowNotification);
if (mCall != null && mCall.getId().equals(callId)) {
mResult = new CallFilteringResult(
- false, // shouldAllowCall
- shouldReject, //shouldReject
- shouldAddToCallLog, //shouldAddToCallLog
- shouldShowNotification // shouldShowNotification
+ false, // shouldAllowCall
+ shouldReject, //shouldReject
+ isServiceRequestingLogging, //shouldAddToCallLog
+ shouldShowNotification, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ componentName.getPackageName(), //callScreeningAppName
+ componentName.flattenToString() //callScreeningComponentName
);
} else {
Log.w(this, "disallowCall, unknown call id: %s", callId);
@@ -141,6 +153,7 @@
private final DefaultDialerCache mDefaultDialerCache;
private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
private final TelecomSystem.SyncRoot mTelecomLock;
+ private final SettingsSecureAdapter mSettingsSecureAdapter;
private Call mCall;
private CallFilterResultCallback mCallback;
@@ -161,13 +174,15 @@
PhoneAccountRegistrar phoneAccountRegistrar,
DefaultDialerCache defaultDialerCache,
ParcelableCallUtils.Converter parcelableCallUtilsConverter,
- TelecomSystem.SyncRoot lock) {
+ TelecomSystem.SyncRoot lock,
+ SettingsSecureAdapter settingsSecureAdapter) {
mContext = context;
mPhoneAccountRegistrar = phoneAccountRegistrar;
mCallsManager = callsManager;
mDefaultDialerCache = defaultDialerCache;
mParcelableCallUtilsConverter = parcelableCallUtilsConverter;
mTelecomLock = lock;
+ mSettingsSecureAdapter = settingsSecureAdapter;
}
@Override
@@ -261,4 +276,56 @@
finishCallScreening();
}
}
+
+ private boolean isLoggable(ComponentName componentName, boolean shouldAddToCallLog) {
+ if (isCarrierCallScreeningApp(componentName)) {
+ return shouldAddToCallLog;
+ } else if (isDefaultDialer(componentName) || isUserChosenCallScreeningApp(componentName)) {
+ return true;
+ }
+
+ return shouldAddToCallLog;
+ }
+
+ private boolean isCarrierCallScreeningApp(ComponentName componentName) {
+ String carrierCallScreeningApp = null;
+ CarrierConfigManager configManager = (CarrierConfigManager) mContext
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ PersistableBundle configBundle = configManager.getConfig();
+ if (configBundle != null) {
+ carrierCallScreeningApp = configBundle
+ .getString(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING);
+ }
+
+ if (!TextUtils.isEmpty(carrierCallScreeningApp) && carrierCallScreeningApp
+ .equals(componentName.flattenToString())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isDefaultDialer(ComponentName componentName) {
+ String defaultDialer = TelecomManager.from(mContext).getDefaultDialerPackage();
+
+ if (!TextUtils.isEmpty(defaultDialer) && defaultDialer
+ .equals(componentName.getPackageName())) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isUserChosenCallScreeningApp(ComponentName componentName) {
+ String defaultCallScreeningApplication = mSettingsSecureAdapter
+ .getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT);
+
+ if (!TextUtils.isEmpty(defaultCallScreeningApplication) && defaultCallScreeningApplication
+ .equals(componentName.flattenToString())) {
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
index 2ac82dc..3a8ff7d 100644
--- a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.callfiltering;
import android.net.Uri;
+import android.provider.CallLog;
import android.telecom.Log;
import com.android.internal.telephony.CallerInfo;
@@ -49,7 +50,11 @@
false, // shouldAllowCall
true, // shouldReject
true, // shouldAddToCallLog
- true // shouldShowNotification
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
+ //callBlockReason
+ null, //callScreeningAppName
+ null // callScreeningComponentName
);
} else {
result = new CallFilteringResult(
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessor.java b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
index 6a8f8c8..ae4a7d8 100644
--- a/src/com/android/server/telecom/components/UserCallIntentProcessor.java
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
@@ -159,7 +159,7 @@
// Save the user handle of current user before forwarding the intent to primary user.
intent.putExtra(CallIntentProcessor.KEY_INITIATING_USER, mUserHandle);
- sendIntentToDestination(intent, isLocalInvocation);
+ sendIntentToDestination(intent, isLocalInvocation, callingPackageName);
}
private boolean isDefaultOrSystemDialer(String callingPackageName) {
@@ -193,7 +193,8 @@
* If the caller is local to the Telecom service, we send the intent to Telecom without
* sending it through TelecomServiceImpl.
*/
- private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation) {
+ private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation,
+ String callingPackage) {
intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, false);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
if (isLocalInvocation) {
@@ -202,7 +203,8 @@
// TODO: We should not be using an intent here; this whole flows needs cleanup.
Log.i(this, "sendIntentToDestination: send intent to Telecom directly.");
synchronized (TelecomSystem.getInstance().getLock()) {
- TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent);
+ TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent,
+ callingPackage);
}
} else {
// We're calling from the UserCallActivity, so the TelecomSystem is not in the same
diff --git a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
index 758ae4f..1c84d29 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -19,6 +19,7 @@
import com.android.server.telecom.testapps.R;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -26,6 +27,7 @@
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Bundle;
import android.telecom.PhoneAccount;
@@ -45,6 +47,7 @@
*/
public class CallServiceNotifier {
private static final CallServiceNotifier INSTANCE = new CallServiceNotifier();
+ private static final String CHANNEL_ID = "channel1";
public static final String CALL_PROVIDER_ID = "testapps_TestConnectionService_CALL_PROVIDER_ID";
public static final String SIM_SUBSCRIPTION_ID =
@@ -86,6 +89,9 @@
*/
public void updateNotification(Context context) {
log("adding the notification ------------");
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Test Channel",
+ NotificationManager.IMPORTANCE_DEFAULT);
+ getNotificationManager(context).createNotificationChannel(channel);
getNotificationManager(context).notify(CALL_NOTIFICATION_ID, getMainNotification(context));
getNotificationManager(context).notify(
PHONE_ACCOUNT_NOTIFICATION_ID, getPhoneAccountNotification(context));
@@ -219,7 +225,7 @@
* Creates a notification object for using the telecom APIs.
*/
private Notification getPhoneAccountNotification(Context context) {
- final Notification.Builder builder = new Notification.Builder(context);
+ final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
// Both notifications have buttons and only the first one with buttons will show its
// buttons. Since the phone accounts notification is always first, setting false ensures
// it can be dismissed to use the other notification.
@@ -244,7 +250,7 @@
* Creates a notification object out of the current calls state.
*/
private Notification getMainNotification(Context context) {
- final Notification.Builder builder = new Notification.Builder(context);
+ final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
builder.setOngoing(true);
builder.setPriority(Notification.PRIORITY_HIGH);
builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
diff --git a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
index 22c803e..91ddf5a 100644
--- a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
@@ -23,6 +23,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
+import android.provider.CallLog;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.test.suitebuilder.annotation.SmallTest;
@@ -62,8 +63,12 @@
private static final CallFilteringResult BLOCK_RESULT = new CallFilteringResult(
false, // shouldAllowCall
true, //shouldReject
- false, //shouldAddToCallLog
- false // shouldShowNotification
+ true, //shouldAddToCallLog
+ false, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //blockReason
+ null, // callScreeningAppName
+ null //callScreeningComponentName
+
);
private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index a319fad..f2530af 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
@@ -25,10 +26,14 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.CallLog;
import android.telecom.CallScreeningService;
import android.telecom.ParcelableCall;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telecom.ICallScreeningAdapter;
@@ -38,6 +43,7 @@
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.ParcelableCallUtils;
import com.android.server.telecom.PhoneAccountRegistrar;
+import com.android.server.telecom.TelecomServiceImpl;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
@@ -60,6 +66,7 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -78,11 +85,22 @@
@Mock PackageManager mPackageManager;
@Mock IBinder mBinder;
@Mock ICallScreeningService mCallScreeningService;
+ @Mock CarrierConfigManager mCarrierConfigManager;
+ @Mock private TelecomManager mTelecomManager;
+ private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
+ spy(new SettingsSecureAdapterFake());
private static final String PKG_NAME = "com.android.services.telecom.tests";
private static final String CLS_NAME = "CallScreeningService";
private static final ComponentName COMPONENT_NAME = new ComponentName(PKG_NAME, CLS_NAME);
private static final String CALL_ID = "u89prgt9ps78y5";
+ private static final String DEFAULT_DIALER_PACKAGE = "com.android.dialer";
+ private static final ComponentName CARRIER_DEFINED_CALL_SCREENING = new ComponentName(
+ "com.android.carrier", "com.android.carrier.callscreeningserviceimpl");
+ private static final ComponentName DEFAULT_DIALER_CALL_SCREENING = new ComponentName(
+ "com.android.dialer", "com.android.dialer.callscreeningserviceimpl");
+ private static final ComponentName USER_CHOSEN_CALL_SCREENING = new ComponentName(
+ "com.android.userchosen", "com.android.userchosen.callscreeningserviceimpl");
private ResolveInfo mResolveInfo;
@@ -95,6 +113,20 @@
private CallScreeningServiceFilter mFilter;
+ public static class SettingsSecureAdapterFake implements
+ TelecomServiceImpl.SettingsSecureAdapter {
+ @Override
+ public void putStringForUser(ContentResolver resolver, String name, String value,
+ int userHandle) {
+
+ }
+
+ @Override
+ public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
+ return USER_CHOSEN_CALL_SCREENING.flattenToString();
+ }
+ }
+
@Override
@Before
public void setUp() throws Exception {
@@ -112,7 +144,7 @@
}};
mFilter = new CallScreeningServiceFilter(mContext, mCallsManager, mPhoneAccountRegistrar,
- mDefaultDialerCache, mParcelableCallUtilsConverter, mLock);
+ mDefaultDialerCache, mParcelableCallUtilsConverter, mLock, mSettingsSecureAdapter);
when(mDefaultDialerCache.getDefaultDialerApplication(eq(UserHandle.USER_CURRENT)))
.thenReturn(PKG_NAME);
@@ -191,7 +223,11 @@
@SmallTest
@Test
- public void testDisallowCall() throws Exception {
+ public void testDisallowCallForCarrierDefined() throws Exception {
+ setCarrierDefinedCallScreeningApplication();
+ when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+ when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
mFilter.startFilterLookup(mCall, mCallback);
ServiceConnection serviceConnection = verifyBindingIntent();
serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
@@ -199,13 +235,73 @@
csAdapter.disallowCall(CALL_ID,
true, // shouldReject
false, // shouldAddToCallLog
- true // shouldShowNotification
+ true, // shouldShowNotification
+ CARRIER_DEFINED_CALL_SCREENING
);
verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
false, // shouldAllowCall
true, // shouldReject
false, // shouldAddToCallLog
- true // shouldShowNotification
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ CARRIER_DEFINED_CALL_SCREENING.getPackageName(), //callScreeningAppName
+ CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
+ )));
+ }
+
+ @SmallTest
+ @Test
+ public void testDisallowCallForDefaultDialer() throws Exception {
+ setCarrierDefinedCallScreeningApplication();
+ when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+ when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
+ mFilter.startFilterLookup(mCall, mCallback);
+ ServiceConnection serviceConnection = verifyBindingIntent();
+ serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+ ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+ csAdapter.disallowCall(CALL_ID,
+ true, // shouldReject
+ false, // shouldAddToCallLog
+ true, // shouldShowNotification
+ DEFAULT_DIALER_CALL_SCREENING
+ );
+ verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ true, // shouldAddToCallLog
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ DEFAULT_DIALER_CALL_SCREENING.getPackageName(), //callScreeningAppName
+ DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
+ )));
+ }
+
+ @SmallTest
+ @Test
+ public void testDisallowCallForUserChosen() throws Exception {
+ setCarrierDefinedCallScreeningApplication();
+ when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+ when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
+ mFilter.startFilterLookup(mCall, mCallback);
+ ServiceConnection serviceConnection = verifyBindingIntent();
+ serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+ ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+ csAdapter.disallowCall(CALL_ID,
+ true, // shouldReject
+ false, // shouldAddToCallLog
+ true, // shouldShowNotification
+ USER_CHOSEN_CALL_SCREENING
+ );
+ verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ true, // shouldAddToCallLog
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ USER_CHOSEN_CALL_SCREENING.getPackageName(), //callScreeningAppName
+ USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
)));
}
@@ -231,4 +327,14 @@
verify(mCallScreeningService).screenCall(captor.capture(), nullable(ParcelableCall.class));
return captor.getValue();
}
+
+ private void setCarrierDefinedCallScreeningApplication() {
+ String carrierDefined = "com.android.carrier/com.android.carrier.callscreeningserviceimpl";
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING,
+ carrierDefined);
+ when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+ .thenReturn(mCarrierConfigManager);
+ when(mCarrierConfigManager.getConfig()).thenReturn(bundle);
+ }
}
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index af4c168..a685c5e 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.tests;
import android.net.Uri;
+import android.provider.CallLog;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.CallerInfo;
@@ -65,7 +66,10 @@
false, // shouldAllowCall
true, // shouldReject
true, // shouldAddToCallLog
- true // shouldShowNotification
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
+ null, //callScreeningAppName
+ null // callScreeningComponentName
));
}
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
index d975ec2..e399088 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -19,6 +19,7 @@
import android.content.ContentResolver;
import android.content.IContentProvider;
import android.net.Uri;
+import android.provider.CallLog;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.Call;
@@ -55,6 +56,7 @@
@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;
@@ -62,7 +64,7 @@
private static final long LONG_TIMEOUT = 1000000;
private static final long SHORT_TIMEOUT = 100;
- private static final CallFilteringResult RESULT1 =
+ private static final CallFilteringResult PASS_CALL_RESULT =
new CallFilteringResult(
true, // shouldAllowCall
false, // shouldReject
@@ -70,23 +72,41 @@
true // shouldShowNotification
);
- private static final CallFilteringResult RESULT2 =
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true // shouldShowNotification
- );
-
- private static final CallFilteringResult RESULT3 =
+ private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
new CallFilteringResult(
false, // shouldAllowCall
true, // shouldReject
true, // shouldAddToCallLog
- false // shouldShowNotification
+ false, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
+ null, //callScreeningAppName
+ null //callScreeningComponentName
);
- private static final CallFilteringResult DEFAULT_RESULT = RESULT1;
+ private static final CallFilteringResult DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT =
+ new CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ true, // shouldAddToCallLog
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
+ null, //callScreeningAppName
+ null //callScreeningComponentName
+ );
+
+ private static final CallFilteringResult CALL_SCREENING_SERVICE_BLOCK_RESULT =
+ new CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ false, // shouldAddToCallLog
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ "com.android.thirdparty", //callScreeningAppName
+ "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
+ //callScreeningComponentName
+ );
+
+ private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
@Override
@Before
@@ -99,20 +119,97 @@
@SmallTest
@Test
- public void testSingleFilter() {
+ public void testAsyncBlockCallResultFilter() {
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
- testFilter.onCallFilteringComplete(mCall, RESULT1);
+ testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(RESULT1));
+ verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
+ (ASYNC_BLOCK_CHECK_BLOCK_RESULT));
}
@SmallTest
@Test
- public void testMultipleFilters() {
+ public void testDirectToVoiceMailCallResultFilter() {
+ IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ 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));
+ 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));
+ 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);
+ 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 CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ false, // shouldAddToCallLog
+ false, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
+ null, //callScreeningAppName
+ null //callScreeningComponentName
+ )));
+ }
+
+ @SmallTest
+ @Test
+ public void testMultipleFiltersForDirectToVoicemailCallFilter() {
List<IncomingCallFilter.CallFilter> filters =
new ArrayList<IncomingCallFilter.CallFilter>() {{
add(mFilter1);
@@ -126,16 +223,49 @@
verify(mFilter2).startFilterLookup(mCall, testFilter);
verify(mFilter3).startFilterLookup(mCall, testFilter);
- testFilter.onCallFilteringComplete(mCall, RESULT1);
- testFilter.onCallFilteringComplete(mCall, RESULT2);
- testFilter.onCallFilteringComplete(mCall, RESULT3);
+ 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 CallFilteringResult(
false, // shouldAllowCall
true, // shouldReject
false, // shouldAddToCallLog
- false // shouldShowNotification
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
+ null, ////callScreeningAppName
+ null ////callScreeningComponentName
+ )));
+ }
+
+ @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);
+ 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 CallFilteringResult(
+ false, // shouldAllowCall
+ true, // shouldReject
+ false, // shouldAddToCallLog
+ true, // shouldShowNotification
+ CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+ "com.android.thirdparty", //callScreeningAppName
+ "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
+ //callScreeningComponentName
)));
}
@@ -148,7 +278,7 @@
testFilter.performFiltering();
verify(mResultCallback, timeout((int) SHORT_TIMEOUT * 2)).onCallFilteringComplete(eq(mCall),
eq(DEFAULT_RESULT));
- testFilter.onCallFilteringComplete(mCall, RESULT1);
+ 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),
@@ -162,7 +292,7 @@
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
testFilter.performFiltering();
- testFilter.onCallFilteringComplete(mCall, RESULT1);
+ testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
Thread.sleep(SHORT_TIMEOUT);
verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
@@ -172,9 +302,13 @@
@SmallTest
@Test
public void testToString() {
- assertEquals("[Allow, logged, notified]", RESULT1.toString());
- assertEquals("[Reject, notified]", RESULT2.toString());
- assertEquals("[Reject, logged]", RESULT3.toString());
+ 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 {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 8905361..a459aac 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -100,7 +100,7 @@
public static class CallIntentProcessAdapterFake implements CallIntentProcessor.Adapter {
@Override
public void processOutgoingCallIntent(Context context, CallsManager callsManager,
- Intent intent) {
+ Intent intent, String callingPackage) {
}