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
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 84901fb..576a89e 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -236,7 +236,6 @@
     private DashboardFeatureProvider mDashboardFeatureProvider;
     private Intent mResultIntentData;
     private ComponentName mCurrentSuggestion;
-    private final StringBuffer mDebugData = new StringBuffer();
 
     @VisibleForTesting
     String mSearchQuery;
@@ -433,34 +432,7 @@
             mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
 
         } else {
-            if (!mIsShowingDashboard) {
-                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);
-            }
+            launchSettingFragment(initialFragmentName, isSubSettings, intent);
         }
 
         mActionBar = getActionBar();
@@ -532,6 +504,35 @@
         }
     }
 
+    @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) {
         if (displaySearch != mDisplaySearch) {
             mDisplaySearch = displaySearch;
@@ -693,7 +694,6 @@
         String startingFragment = getStartingFragmentClass(superIntent);
         // This is called from super.onCreate, isMultiPane() is not yet reliable
         // Do not use onIsHidingHeaders either, which relies itself on this method
-        log("getIntent() startingFragment", startingFragment);
         if (startingFragment != null) {
             Intent modIntent = new Intent(superIntent);
             modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
@@ -715,11 +715,9 @@
      * returns the class name to load as a fragment.
      */
     private String getStartingFragmentClass(Intent intent) {
-        log("getStartingFragmentClass() mFragmentClass", mFragmentClass);
         if (mFragmentClass != null) return mFragmentClass;
 
         String intentClass = intent.getComponent().getClassName();
-        log("getStartingFragmentClass() intentClass", intentClass);
         if (intentClass.equals(getClass().getName())) return null;
 
         if ("com.android.settings.ManageApplications".equals(intentClass)
@@ -1125,37 +1123,4 @@
         }
         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(", ");
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 1661947..df7a454 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -16,18 +16,47 @@
 
 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.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 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)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SettingsActivityTest {
 
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private FragmentManager mFragmentManager;
+
     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
     public void testQueryTextChange_shouldUpdate() {
         final String testQuery = "abc";
@@ -42,4 +71,16 @@
 
         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));
+    }
 }