Fix Dialer NPE

Make sure that smart dialing state is properly set before
any digits in the dialpad EditText is populated.

Also turn smart dialing off by default even if the system
setting hasn't been previously set.

Bug 8963485

Change-Id: If556d8b1405cc9e60043774b3aafd5e111e4e7ee
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index ba82774..f571d89 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -555,7 +555,7 @@
 
         // retrieve dialpad autocomplete setting
         mSmartDialEnabled = Settings.Secure.getInt(contentResolver,
-                Settings.Secure.DIALPAD_AUTOCOMPLETE, 1) == 1;
+                Settings.Secure.DIALPAD_AUTOCOMPLETE, 0) == 1;
 
         stopWatch.lap("dtwd");
 
@@ -580,6 +580,10 @@
         // Prevent unnecessary confusion. Reset the press count anyway.
         mDialpadPressCount = 0;
 
+        // Initialize smart dialing state. This has to be done before anything is filled in before
+        // the dialpad edittext to prevent entries from being loaded from a null cache.
+        initializeSmartDialingState();
+
         Activity parent = getActivity();
         if (parent instanceof DialtactsActivity) {
             // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
@@ -621,26 +625,6 @@
             showDialpadChooser(false);
         }
 
-        // Handle smart dialing related state
-        if (mSmartDialEnabled) {
-            mSmartDialList.setVisibility(View.VISIBLE);
-            mSmartDialCache = SmartDialCache.getInstance(getActivity(),
-                    mContactsPrefs.getDisplayOrder());
-            // Don't force recache if this is the first time onResume is being called, since
-            // caching should already happen in setUserVisibleHint.
-            if (!mFirstLaunch) {
-                // This forced recache covers the case where the dialer was previously running, and
-                // was brought back into the foreground. If the dialpad fragment hasn't actually
-                // become visible throughout the entire activity's lifecycle, it is possible that
-                // caching hasn't happened yet. In this case, we can force a recache anyway, since
-                // we are not worried about startup performance anymore.
-                mSmartDialCache.cacheIfNeeded(true);
-            }
-        } else {
-            mSmartDialList.setVisibility(View.GONE);
-            mSmartDialCache = null;
-        }
-
         mFirstLaunch = false;
 
         stopWatch.lap("hnt");
@@ -1701,6 +1685,11 @@
             return;
         }
 
+        if (mSmartDialCache == null) {
+            Log.e(TAG, "Trying to load smart dialing entries from a null cache");
+            return;
+        }
+
         // Update only when the digits have changed.
         final String digits = SmartDialNameMatcher.normalizeNumber(mDigits.getText().toString());
         if (TextUtils.equals(digits, mLastDigitsForSmartDial)) {
@@ -1724,6 +1713,28 @@
         mSmartDialAdapter.setEntries(data);
     }
 
+    private void initializeSmartDialingState() {
+        // Handle smart dialing related state
+        if (mSmartDialEnabled) {
+            mSmartDialList.setVisibility(View.VISIBLE);
+            mSmartDialCache = SmartDialCache.getInstance(getActivity(),
+                    mContactsPrefs.getDisplayOrder());
+            // Don't force recache if this is the first time onResume is being called, since
+            // caching should already happen in setUserVisibleHint.
+            if (!mFirstLaunch) {
+                // This forced recache covers the case where the dialer was previously running, and
+                // was brought back into the foreground. If the dialpad fragment hasn't actually
+                // become visible throughout the entire activity's lifecycle, it is possible that
+                // caching hasn't happened yet. In this case, we can force a recache anyway, since
+                // we are not worried about startup performance anymore.
+                mSmartDialCache.cacheIfNeeded(true);
+            }
+        } else {
+            mSmartDialList.setVisibility(View.GONE);
+            mSmartDialCache = null;
+        }
+    }
+
     private class OnSmartDialLongClick implements AdapterView.OnItemLongClickListener {
         @Override
         public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {