Show DialpadChooser correctly.

We need to make DialpadFragment to handle a new Intent
via onNewIntent(). The code was once removed in
I3b2f95b0d34e89bb9665b2014048a634d29e54ce because of possible
NPE. This time we avoid it by just using "if" clause.

Set DialpadChooserAdapter anytime when it is required. Now
Fragment can be reused with onCreateView() (when users' swipe
action), at which the adapter can be available though
the chooser view is recreated.

Modify DialpadFragment#resolveIntent() so that it is
easier to understand. Rename it to configureScreenFromIntent(),
since it is only about its screen state now.

Remove some logic around dial uri handling. Now DialpadFragment
gets the uri directly from Intent instead of parent Activity, so
there's no need to keep it inside DialtactsActivity.

TESTED:
- Launch "Phone" with no calls active
- Make a call, press the "Add call" button from the in-call UI
- Make a call, bail out of the in-call UI without ending the
  call, launch "Phone" from the home screen. Play with swipe,
  exiting dialpad chooser screen several times
- Launch "Phone" from the other app with a phone number Uri

Bug: 5087992
Bug: 4983278

Change-Id: I5fd687daccf15f632219925a4846019594beec0a
diff --git a/src/com/android/contacts/activities/DialpadActivity.java b/src/com/android/contacts/activities/DialpadActivity.java
index cfe17f3..1221068 100644
--- a/src/com/android/contacts/activities/DialpadActivity.java
+++ b/src/com/android/contacts/activities/DialpadActivity.java
@@ -64,7 +64,7 @@
     @Override
     protected void onNewIntent(Intent newIntent) {
         setIntent(newIntent);
-        mFragment.resolveIntent(newIntent);
+        mFragment.configureScreenFromIntent(newIntent);
     }
 
     public DialpadFragment getFragment() {
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 01212f5..2040f8d 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -481,12 +481,18 @@
         final String action = newIntent.getAction();
         if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
             setupFilterText(newIntent);
-        } else if (isDialIntent(newIntent)) {
-            setupDialUri(newIntent);
         }
         if (mInSearchUi || mSearchFragment.isVisible()) {
             exitSearchUi();
         }
+
+        if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) {
+            if (mDialpadFragment != null) {
+                mDialpadFragment.configureScreenFromIntent(newIntent);
+            } else {
+                Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
+            }
+        }
     }
 
     /** Returns true if the given intent contains a phone number to populate the dialer with */
@@ -535,33 +541,6 @@
         }
     }
 
