Fix crash when switching to fragment with null name.
Check for null fragment name before trying to launch the fragment. Change-Id: Ibee6f7a1f27f7bc7d556a600c7e43fd30c2f1d6c Fix: 35203478 Test: make RunSettingsRoboTests
This commit is contained in:
@@ -236,7 +236,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
private DashboardFeatureProvider mDashboardFeatureProvider;
|
private DashboardFeatureProvider mDashboardFeatureProvider;
|
||||||
private Intent mResultIntentData;
|
private Intent mResultIntentData;
|
||||||
private ComponentName mCurrentSuggestion;
|
private ComponentName mCurrentSuggestion;
|
||||||
private final StringBuffer mDebugData = new StringBuffer();
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
String mSearchQuery;
|
String mSearchQuery;
|
||||||
@@ -433,34 +432,7 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
|
mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!mIsShowingDashboard) {
|
launchSettingFragment(initialFragmentName, isSubSettings, intent);
|
||||||
if (initialFragmentName == null) {
|
|
||||||
logFragmentData(intent, className, isSubSettings);
|
|
||||||
}
|
|
||||||
mDisplaySearch = false;
|
|
||||||
// UP will be shown only if it is a sub settings
|
|
||||||
if (mIsShortcut) {
|
|
||||||
mDisplayHomeAsUpEnabled = isSubSettings;
|
|
||||||
} else if (isSubSettings) {
|
|
||||||
mDisplayHomeAsUpEnabled = true;
|
|
||||||
} else {
|
|
||||||
mDisplayHomeAsUpEnabled = false;
|
|
||||||
}
|
|
||||||
setTitleFromIntent(intent);
|
|
||||||
|
|
||||||
Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
|
||||||
switchToFragment(initialFragmentName, initialArguments, true, false,
|
|
||||||
mInitialTitleResId, mInitialTitle, false);
|
|
||||||
} else {
|
|
||||||
// No UP affordance if we are displaying the main Dashboard
|
|
||||||
mDisplayHomeAsUpEnabled = false;
|
|
||||||
// Show Search affordance
|
|
||||||
mDisplaySearch = true;
|
|
||||||
mInitialTitleResId = R.string.dashboard_title;
|
|
||||||
|
|
||||||
switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
|
|
||||||
mInitialTitleResId, mInitialTitle, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mActionBar = getActionBar();
|
mActionBar = getActionBar();
|
||||||
@@ -532,6 +504,35 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void launchSettingFragment(String initialFragmentName, boolean isSubSettings, Intent intent) {
|
||||||
|
if (!mIsShowingDashboard && initialFragmentName != null) {
|
||||||
|
mDisplaySearch = false;
|
||||||
|
// UP will be shown only if it is a sub settings
|
||||||
|
if (mIsShortcut) {
|
||||||
|
mDisplayHomeAsUpEnabled = isSubSettings;
|
||||||
|
} else if (isSubSettings) {
|
||||||
|
mDisplayHomeAsUpEnabled = true;
|
||||||
|
} else {
|
||||||
|
mDisplayHomeAsUpEnabled = false;
|
||||||
|
}
|
||||||
|
setTitleFromIntent(intent);
|
||||||
|
|
||||||
|
Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||||
|
switchToFragment(initialFragmentName, initialArguments, true, false,
|
||||||
|
mInitialTitleResId, mInitialTitle, false);
|
||||||
|
} else {
|
||||||
|
// No UP affordance if we are displaying the main Dashboard
|
||||||
|
mDisplayHomeAsUpEnabled = false;
|
||||||
|
// Show Search affordance
|
||||||
|
mDisplaySearch = true;
|
||||||
|
mInitialTitleResId = R.string.dashboard_title;
|
||||||
|
|
||||||
|
switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
|
||||||
|
mInitialTitleResId, mInitialTitle, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setDisplaySearchMenu(boolean displaySearch) {
|
public void setDisplaySearchMenu(boolean displaySearch) {
|
||||||
if (displaySearch != mDisplaySearch) {
|
if (displaySearch != mDisplaySearch) {
|
||||||
mDisplaySearch = displaySearch;
|
mDisplaySearch = displaySearch;
|
||||||
@@ -693,7 +694,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
String startingFragment = getStartingFragmentClass(superIntent);
|
String startingFragment = getStartingFragmentClass(superIntent);
|
||||||
// This is called from super.onCreate, isMultiPane() is not yet reliable
|
// This is called from super.onCreate, isMultiPane() is not yet reliable
|
||||||
// Do not use onIsHidingHeaders either, which relies itself on this method
|
// Do not use onIsHidingHeaders either, which relies itself on this method
|
||||||
log("getIntent() startingFragment", startingFragment);
|
|
||||||
if (startingFragment != null) {
|
if (startingFragment != null) {
|
||||||
Intent modIntent = new Intent(superIntent);
|
Intent modIntent = new Intent(superIntent);
|
||||||
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
|
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
|
||||||
@@ -715,11 +715,9 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
* returns the class name to load as a fragment.
|
* returns the class name to load as a fragment.
|
||||||
*/
|
*/
|
||||||
private String getStartingFragmentClass(Intent intent) {
|
private String getStartingFragmentClass(Intent intent) {
|
||||||
log("getStartingFragmentClass() mFragmentClass", mFragmentClass);
|
|
||||||
if (mFragmentClass != null) return mFragmentClass;
|
if (mFragmentClass != null) return mFragmentClass;
|
||||||
|
|
||||||
String intentClass = intent.getComponent().getClassName();
|
String intentClass = intent.getComponent().getClassName();
|
||||||
log("getStartingFragmentClass() intentClass", intentClass);
|
|
||||||
if (intentClass.equals(getClass().getName())) return null;
|
if (intentClass.equals(getClass().getName())) return null;
|
||||||
|
|
||||||
if ("com.android.settings.ManageApplications".equals(intentClass)
|
if ("com.android.settings.ManageApplications".equals(intentClass)
|
||||||
@@ -1125,37 +1123,4 @@ public class SettingsActivity extends SettingsDrawerActivity
|
|||||||
}
|
}
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logFragmentData(Intent intent, String className, boolean isSubSettings) {
|
|
||||||
if (intent != null) {
|
|
||||||
logBundleData(intent.getExtras(), "Intent extra");
|
|
||||||
logBundleData(intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS), "Fragment args");
|
|
||||||
} else {
|
|
||||||
log("Intent data", "NULL");
|
|
||||||
}
|
|
||||||
log("Fragment", mFragmentClass);
|
|
||||||
log("Shortcut", mIsShortcut);
|
|
||||||
log("Class Name", className);
|
|
||||||
log("Show dashboard", mIsShowingDashboard);
|
|
||||||
log("Sub setting", isSubSettings);
|
|
||||||
log("Title", mInitialTitle);
|
|
||||||
Log.d(LOG_TAG, mDebugData.toString());
|
|
||||||
mDebugData.delete(0, mDebugData.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void logBundleData(Bundle data, String name) {
|
|
||||||
if (data != null) {
|
|
||||||
final Set<String> keys = data.keySet();
|
|
||||||
mDebugData.append(name).append(": ");
|
|
||||||
for (String key : keys) {
|
|
||||||
log(key, data.get(key));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log(name, "NULL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void log(String key, Object data) {
|
|
||||||
mDebugData.append(key).append("=").append(data).append(", ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -16,18 +16,47 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
|
import android.app.FragmentManager;
|
||||||
|
import android.app.FragmentTransaction;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
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)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
public class SettingsActivityTest {
|
public class SettingsActivityTest {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private FragmentManager mFragmentManager;
|
||||||
|
|
||||||
private SettingsActivity mActivity;
|
private SettingsActivity mActivity;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
FakeFeatureFactory.setupForTest(mContext);
|
||||||
|
final FakeFeatureFactory factory =
|
||||||
|
(FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
||||||
|
when(factory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryTextChange_shouldUpdate() {
|
public void testQueryTextChange_shouldUpdate() {
|
||||||
final String testQuery = "abc";
|
final String testQuery = "abc";
|
||||||
@@ -42,4 +71,16 @@ public class SettingsActivityTest {
|
|||||||
|
|
||||||
assertThat(mActivity.mSearchQuery).isEqualTo(testQuery);
|
assertThat(mActivity.mSearchQuery).isEqualTo(testQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash()
|
||||||
|
throws ClassNotFoundException {
|
||||||
|
mActivity = spy(new SettingsActivity());
|
||||||
|
when(mActivity.getFragmentManager()).thenReturn(mFragmentManager);
|
||||||
|
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
||||||
|
|
||||||
|
doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
|
||||||
|
|
||||||
|
mActivity.launchSettingFragment(null, true, mock(Intent.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user