Fix crash when Assist app does not have settings activity.

Check for null settings activity before trying to create settings
intent. If there is no settings activity, we will not show settings gear
for the preference.

Change-Id: I16f9d695cf9ef09ff65f4511d53d5778760125b5
Fix: 37161567
Test: make RunSettingsRoboTests
This commit is contained in:
Doris Ling
2017-04-14 12:43:07 -07:00
parent d09c7e61f4
commit 386e21808c
2 changed files with 64 additions and 5 deletions

View File

@@ -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();
}
}

View File

@@ -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<ResolveInfo> 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
}
}