Apply Dnd filter only calls with dnd only filter extra
1. Still apply Dnd call filter even if phone account has EXTRA_SKIP_CALL_FILTERING
, this is to make sure BluetoothInCallService works as intended when Dnd is on.
2. Create a provider interface for InComingCallFilterGraph for uni testing purpose.
Test: manual test works, dialer can receive this boolean in extra
Bug: 222333869
Change-Id: I9e65555d0524b213cb1ab2e9b89316f9638f80e9
diff --git a/flags/Android.bp b/flags/Android.bp
index 0e2071b..402826a 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -25,6 +25,7 @@
"telecom_broadcast_flags.aconfig",
"telecom_ringer_flag_declarations.aconfig",
"telecom_api_flags.aconfig",
+ "telecom_call_filtering_flags.aconfig",
"telecom_incallservice_flags.aconfig"
],
}
diff --git a/flags/telecom_call_filtering_flags.aconfig b/flags/telecom_call_filtering_flags.aconfig
new file mode 100644
index 0000000..95e74ce
--- /dev/null
+++ b/flags/telecom_call_filtering_flags.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.server.telecom.flags"
+
+flag {
+ name: "skip_filter_phone_account_perform_dnd_filter"
+ namespace: "telecom"
+ description: "Gates whether to still perform Dnd filter when phone account has skip_filter call extra."
+ bug: "222333869"
+}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 92e187c..bf5e624 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -129,6 +129,7 @@
import com.android.server.telecom.callfiltering.DirectToVoicemailFilter;
import com.android.server.telecom.callfiltering.DndCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
+import com.android.server.telecom.callfiltering.IncomingCallFilterGraphProvider;
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.components.ErrorDialogActivity;
import com.android.server.telecom.components.TelecomBroadcastReceiver;
@@ -466,6 +467,8 @@
private final CallStreamingNotification mCallStreamingNotification;
private final FeatureFlags mFeatureFlags;
+ private final IncomingCallFilterGraphProvider mIncomingCallFilterGraphProvider;
+
private final ConnectionServiceFocusManager.CallsManagerRequester mRequester =
new ConnectionServiceFocusManager.CallsManagerRequester() {
@Override
@@ -580,7 +583,8 @@
EmergencyCallDiagnosticLogger emergencyCallDiagnosticLogger,
CallAudioCommunicationDeviceTracker communicationDeviceTracker,
CallStreamingNotification callStreamingNotification,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ IncomingCallFilterGraphProvider incomingCallFilterGraphProvider) {
mContext = context;
mLock = lock;
@@ -599,6 +603,7 @@
mEmergencyCallHelper = emergencyCallHelper;
mCallerInfoLookupHelper = callerInfoLookupHelper;
mEmergencyCallDiagnosticLogger = emergencyCallDiagnosticLogger;
+ mIncomingCallFilterGraphProvider = incomingCallFilterGraphProvider;
mDtmfLocalTonePlayer =
new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
@@ -793,11 +798,12 @@
? new Bundle()
: phoneAccount.getExtras();
TelephonyManager telephonyManager = getTelephonyManager();
+ boolean performDndFilter = mFeatureFlags.skipFilterPhoneAccountPerformDndFilter();
if (incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE) ||
incomingCall.hasProperty(Connection.PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL) ||
telephonyManager.isInEmergencySmsMode() ||
incomingCall.isSelfManaged() ||
- extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING)) {
+ (!performDndFilter && extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING))) {
Log.i(this, "Skipping call filtering for %s (ecm=%b, "
+ "networkIdentifiedEmergencyCall = %b, emergencySmsMode = %b, "
+ "selfMgd=%b, skipExtra=%b)",
@@ -815,12 +821,27 @@
.build(), false);
incomingCall.setIsUsingCallFiltering(false);
return;
+ } else if (performDndFilter && extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING)) {
+ IncomingCallFilterGraph graph = setupDndFilterOnlyGraph(incomingCall);
+ graph.performFiltering();
+ return;
}
IncomingCallFilterGraph graph = setUpCallFilterGraph(incomingCall);
graph.performFiltering();
}
+ private IncomingCallFilterGraph setupDndFilterOnlyGraph(Call incomingHfpCall) {
+ incomingHfpCall.setIsUsingCallFiltering(true);
+ DndCallFilter dndCallFilter = new DndCallFilter(incomingHfpCall, mRinger);
+ IncomingCallFilterGraph graph = mIncomingCallFilterGraphProvider.createGraph(
+ incomingHfpCall,
+ this::onCallFilteringComplete, mContext, mTimeoutsAdapter, mLock);
+ graph.addFilter(dndCallFilter);
+ mGraphHandlerThreads.add(graph.getHandlerThread());
+ return graph;
+ }
+
private IncomingCallFilterGraph setUpCallFilterGraph(Call incomingCall) {
incomingCall.setIsUsingCallFiltering(true);
String carrierPackageName = getCarrierPackageName();
@@ -833,7 +854,7 @@
mContext.getPackageManager(), packageName);
ParcelableCallUtils.Converter converter = new ParcelableCallUtils.Converter();
- IncomingCallFilterGraph graph = new IncomingCallFilterGraph(incomingCall,
+ IncomingCallFilterGraph graph = mIncomingCallFilterGraphProvider.createGraph(incomingCall,
this::onCallFilteringComplete, mContext, mTimeoutsAdapter, mLock);
DirectToVoicemailFilter voicemailFilter = new DirectToVoicemailFilter(incomingCall,
mCallerInfoLookupHelper);
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 3d2f732..57d7139 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -45,6 +45,9 @@
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import com.android.server.telecom.callfiltering.BlockedNumbersAdapter;
+import com.android.server.telecom.callfiltering.CallFilterResultCallback;
+import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
+import com.android.server.telecom.callfiltering.IncomingCallFilterGraphProvider;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.flags.FeatureFlags;
@@ -409,7 +412,8 @@
emergencyCallDiagnosticLogger,
communicationDeviceTracker,
callStreamingNotification,
- featureFlags);
+ featureFlags,
+ IncomingCallFilterGraph::new);
mIncomingCallNotifier = incomingCallNotifier;
incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraphProvider.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraphProvider.java
new file mode 100644
index 0000000..1501280
--- /dev/null
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraphProvider.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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 com.android.server.telecom.Call;
+import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.Timeouts;
+
+/**
+ * Interface to provide a {@link IncomingCallFilterGraph}. This class serve for unit test purpose
+ * to mock an incoming call filter graph in test code.
+ */
+public interface IncomingCallFilterGraphProvider {
+
+
+ /**
+ * Provide a {@link IncomingCallFilterGraph}
+ * @param call The call for the filters.
+ * @param listener Callback object to trigger when filtering is done.
+ * @param context An android context.
+ * @param timeoutsAdapter Adapter to provide timeout value for call filtering.
+ * @param lock Telecom lock.
+ * @return
+ */
+ IncomingCallFilterGraph createGraph(Call call, CallFilterResultCallback listener,
+ Context context,
+ Timeouts.Adapter timeoutsAdapter, TelecomSystem.SyncRoot lock);
+}
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 8460c18..5577290 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -125,6 +125,7 @@
import com.android.server.telecom.callfiltering.BlockedNumbersAdapter;
import com.android.server.telecom.callfiltering.CallFilteringResult;
import com.android.server.telecom.flags.FeatureFlags;
+import com.android.server.telecom.callfiltering.IncomingCallFilterGraph;
import com.android.server.telecom.ui.AudioProcessingNotification;
import com.android.server.telecom.ui.CallStreamingNotification;
import com.android.server.telecom.ui.DisconnectedCallNotifier;
@@ -282,6 +283,8 @@
@Mock private CallStreamingNotification mCallStreamingNotification;
@Mock private FeatureFlags mFeatureFlags;
+ @Mock private IncomingCallFilterGraph mIncomingCallFilterGraph;
+
private CallsManager mCallsManager;
@Override
@@ -356,7 +359,8 @@
mEmergencyCallDiagnosticLogger,
mCommunicationDeviceTracker,
mCallStreamingNotification,
- mFeatureFlags);
+ mFeatureFlags,
+ (call, listener, context, timeoutsAdapter, lock) -> mIncomingCallFilterGraph);
when(mPhoneAccountRegistrar.getPhoneAccount(
eq(SELF_MANAGED_HANDLE), any())).thenReturn(SELF_MANAGED_ACCOUNT);
@@ -1326,8 +1330,9 @@
@SmallTest
@Test
- public void testNoFilteringOfCallsWhenPhoneAccountRequestsSkipped() {
+ public void testDndFilterAppliesOfCallsWhenPhoneAccountRequestsSkipped() {
// GIVEN an incoming call which is from a PhoneAccount that requested to skip filtering.
+ when(mFeatureFlags.skipFilterPhoneAccountPerformDndFilter()).thenReturn(true);
Call incomingCall = addSpyCall(SIM_1_HANDLE, CallState.NEW);
Bundle extras = new Bundle();
extras.putBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING, true);
@@ -1347,7 +1352,35 @@
// WHEN the incoming call is successfully added.
mCallsManager.onSuccessfulIncomingCall(incomingCall);
- // THEN the incoming call is not using call filtering
+ // THEN the incoming call is still applying Dnd filter.
+ verify(incomingCall).setIsUsingCallFiltering(eq(true));
+ }
+
+ @SmallTest
+ @Test
+ public void testNoFilterAppliesOfCallsWhenFlagNotEnabled() {
+ // Flag is not enabled.
+ when(mFeatureFlags.skipFilterPhoneAccountPerformDndFilter()).thenReturn(false);
+ Call incomingCall = addSpyCall(SIM_1_HANDLE, CallState.NEW);
+ Bundle extras = new Bundle();
+ extras.putBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING, true);
+ PhoneAccount skipRequestedAccount = new PhoneAccount.Builder(SIM_2_HANDLE, "Skipper")
+ .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
+ | PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setExtras(extras)
+ .setIsEnabled(true)
+ .build();
+ when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(SIM_1_HANDLE))
+ .thenReturn(skipRequestedAccount);
+ doReturn(false).when(incomingCall).can(Connection.CAPABILITY_HOLD);
+ doReturn(false).when(incomingCall).can(Connection.CAPABILITY_SUPPORT_HOLD);
+ doReturn(false).when(incomingCall).isSelfManaged();
+ doReturn(true).when(incomingCall).setState(anyInt(), any());
+
+ // WHEN the incoming call is successfully added.
+ mCallsManager.onSuccessfulIncomingCall(incomingCall);
+
+ // THEN the incoming call is not applying filter.
verify(incomingCall).setIsUsingCallFiltering(eq(false));
}