Add ActionBarController

* Collect all actionBar interactions within DialtactsActivity into
a single controller to ensure that it behaves more deterministically,
and fix some bugs with regards to actionBar interactions.

* Make sure that action bar correctly handles activity recreation
and destruction by saving its state

* Add unit tests and mock classes for ActionBarController

Bug: 14900155

Change-Id: I370831db425e1970b118f5d4fed3ce9297e3610d
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 8445ff7..d8a02ac 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -20,7 +20,6 @@
 import android.app.ActionBar;
 import android.app.Activity;
 import android.app.Fragment;
-import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
@@ -85,6 +84,7 @@
 import com.android.dialer.list.RemoveView;
 import com.android.dialer.list.SearchFragment;
 import com.android.dialer.list.SmartDialSearchFragment;
+import com.android.dialer.widget.ActionBarController;
 import com.android.dialer.widget.SearchEditTextLayout;
 import com.android.dialer.widget.SearchEditTextLayout.OnBackButtonClickedListener;
 import com.android.dialerbind.DatabaseHelperManager;
@@ -102,10 +102,12 @@
         DialpadFragment.HostInterface,
         ListsFragment.HostInterface,
         SpeedDialFragment.HostInterface,
+        SearchFragment.HostInterface,
         OnDragDropListener,
         OnPhoneNumberPickerActionListener,
         PopupMenu.OnMenuItemClickListener,
-        ViewPager.OnPageChangeListener {
+        ViewPager.OnPageChangeListener,
+        ActionBarController.ActivityUi {
     private static final String TAG = "DialtactsActivity";
 
     public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -208,6 +210,7 @@
 
     private DialerDatabaseHelper mDialerDatabaseHelper;
     private DragDropController mDragDropController;
+    private ActionBarController mActionBarController;
 
     private class OptionsPopupMenu extends PopupMenu {
         public OptionsPopupMenu(Context context, View anchor) {
@@ -293,6 +296,7 @@
         @Override
         public void onClick(View v) {
             if (!isInSearchUi()) {
+                mActionBarController.onSearchBoxTapped();
                 enterSearchUi(false /* smartDialSearch */, mSearchView.getText().toString());
             }
         }
@@ -325,6 +329,9 @@
         actionBar.setDisplayShowCustomEnabled(true);
         actionBar.setBackgroundDrawable(null);
 
+        mActionBarController = new ActionBarController(this,
+                (SearchEditTextLayout) actionBar.getCustomView());
+
         mSearchEditTextLayout = (SearchEditTextLayout) actionBar.getCustomView();
         mSearchEditTextLayout.setPreImeKeyListener(mSearchEditTextLayoutListener);
 
@@ -363,6 +370,7 @@
             mInRegularSearch = savedInstanceState.getBoolean(KEY_IN_REGULAR_SEARCH_UI);
             mInDialpadSearch = savedInstanceState.getBoolean(KEY_IN_DIALPAD_SEARCH_UI);
             mFirstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
+            mActionBarController.restoreInstanceState(savedInstanceState);
         }
 
         parentLayout = (RelativeLayout) findViewById(R.id.dialtacts_mainlayout);
@@ -426,6 +434,7 @@
         outState.putBoolean(KEY_IN_REGULAR_SEARCH_UI, mInRegularSearch);
         outState.putBoolean(KEY_IN_DIALPAD_SEARCH_UI, mInDialpadSearch);
         outState.putBoolean(KEY_FIRST_LAUNCH, mFirstLaunch);
+        mActionBarController.saveInstanceState(outState);
     }
 
     @Override
@@ -563,6 +572,8 @@
         ft.show(mDialpadFragment);
         ft.commit();
 
+        mActionBarController.onDialpadUp();
+
         if (!isInSearchUi()) {
             enterSearchUi(true /* isSmartDial */, mSearchQuery);
         }
@@ -581,7 +592,6 @@
         }
 
         updateSearchFragmentPosition();
-        getActionBar().hide();
     }
 
     /**
@@ -617,7 +627,7 @@
             commitDialpadFragmentHide();
         }
 
-        mListsFragment.maybeShowActionBar();
+        mActionBarController.onDialpadDown();
 
         if (isInSearchUi()) {
             if (TextUtils.isEmpty(mSearchQuery)) {
@@ -649,10 +659,21 @@
         }
     }
 
-    private boolean isInSearchUi() {
+    @Override
+    public boolean isInSearchUi() {
         return mInDialpadSearch || mInRegularSearch;
     }
 
+    @Override
+    public boolean hasSearchQuery() {
+        return !TextUtils.isEmpty(mSearchQuery);
+    }
+
+    @Override
+    public boolean shouldShowActionBar() {
+        return mListsFragment.shouldShowActionBar();
+    }
+
     private void setNotInSearchUi() {
         mInDialpadSearch = false;
         mInRegularSearch = false;
@@ -829,7 +850,6 @@
         transaction.commit();
 
         mListsFragment.getView().animate().alpha(0).withLayer();
-        mSearchEditTextLayout.animateExpandOrCollapse(true);
     }
 
     /**
@@ -856,7 +876,7 @@
         transaction.commit();
 
         mListsFragment.getView().animate().alpha(1).withLayer();
-        mSearchEditTextLayout.animateExpandOrCollapse(false);
+        mActionBarController.onSearchUiExited();
     }
 
     /** Returns an Intent to launch Call Settings screen */
@@ -974,7 +994,7 @@
      */
     @Override
     public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
-        getActionBar().hide();
+        mActionBarController.slideActionBarUp(true);
         mRemoveViewContainer.setVisibility(View.VISIBLE);
     }
 
@@ -987,7 +1007,7 @@
      */
     @Override
     public void onDragFinished(int x, int y) {
-        getActionBar().show();
+        mActionBarController.slideActionBarDown(true);
         mRemoveViewContainer.setVisibility(View.GONE);
     }
 
@@ -1031,10 +1051,6 @@
         exitSearchUi();
     }
 
-    public int getActionBarHeight() {
-        return mActionBarHeight;
-    }
-
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 
@@ -1107,4 +1123,24 @@
         public void onAnimationRepeat(Animation animation) {
         }
     }
+
+    @Override
+    public boolean isActionBarShowing() {
+        return mActionBarController.isActionBarShowing();
+    }
+
+    @Override
+    public int getActionBarHideOffset() {
+        return getActionBar().getHideOffset();
+    }
+
+    @Override
+    public int getActionBarHeight() {
+        return mActionBarHeight;
+    }
+
+    @Override
+    public void setActionBarHideOffset(int hideOffset) {
+        getActionBar().setHideOffset(hideOffset);
+    }
 }