diff --git a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java index 747ce4da596..b8d6a87c94f 100644 --- a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java +++ b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java @@ -24,6 +24,7 @@ import android.content.pm.ResolveInfo; import android.service.voice.VoiceInteractionService; import android.service.voice.VoiceInteractionServiceInfo; +import android.support.annotation.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.applications.defaultapps.DefaultAppPreferenceController; @@ -56,13 +57,10 @@ public class DefaultAssistPreferenceController extends DefaultAppPreferenceContr if (services == null || services.isEmpty()) { return null; } - final ResolveInfo resolveInfo = services.get(0); - final VoiceInteractionServiceInfo voiceInfo = - new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo); - if (!voiceInfo.getSupportsAssist()) { + final String activity = getAssistSettingsActivity(cn, services.get(0), pm); + if (activity == null) { return null; } - final String activity = voiceInfo.getSettingsActivity(); return new Intent(Intent.ACTION_MAIN) .setComponent(new ComponentName(cn.getPackageName(), activity)); } @@ -85,4 +83,14 @@ public class DefaultAssistPreferenceController extends DefaultAppPreferenceContr } return new DefaultAppInfo(mPackageManager, mUserId, cn); } + + @VisibleForTesting + String getAssistSettingsActivity(ComponentName cn, ResolveInfo resolveInfo, PackageManager pm) { + final VoiceInteractionServiceInfo voiceInfo = + new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo); + if (!voiceInfo.getSupportsAssist()) { + return null; + } + return voiceInfo.getSettingsActivity(); + } } diff --git a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java index 1182762ae3a..728a8a56c67 100644 --- a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java @@ -16,7 +16,16 @@ package com.android.settings.applications.assist; +import android.Manifest; +import android.app.SearchManager; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.provider.Settings; import com.android.settings.SettingsRobolectricTestRunner; @@ -24,6 +33,8 @@ import com.android.settings.TestConfig; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.testutils.shadow.ShadowSecureSettings; +import java.util.ArrayList; +import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,6 +43,13 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @@ -39,6 +57,10 @@ public class DefaultAssistPreferenceControllerTest { @Mock private Context mContext; + @Mock + private SearchManager mSearchManager; + @Mock + private PackageManager mPackageManager; private DefaultAssistPreferenceController mController; @Before @@ -61,4 +83,33 @@ public class DefaultAssistPreferenceControllerTest { assertThat(appInfo.getKey()).isEqualTo(flattenKey); } + + @Test + public void getSettingIntent_noSettingsActivity_shouldNotCrash() { + final String flattenKey = "com.android.settings/assist"; + ShadowSecureSettings.putString(null, Settings.Secure.ASSISTANT, flattenKey); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + DefaultAssistPreferenceController controller = + spy(new DefaultAssistPreferenceController(mContext)); + final ResolveInfo resolveInfo = new ResolveInfo(); + resolveInfo.activityInfo = new ActivityInfo(); + resolveInfo.activityInfo.name = "assist"; + resolveInfo.activityInfo.applicationInfo = new ApplicationInfo(); + resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings"; + when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt())) + .thenReturn(resolveInfo); + when(mContext.getSystemService(Context.SEARCH_SERVICE)).thenReturn(mSearchManager); + when(mSearchManager.getAssistIntent(anyBoolean())).thenReturn(mock(Intent.class)); + final ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.permission = Manifest.permission.BIND_VOICE_INTERACTION; + resolveInfo.serviceInfo = serviceInfo; + final List services = new ArrayList<>(); + services.add(resolveInfo); + when(mPackageManager.queryIntentServices(any(Intent.class), anyInt())).thenReturn(services); + doReturn(null).when(controller).getAssistSettingsActivity( + ComponentName.unflattenFromString(flattenKey), resolveInfo, mPackageManager); + + controller.getSettingIntent(null); + // should not crash + } }