[Call Screening]Programmatically changing the default call screening app.
Implement three methods increased in TelecomManager.java, increase
one activity in Telecomm services and four test cases in
TelecomServiceImplTest.java.
Bug: 113302920
Test: atest TelecomServiceImplTest.
Test: simulate third party call screening application to use methods in
TelecomManager.java, and triggle the activity to show the dialog of
setting default call screeening application.
Change-Id: I391debd3755f392a1f95c7d1301a99da05459cdc
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d3ada02..9ea8f4c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -296,6 +296,15 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+
+ <activity android:name="com.android.server.telecom.components.ChangeDefaultCallScreeningApp"
+ android:label="@string/change_default_dialer_dialog_title"
+ android:excludeFromRecents="true"
+ android:theme="@*android:style/Theme.Material.Light.Dialog.Alert"
+ android:priority="1000"
+ android:process=":ui">
+ </activity>
+
<activity android:name=".ui.TelecomDeveloperMenu"
android:label="@string/developer_title"
android:exported="false"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9065173..eff68a0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -111,7 +111,7 @@
<!-- Button label on the "Missing voicemail number" dialog -->
<string name="add_vm_number_str">Add number</string>
- <!-- Title of dialog used to comfirm whether the user intends to change the default dialer
+ <!-- Title of dialog used to confirm whether the user intends to change the default dialer
application [CHAR LIMIT=55]-->
<string name="change_default_dialer_dialog_title">Make <xliff:g id="new_app">%s</xliff:g> your default Phone app?</string>
<!-- Confirmation text that a user taps on to change the Default Phone App-->
@@ -121,6 +121,18 @@
<!-- Warning message indicating what may happen if a user allows a 3rd party app to become the default dialer.-->
<string name="change_default_dialer_warning_message"><xliff:g id="new_app">%s</xliff:g> will be able to place and control all aspects of calls. Only apps you trust should be set as the default Phone app.</string>
+ <!-- Title of dialog used to confirm whether the user intends to change the default call screening
+ application [CHAR LIMIT=55]-->
+ <string name="change_default_call_screening_dialog_title">Make <xliff:g id="new_app">%s</xliff:g> your default call screening app?</string>
+ <!-- Warning message indicating the old call screening app will no longer be able to screen calls.-->
+ <string name="change_default_call_screening_warning_message_for_disable_old_app"><xliff:g id="old_app">%s</xliff:g> will no longer be able to screen calls.</string>
+ <!-- Warning message indicating what may happen if a user allows a 3rd party app to become the default call screening.-->
+ <string name="change_default_call_screening_warning_message"><xliff:g id="new_app">%s</xliff:g> will be able to see information about callers not in your contacts and will be able to block these calls. Only apps you trust should be set as the default call screening app.</string>
+ <!-- Confirmation text that a user taps on to change the Default call screening App-->
+ <string name="change_default_call_screening_dialog_affirmative">Set Default</string>
+ <!-- Cancel text that a user taps on to not change the Default call screening App-->
+ <string name="change_default_call_screening_dialog_negative">Cancel</string>
+
<!-- Blocked numbers -->
<string name="blocked_numbers">Blocked numbers</string>
<!-- Text shown at the beginning of the blocked numbers screen to explain what the screen is about. -->
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index c775931..892b5b0 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -29,16 +29,21 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.CallScreeningService;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
@@ -47,10 +52,12 @@
import android.telecom.VideoProfile;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.EventLog;
import com.android.internal.telecom.ITelecomService;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.telecom.components.ChangeDefaultCallScreeningApp;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.settings.BlockedNumbersActivity;
@@ -77,6 +84,25 @@
}
}
+ public interface SettingsSecureAdapter {
+ void putStringForUser(ContentResolver resolver, String name, String value, int userHandle);
+
+ String getStringForUser(ContentResolver resolver, String name, int userHandle);
+ }
+
+ static class SettingsSecureAdapterImpl implements SettingsSecureAdapter {
+ @Override
+ public void putStringForUser(ContentResolver resolver, String name, String value,
+ int userHandle) {
+ Settings.Secure.putStringForUser(resolver, name, value, userHandle);
+ }
+
+ @Override
+ public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
+ return Settings.Secure.getStringForUser(resolver, name, userHandle);
+ }
+ }
+
private static final String TIME_LINE_ARG = "timeline";
private static final int DEFAULT_VIDEO_STATE = -1;
private static final String PERMISSION_HANDLE_CALL_INTENT =
@@ -1319,6 +1345,147 @@
}
}
+ /**
+ * @see android.telecom.TelecomManager#requestChangeDefaultCallScreeningApp
+ */
+ @Override
+ public void requestChangeDefaultCallScreeningApp(ComponentName componentName, String
+ callingPackage) {
+ try {
+ Log.startSession("TSI.rCDCSA");
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ if (callingPackage.equals(componentName.getPackageName())) {
+ final Intent intent = new Intent(mContext,
+ ChangeDefaultCallScreeningApp.class);
+ intent.putExtra(
+ TelecomManager.EXTRA_DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME,
+ componentName.flattenToString());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ } else {
+ throw new SecurityException(
+ "calling package name does't match the package of the passed "
+ + "component name.");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ /**
+ * @see android.telecom.TelecomManager#isDefaultCallScreeningApp
+ */
+ @Override
+ public boolean isDefaultCallScreeningApp(ComponentName componentName) {
+ try {
+ Log.startSession("TSI.iDCSA");
+ synchronized (mLock) {
+ if (componentName == null) {
+ return false;
+ }
+ mAppOpsManager
+ .checkPackage(Binder.getCallingUid(), componentName.getPackageName());
+
+ long token = Binder.clearCallingIdentity();
+ try {
+ final String defaultPackage = mSettingsSecureAdapter
+ .getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT,
+ UserHandle.USER_CURRENT);
+
+ if (!TextUtils.isEmpty(defaultPackage) && !TextUtils
+ .isEmpty(componentName.flattenToString()) && TextUtils
+ .equals(defaultPackage, componentName.flattenToString())) {
+ return true;
+ } else {
+ Log.d(this,
+ "Provided package name is not the current default Call Screening application.");
+ return false;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ /**
+ * @see android.telecom.TelecomManager#setDefaultCallScreeningApp
+ */
+ @Override
+ public void setDefaultCallScreeningApp(ComponentName componentName) {
+ try {
+ Log.startSession("TSI.sDCSA");
+ enforcePermission(MODIFY_PHONE_STATE);
+ enforcePermission(WRITE_SECURE_SETTINGS);
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ try {
+ mContext.getPackageManager().getApplicationInfo(
+ componentName.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException(
+ "the specified package name does't exist componentName = " +
+ componentName);
+ }
+
+ Intent intent = new Intent(CallScreeningService.SERVICE_INTERFACE)
+ .setPackage(componentName.getPackageName());
+ List<ResolveInfo> entries = mContext.getPackageManager()
+ .queryIntentServicesAsUser(intent, 0,
+ mCallsManager.getCurrentUserHandle().getIdentifier());
+ if (entries.isEmpty()) {
+ throw new IllegalArgumentException(
+ "The specified package name doesn't have call screening services");
+ }
+
+ try {
+ ServiceInfo serviceInfo = mContext.getPackageManager().getServiceInfo(
+ componentName, 0);
+ if (!Manifest.permission.BIND_SCREENING_SERVICE.equals(serviceInfo
+ .permission)) {
+ throw new IllegalArgumentException(
+ "The passed component doesn't require " +
+ "BIND_SCREENING_SERVICE permission");
+ }
+
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException(
+ "the specified component name does't exist componentName = "
+ + componentName);
+ }
+
+ final String oldComponentName = mSettingsSecureAdapter
+ .getStringForUser(mContext.getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT,
+ UserHandle.USER_CURRENT);
+
+ broadcastCallScreeningAppChangedIntent(oldComponentName, false);
+
+ mSettingsSecureAdapter.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT,
+ componentName.flattenToString(), UserHandle.USER_CURRENT);
+
+ broadcastCallScreeningAppChangedIntent(componentName.flattenToString(),
+ true);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
@Override
public TelecomAnalytics dumpCallAnalytics() {
try {
@@ -1549,6 +1716,7 @@
private final UserCallIntentProcessorFactory mUserCallIntentProcessorFactory;
private final DefaultDialerCache mDefaultDialerCache;
private final SubscriptionManagerAdapter mSubscriptionManagerAdapter;
+ private final SettingsSecureAdapter mSettingsSecureAdapter;
private final TelecomSystem.SyncRoot mLock;
public TelecomServiceImpl(
@@ -1559,6 +1727,7 @@
UserCallIntentProcessorFactory userCallIntentProcessorFactory,
DefaultDialerCache defaultDialerCache,
SubscriptionManagerAdapter subscriptionManagerAdapter,
+ SettingsSecureAdapter settingsSecureAdapter,
TelecomSystem.SyncRoot lock) {
mContext = context;
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -1572,6 +1741,7 @@
mDefaultDialerCache = defaultDialerCache;
mCallIntentProcessorAdapter = callIntentProcessorAdapter;
mSubscriptionManagerAdapter = subscriptionManagerAdapter;
+ mSettingsSecureAdapter = settingsSecureAdapter;
}
public ITelecomService.Stub getBinder() {
@@ -1848,4 +2018,24 @@
// If only TX or RX were set (or neither), the video state is valid.
return remainingState == 0;
}
+
+ private void broadcastCallScreeningAppChangedIntent(String componentName,
+ boolean isDefault) {
+ if (TextUtils.isEmpty(componentName)) {
+ return;
+ }
+
+ ComponentName broadcastComponentName = ComponentName.unflattenFromString(componentName);
+
+ if (broadcastComponentName != null) {
+ Intent intent = new Intent(TelecomManager
+ .ACTION_DEFAULT_CALL_SCREENING_APP_CHANGED);
+ intent.putExtra(TelecomManager
+ .EXTRA_IS_DEFAULT_CALL_SCREENING_APP, isDefault);
+ intent.putExtra(TelecomManager
+ .EXTRA_DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME, componentName);
+ intent.setPackage(broadcastComponentName.getPackageName());
+ mContext.sendBroadcast(intent);
+ }
+ }
}
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 6fa7167..c22bfec 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -332,6 +332,7 @@
},
defaultDialerCache,
new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
+ new TelecomServiceImpl.SettingsSecureAdapterImpl(),
mLock);
Log.endSession();
}
diff --git a/src/com/android/server/telecom/components/ChangeDefaultCallScreeningApp.java b/src/com/android/server/telecom/components/ChangeDefaultCallScreeningApp.java
new file mode 100644
index 0000000..a88c7d1
--- /dev/null
+++ b/src/com/android/server/telecom/components/ChangeDefaultCallScreeningApp.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018 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.components;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+import com.android.server.telecom.R;
+
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.Log;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+
+public class ChangeDefaultCallScreeningApp extends AlertActivity implements
+ DialogInterface.OnClickListener {
+
+ private static final String TAG = ChangeDefaultCallScreeningApp.class.getSimpleName();
+ private ComponentName mNewComponentName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mNewComponentName = ComponentName.unflattenFromString(getIntent().getStringExtra(
+ TelecomManager.EXTRA_DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME));
+
+ if (canChangeDefaultCallScreening()) {
+ buildDialog();
+ } else {
+ finish();
+ }
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ case BUTTON_POSITIVE:
+ try {
+ TelecomManager.from(this).setDefaultCallScreeningApp(mNewComponentName);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, e, e.getMessage());
+ break;
+ }
+ break;
+ case BUTTON_NEGATIVE:
+ break;
+ }
+ }
+
+ private boolean canChangeDefaultCallScreening() {
+ boolean canChange;
+ String defaultComponentName = Settings.Secure
+ .getStringForUser(getApplicationContext().getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT);
+
+ ComponentName oldComponentName = TextUtils.isEmpty(defaultComponentName) ? null
+ : ComponentName.unflattenFromString(defaultComponentName);
+
+ canChange = oldComponentName == null || !oldComponentName.getPackageName()
+ .equals(mNewComponentName.getPackageName()) || !oldComponentName.flattenToString()
+ .equals(mNewComponentName.flattenToString());
+
+ return canChange;
+ }
+
+ private void buildDialog() {
+ final String newPackageLabel = getApplicationLabel(mNewComponentName);
+ final AlertController.AlertParams p = mAlertParams;
+
+ p.mTitle = getString(R.string.change_default_call_screening_dialog_title, newPackageLabel);
+ p.mMessage = getDialogBody(newPackageLabel);
+ p.mPositiveButtonText = getString(
+ R.string.change_default_call_screening_dialog_affirmative);
+ p.mNegativeButtonText = getString(R.string.change_default_call_screening_dialog_negative);
+ p.mPositiveButtonListener = this;
+ p.mNegativeButtonListener = this;
+
+ setupAlert();
+ }
+
+ private String getDialogBody(String newPackageLabel) {
+ final String oldPackage = Settings.Secure.getStringForUser(
+ getApplicationContext().getContentResolver(),
+ Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT);
+ ComponentName oldPackageComponentName = null;
+ if (!TextUtils.isEmpty(oldPackage)) {
+ oldPackageComponentName = ComponentName.unflattenFromString(oldPackage);
+ }
+
+ String dialogBody = getString(R.string.change_default_call_screening_warning_message,
+ newPackageLabel);
+
+ if (oldPackageComponentName != null) {
+ dialogBody = getString(
+ R.string.change_default_call_screening_warning_message_for_disable_old_app,
+ getApplicationLabel(oldPackageComponentName)) + " "
+ + dialogBody;
+ }
+
+ return dialogBody;
+ }
+
+ /**
+ * Returns the application label that corresponds to the given package name
+ *
+ * @return Application label for the given package name, or null if not found.
+ */
+ private String getApplicationLabel(ComponentName componentName) {
+ final PackageManager pm = getPackageManager();
+
+ try {
+ ApplicationInfo info = pm.getApplicationInfo(componentName.getPackageName(), 0);
+ return pm.getApplicationLabel(info).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Application info not found for packageName " + componentName
+ .getPackageName());
+ }
+
+ return componentName.getPackageName();
+ }
+}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 0e79fce..8132157 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -34,6 +34,7 @@
<!-- Used to access TelephonyManager APIs -->
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application android:label="@string/app_name"
android:debuggable="true">
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index cbca5e1..8905361 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -25,6 +25,7 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -87,6 +88,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -121,6 +123,20 @@
}
}
+ 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 THIRD_PARTY_CALL_SCREENING.flattenToString();
+ }
+ }
+
private static class AnyStringIn implements ArgumentMatcher<String> {
private Collection<String> mStrings;
public AnyStringIn(Collection<String> strings) {
@@ -145,6 +161,8 @@
@Mock private DefaultDialerCache mDefaultDialerCache;
private TelecomServiceImpl.SubscriptionManagerAdapter mSubscriptionManagerAdapter =
spy(new SubscriptionManagerAdapterFake());
+ private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
+ spy(new SettingsSecureAdapterFake());
@Mock private UserCallIntentProcessor mUserCallIntentProcessor;
private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
@@ -160,6 +178,8 @@
new ComponentName("test", "telComponentName"), "2", Binder.getCallingUserHandle());
private static final PhoneAccountHandle SIP_PA_HANDLE_CURRENT = new PhoneAccountHandle(
new ComponentName("test", "sipComponentName"), "3", Binder.getCallingUserHandle());
+ private static final ComponentName THIRD_PARTY_CALL_SCREENING = new ComponentName("com.android" +
+ ".thirdparty", "com.android.thirdparty.callscreeningserviceimpl");
@Override
@Before
@@ -185,6 +205,7 @@
},
mDefaultDialerCache,
mSubscriptionManagerAdapter,
+ mSettingsSecureAdapter,
mLock);
mTSIBinder = telecomServiceImpl.getBinder();
mComponentContextFixture.setTelecomManager(mTelecomManager);
@@ -743,6 +764,80 @@
@SmallTest
@Test
+ public void testRequestChangeDefaultCallScreeningAppCallingPackageMatchComponentName()
+ throws Exception {
+ String callingPackage = "com.android.thirdparty";
+
+ doNothing().when(mContext).startActivity(any(Intent.class));
+
+ mTSIBinder.requestChangeDefaultCallScreeningApp(THIRD_PARTY_CALL_SCREENING,
+ callingPackage);
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, times(1)).startActivity(intentCaptor.capture());
+
+ Intent capturedIntent = intentCaptor.getValue();
+ String className = capturedIntent.getComponent().getClassName();
+ assertEquals(className,
+ "com.android.server.telecom.components.ChangeDefaultCallScreeningApp");
+
+ String packageNameExtra = capturedIntent.getStringExtra(
+ TelecomManager.EXTRA_DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME);
+ assertEquals(packageNameExtra, THIRD_PARTY_CALL_SCREENING.flattenToString());
+ }
+
+ @SmallTest
+ @Test
+ public void testRequestChangeDefaultCallScreeningAppCallingPackageNoMatchComponentName()
+ throws Exception {
+ boolean exceptionThrown = false;
+ String callingPackage = "com.android.unknown";
+
+ try {
+ mTSIBinder
+ .requestChangeDefaultCallScreeningApp(THIRD_PARTY_CALL_SCREENING, callingPackage);
+ } catch (SecurityException e) {
+ exceptionThrown = true;
+ }
+
+ assertTrue(exceptionThrown);
+ }
+
+ @SmallTest
+ @Test
+ public void testIsDefaultCallScreeningApp() throws Exception {
+ doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
+ assertTrue(mTSIBinder.isDefaultCallScreeningApp(THIRD_PARTY_CALL_SCREENING));
+ }
+
+ @SmallTest
+ @Test
+ public void testIsDefaultCallScreeningAppFailure() throws Exception {
+ ComponentName unknownComponentName = new ComponentName("com.android.unknown",
+ "com.android.unknown.callscreeningserviceimpl");
+ assertFalse(mTSIBinder.isDefaultCallScreeningApp(unknownComponentName));
+ }
+
+ @SmallTest
+ @Test
+ public void testSetDefaultCallScreeningAppSpecifiedComponentNameNoExist() throws Exception {
+ boolean exceptionThrown = false;
+
+ when(mContext.getPackageManager()
+ .getApplicationInfo(THIRD_PARTY_CALL_SCREENING.getPackageName(), 0))
+ .thenThrow(new IllegalArgumentException());
+
+ try {
+ mTSIBinder.setDefaultCallScreeningApp(THIRD_PARTY_CALL_SCREENING);
+ } catch (IllegalArgumentException e) {
+ exceptionThrown = true;
+ }
+
+ assertTrue(exceptionThrown);
+ }
+
+ @SmallTest
+ @Test
public void testSetDefaultDialerNoModifyPhoneStatePermission() throws Exception {
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
eq(MODIFY_PHONE_STATE), nullable(String.class));