-    /**
-     * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
-     * originally came from a dial intent received by this activity. The stored
-     * uri will then be cleared after after this method returns.
-     *
-     * @return The stored uri
-     */
-    public Uri getAndClearDialUri() {
-        Uri dialUri = mDialUri;
-        mDialUri = null;
-        return dialUri;
-    }
-
-    /**
-     * Stores the uri associated with a dial intent. This is so child activities can
-     * check if they are supposed to display new dial info.
-     *
-     * @param intent The intent received in {@link #onNewIntent(Intent)}
-     */
-    private void setupDialUri(Intent intent) {
-        // If the intent was relaunched from history, don't reapply the intent.
-        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
-            return;
-        }
-        mDialUri = intent.getData();
-    }
-
     @Override
     public void onBackPressed() {
         if (mInSearchUi) {
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index add6b80..a5db5ce 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -143,9 +143,6 @@
     static final String EXTRA_SEND_EMPTY_FLASH
             = "com.android.phone.extra.SEND_EMPTY_FLASH";
 
-    /** Indicates if we are opening this dialer to add a call from the InCallScreen. */
-    private boolean mIsAddCallMode;
-
     private String mCurrentCountryIso;
 
     /**
@@ -313,7 +310,7 @@
         mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
         mDialpadChooser.setOnItemClickListener(this);
 
-        resolveIntent(getActivity().getIntent());
+        configureScreenFromIntent(getActivity().getIntent());
 
         return fragmentView;
     }
@@ -323,38 +320,18 @@
     }
 
     /**
-     * Handles the intent that launched us.
-     *
-     * We can be launched either with ACTION_DIAL or ACTION_VIEW (which
-     * may include a phone number to pre-load), or ACTION_MAIN (which just
-     * brings up a blank dialpad).
-     *
-     * @return true IFF the current intent has the DialtactsActivity.EXTRA_IGNORE_STATE
-     *    extra set to true, which indicates (to our container) that we should ignore
-     *    any possible saved state, and instead reset our state based on the parent's
-     *    intent.
+     * @return true when {@link #mDigits} is actually filled by the Intent.
      */
-    public boolean resolveIntent(Intent intent) {
-        boolean ignoreState = false;
-
-        // by default we are not adding a call.
-        mIsAddCallMode = false;
-
-        // By default we don't show the "dialpad chooser" UI.
-        boolean needToShowDialpadChooser = false;
-
-        // Resolve the intent
+    private boolean fillDigitsIfNecessary(Intent intent) {
         final String action = intent.getAction();
         if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
-            // see if we are "adding a call" from the InCallScreen; false by default.
-            mIsAddCallMode = intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
-
             Uri uri = intent.getData();
             if (uri != null) {
                 if ("tel".equals(uri.getScheme())) {
                     // Put the requested number into the input area
                     String data = uri.getSchemeSpecificPart();
                     setFormattedDigits(data, null);
+                    return true;
                 } else {
                     String type = intent.getType();
                     if (People.CONTENT_ITEM_TYPE.equals(type)
@@ -364,22 +341,42 @@
                                 new String[] {PhonesColumns.NUMBER, PhonesColumns.NUMBER_KEY},
                                 null, null, null);
                         if (c != null) {
-                            if (c.moveToFirst()) {
-                                // Put the number into the input area
-                                setFormattedDigits(c.getString(0), c.getString(1));
+                            try {
+                                if (c.moveToFirst()) {
+                                    // Put the number into the input area
+                                    setFormattedDigits(c.getString(0), c.getString(1));
+                                    return true;
+                                }
+                            } finally {
+                                c.close();
                             }
-                            c.close();
                         }
                     }
                 }
-            } else {
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @see #showDialpadChooser(boolean)
+     */
+    private static boolean needToShowDialpadChooser(Intent intent, boolean isAddCallMode) {
+        final String action = intent.getAction();
+
+        boolean needToShowDialpadChooser = false;
+
+        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
+            Uri uri = intent.getData();
+            if (uri == null) {
                 // ACTION_DIAL or ACTION_VIEW with no data.
                 // This behaves basically like ACTION_MAIN: If there's
                 // already an active call, bring up an intermediate UI to
                 // make the user confirm what they really want to do.
                 // Be sure *not* to show the dialpad chooser if this is an
                 // explicit "Add call" action, though.
-                if (!mIsAddCallMode && phoneIsInUse()) {
+                if (!isAddCallMode && phoneIsInUse()) {
                     needToShowDialpadChooser = true;
                 }
             }
@@ -399,11 +396,34 @@
             }
         }
 
-        // Bring up the "dialpad chooser" IFF we need to make the user
-        // confirm which dialpad they really want.
-        showDialpadChooser(needToShowDialpadChooser);
+        return needToShowDialpadChooser;
+    }
 
-        return ignoreState;
+    private static boolean isAddCallMode(Intent intent) {
+        final String action = intent.getAction();
+        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
+            // see if we are "adding a call" from the InCallScreen; false by default.
+            return intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Checks the given Intent and changes dialpad's UI state. For example, if the Intent requires
+     * the screen to enter "Add Call" mode, this method will show correct UI for the mode.
+     */
+    public void configureScreenFromIntent(Intent intent) {
+        boolean needToShowDialpadChooser = false;
+
+        final boolean isAddCallMode = isAddCallMode(intent);
+        if (!isAddCallMode) {
+            final boolean digitsFilled = fillDigitsIfNecessary(intent);
+            if (!digitsFilled) {
+                needToShowDialpadChooser = needToShowDialpadChooser(intent, isAddCallMode);
+            }
+        }
+        showDialpadChooser(needToShowDialpadChooser);
     }
 
     private void setFormattedDigits(String data, String normalizedNumber) {
@@ -476,13 +496,10 @@
         }
 
         Activity parent = getActivity();
-        // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
-        // digits in the dialer field.
         if (parent instanceof DialtactsActivity) {
-            Uri dialUri = ((DialtactsActivity) parent).getAndClearDialUri();
-            if (dialUri != null) {
-                resolveIntent(parent.getIntent());
-            }
+            // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
+            // digits in the dialer field.
+            fillDigitsIfNecessary(parent.getIntent());
         }
 
         // While we're in the foreground, listen for phone state changes,
@@ -904,8 +921,8 @@
             // ListView.  We do this only once.
             if (mDialpadChooserAdapter == null) {
                 mDialpadChooserAdapter = new DialpadChooserAdapter(getActivity());
-                mDialpadChooser.setAdapter(mDialpadChooserAdapter);
             }
+            mDialpadChooser.setAdapter(mDialpadChooserAdapter);
         } else {
             // Log.i(TAG, "Displaying normal Dialer UI.");
             mDigits.setVisibility(View.VISIBLE);