People: Action bar tab refactoring

- Now ActionBarAdapter manages the action bar tabs.
- Now ActionBarAdapter.setCurrentTab() should always be used to select
  a tab programmatically, rather than directly calling
  ActionBar.setSelectedNavigationItem().

- Do not re-create/re-initialize ActionBarAdapter/ActionBar for new
  intents.

- Simplify fragment visibility update logic in PeopleActivity.

- Do not clear ActionBarAdapter.Listener in PeopleActivity.onPause;
  do this only in onDestroy.
  Activity is paused when we're processing onNewIntent(), but we still want to
  get callbacks during this.

Change-Id: I93ec35e569e1854923503734693b6404cff92f50
diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index 1414f80..020d135 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -21,6 +21,7 @@
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
+import android.app.FragmentTransaction;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -117,4 +118,12 @@
         }
         return result;
     }
+
+    protected static void showFragment(FragmentTransaction ft, Fragment f) {
+        if ((f != null) && f.isHidden()) ft.show(f);
+    }
+
+    protected static void hideFragment(FragmentTransaction ft, Fragment f) {
+        if ((f != null) && !f.isHidden()) ft.hide(f);
+    }
 }
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index 3a183d2..dc37d3e 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -22,7 +22,10 @@
 
 import android.app.ActionBar;
 import android.app.ActionBar.LayoutParams;
+import android.app.ActionBar.Tab;
+import android.app.FragmentTransaction;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
@@ -30,6 +33,7 @@
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
 import android.widget.SearchView.OnQueryTextListener;
+import android.widget.TabHost.OnTabChangeListener;
 
 /**
  * Adapter for the action bar at the top of the Contacts activity.
@@ -42,6 +46,12 @@
         }
 
         void onAction(Action action);
+
+        /**
+         * Called when the user selects a tab.  The new tab can be obtained using
+         * {@link #getCurrentTab}.
+         */
+        void onSelectedTabChanged();
     }
 
     private static final String EXTRA_KEY_SEARCH_MODE = "navBar.searchMode";
@@ -59,27 +69,33 @@
 
     private Listener mListener;
 
-    private ActionBar mActionBar;
+    private final ActionBar mActionBar;
+    private final MyTabListener mTabListener = new MyTabListener();
 
+    public enum TabState {
+        FAVORITES, ALL, GROUPS;
 
-    public ActionBarAdapter(Context context, Listener listener) {
-        mContext = context;
-        mListener = listener;
-        mSearchLabelText = mContext.getString(R.string.search_label);
-        mAlwaysShowSearchView = mContext.getResources().getBoolean(R.bool.always_show_search_view);
+        public static TabState fromInt(int value) {
+            switch (value) {
+                case 0:
+                    return FAVORITES;
+                case 1:
+                    return ALL;
+                case 2:
+                    return GROUPS;
+            }
+            throw new IllegalArgumentException("Invalid value: " + value);
+        }
     }
 
-    public void onCreate(Bundle savedState, ContactsRequest request, ActionBar actionBar) {
-        mActionBar = actionBar;
-        mQueryString = null;
+    private TabState mCurrentTab = TabState.FAVORITES;
 
-        if (savedState != null) {
-            mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
-            mQueryString = savedState.getString(EXTRA_KEY_QUERY);
-        } else {
-            mSearchMode = request.isSearchMode();
-            mQueryString = request.getQueryString();
-        }
+    public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar) {
+        mContext = context;
+        mListener = listener;
+        mActionBar = actionBar;
+        mSearchLabelText = mContext.getString(R.string.search_label);
+        mAlwaysShowSearchView = mContext.getResources().getBoolean(R.bool.always_show_search_view);
 
         // Set up search view.
         View customSearchView = LayoutInflater.from(mContext).inflate(R.layout.custom_action_bar,
@@ -97,6 +113,30 @@
         mSearchView.setQuery(mQueryString, false);
         mActionBar.setCustomView(customSearchView, layoutParams);
 
+        mActionBar.setDisplayShowTitleEnabled(true);
+
+        // TODO Just use a boolean resource instead of styles.
+        TypedArray array = mContext.obtainStyledAttributes(null, R.styleable.ActionBarHomeIcon);
+        boolean showHomeIcon = array.getBoolean(R.styleable.ActionBarHomeIcon_show_home_icon, true);
+        array.recycle();
+        mActionBar.setDisplayShowHomeEnabled(showHomeIcon);
+
+        addTab(TabState.FAVORITES, mContext.getString(R.string.contactsFavoritesLabel));
+        addTab(TabState.ALL, mContext.getString(R.string.contactsAllLabel));
+        addTab(TabState.GROUPS, mContext.getString(R.string.contactsGroupsLabel));
+    }
+
+    public void initialize(Bundle savedState, ContactsRequest request) {
+        if (savedState == null) {
+            mSearchMode = request.isSearchMode();
+            mQueryString = request.getQueryString();
+        } else {
+            mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
+            mQueryString = savedState.getString(EXTRA_KEY_QUERY);
+
+            // Just set to the field here.  The listener will be notified by update().
+            mCurrentTab = TabState.fromInt(savedState.getInt(EXTRA_KEY_SELECTED_TAB));
+        }
         update();
     }
 
@@ -104,6 +144,55 @@
         mListener = listener;
     }
 
+    private void addTab(TabState tabState, String text) {
+        final Tab tab = mActionBar.newTab();
+        tab.setTag(tabState);
+        tab.setText(text);
+        tab.setTabListener(mTabListener);
+        mActionBar.addTab(tab);
+    }
+
+    private class MyTabListener implements ActionBar.TabListener {
+        /**
+         * If true, it won't call {@link #setCurrentTab} in {@link #onTabSelected}.
+         * This flag is used when we want to programmatically update the current tab without
+         * {@link #onTabSelected} getting called.
+         */
+        public boolean mIgnoreTabSelected;
+
+        @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { }
+        @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { }
+
+        @Override public void onTabSelected(Tab tab, FragmentTransaction ft) {
+            if (!mIgnoreTabSelected) {
+                setCurrentTab((TabState)tab.getTag());
+            }
+        }
+    }
+
+    /**
+     * Change the current tab, and notify the listener.
+     */
+    public void setCurrentTab(TabState tab) {
+        if (tab == null) throw new NullPointerException();
+        if (tab == mCurrentTab) {
+            return;
+        }
+        mCurrentTab = tab;
+
+        int index = mCurrentTab.ordinal();
+        if ((mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS)
+                && (index != mActionBar.getSelectedNavigationIndex())) {
+            mActionBar.setSelectedNavigationItem(index);
+        }
+
+        if (mListener != null) mListener.onSelectedTabChanged();
+    }
+
+    public TabState getCurrentTab() {
+        return mCurrentTab;
+    }
+
     public boolean isSearchMode() {
         return mSearchMode;
     }
@@ -134,7 +223,7 @@
         }
     }
 
-    public void update() {
+    private void update() {
         if (mSearchMode) {
             mActionBar.setDisplayShowCustomEnabled(true);
             if (mAlwaysShowSearchView) {
@@ -144,16 +233,32 @@
                 // Phone -- search view gets focus
                 setFocusOnSearchView();
             }
-            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_STANDARD) {
+                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            }
             if (mListener != null) {
                 mListener.onAction(Action.START_SEARCH_MODE);
             }
         } else {
             mActionBar.setDisplayShowCustomEnabled(mAlwaysShowSearchView);
-            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+            if (mActionBar.getNavigationMode() != ActionBar.NAVIGATION_MODE_TABS) {
+                // setNavigationMode will trigger onTabSelected() with the tab which was previously
+                // selected.
+                // The issue is that when we're first switching to the tab navigation mode after
+                // screen orientation changes, onTabSelected() will get called with the first tab
+                // (i.e. favorite), which would results in mCurrentTab getting set to FAVORITES and
+                // we'd lose restored tab.
+                // So let's just disable the callback here temporarily.  We'll notify the listener
+                // after this anyway.
+                mTabListener.mIgnoreTabSelected = true;
+                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+                mActionBar.setSelectedNavigationItem(mCurrentTab.ordinal());
+                mTabListener.mIgnoreTabSelected = false;
+            }
             mActionBar.setTitle(null);
             if (mListener != null) {
                 mListener.onAction(Action.STOP_SEARCH_MODE);
+                mListener.onSelectedTabChanged();
             }
         }
     }
@@ -192,16 +297,7 @@
     public void onSaveInstanceState(Bundle outState) {
         outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
         outState.putString(EXTRA_KEY_QUERY, mQueryString);
-        outState.putInt(EXTRA_KEY_SELECTED_TAB, mActionBar.getSelectedNavigationIndex());
-    }
-
-    public void onRestoreInstanceState(Bundle savedState) {
-        mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
-        mQueryString = savedState.getString(EXTRA_KEY_QUERY);
-        int selectedTab = savedState.getInt(EXTRA_KEY_SELECTED_TAB);
-        if (selectedTab >= 0) {
-            mActionBar.setSelectedNavigationItem(selectedTab);
-        }
+        outState.putInt(EXTRA_KEY_SELECTED_TAB, mCurrentTab.ordinal());
     }
 
     private void setFocusOnSearchView() {
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 2445a1f..5c610ef 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -20,6 +20,7 @@
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
+import com.android.contacts.activities.ActionBarAdapter.TabState;
 import com.android.contacts.detail.ContactDetailFragment;
 import com.android.contacts.detail.ContactDetailLayoutController;
 import com.android.contacts.detail.ContactDetailTabCarousel;
@@ -60,8 +61,6 @@
 
 import android.accounts.Account;
 import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -69,7 +68,6 @@
 import android.content.ActivityNotFoundException;
 import android.content.ContentValues;
 import android.content.Intent;
-import android.content.res.TypedArray;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -167,35 +165,6 @@
 
     private final Handler mHandler = new Handler();
 
-    /**
-     * TODO: Use ViewPager so that tabs can be swiped left and right. Figure out how to use the
-     * support library in our app.
-     */
-    private final TabListener mTabListener = new TabListener() {
-        @Override
-        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-            hideFragmentOnTabUnselect((TabState) tab.getTag(), ft);
-        }
-
-        @Override
-        public void onTabSelected(Tab tab, FragmentTransaction ft) {
-            final TabState tabState = (TabState) tab.getTag();
-            setSelectedTab(tabState);
-            showFragmentOnTabSelect(tabState, ft);
-            invalidateOptionsMenu();
-        }
-
-        @Override
-        public void onTabReselected(Tab tab, FragmentTransaction ft) {
-        }
-    };
-
-    private enum TabState {
-        FAVORITES, ALL, GROUPS
-    }
-
-    private TabState mSelectedTab;
-
     public PeopleActivity() {
         mIntentResolver = new ContactsIntentResolver(this);
         mContactListFilterController = new ContactListFilterController(this);
@@ -330,9 +299,11 @@
         }
 
         setTitle(mRequest.getActivityTitle());
-        ActionBar actionBar = getActionBar();
-        mActionBarAdapter = new ActionBarAdapter(this, this);
-        mActionBarAdapter.onCreate(savedState, mRequest, getActionBar());
+        if (createContentView) {
+            mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar());
+        }
+        mActionBarAdapter.initialize(savedState, mRequest);
+
 
         ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
         ContactDetailTabCarousel tabCarousel = (ContactDetailTabCarousel)
@@ -342,120 +313,15 @@
                 mContactDetailFragmentListener);
 
         if (createContentView) {
-            actionBar.removeAllTabs();
-            Tab favoritesTab = actionBar.newTab();
-            favoritesTab.setTag(TabState.FAVORITES);
-            favoritesTab.setText(getString(R.string.contactsFavoritesLabel));
-            favoritesTab.setTabListener(mTabListener);
-            actionBar.addTab(favoritesTab);
-
-            Tab allTab = actionBar.newTab();
-            allTab.setTag(TabState.ALL);
-            allTab.setText(getString(R.string.contactsAllLabel));
-            allTab.setTabListener(mTabListener);
-            actionBar.addTab(allTab);
-
-            Tab groupsTab = actionBar.newTab();
-            groupsTab.setTag(TabState.GROUPS);
-            groupsTab.setText(getString(R.string.contactsGroupsLabel));
-            groupsTab.setTabListener(mTabListener);
-            actionBar.addTab(groupsTab);
-            actionBar.setDisplayShowTitleEnabled(true);
-
-            TypedArray a = obtainStyledAttributes(null, R.styleable.ActionBarHomeIcon);
-            boolean showHomeIcon = a.getBoolean(R.styleable.ActionBarHomeIcon_show_home_icon, true);
-            actionBar.setDisplayShowHomeEnabled(showHomeIcon);
-
+            // TODO Is the createContentView test really necessary?
             invalidateOptionsMenuIfNeeded();
         }
 
         configureFragments(savedState == null);
     }
 
-    private void hideFragmentOnTabUnselect(TabState newTabState, FragmentTransaction ft) {
-        switch (newTabState) {
-            case FAVORITES: {
-                ft.hide(mFavoritesFragment);
-                if (mFrequentFragment != null) {
-                    ft.hide(mFrequentFragment);
-                }
-                break;
-            }
-            case ALL: {
-                ft.hide(mAllFragment);
-                if (mContactDetailFragment != null) {
-                    ft.hide(mContactDetailFragment);
-                }
-                break;
-            }
-            case GROUPS: {
-                ft.hide(mGroupsFragment);
-                if (mGroupDetailFragment != null) {
-                    ft.hide(mGroupDetailFragment);
-                }
-                break;
-            }
-            default: {
-                throw new IllegalStateException("Unexpected tab state: " + newTabState);
-            }
-        }
-    }
-
-    private void showFragmentOnTabSelect(TabState newTabState, FragmentTransaction ft) {
-        switch (newTabState) {
-            case FAVORITES: {
-                ft.show(mFavoritesFragment);
-                if (mFrequentFragment != null) {
-                    ft.show(mFrequentFragment);
-                }
-                break;
-            }
-            case ALL: {
-                ft.show(mAllFragment);
-                if (mContactDetailFragment != null) {
-                    ft.show(mContactDetailFragment);
-                }
-                break;
-            }
-            case GROUPS: {
-                ft.show(mGroupsFragment);
-                if (mGroupDetailFragment != null) {
-                    ft.show(mGroupDetailFragment);
-                }
-                break;
-            }
-            default: {
-                throw new IllegalStateException("Unexpected tab state: " + newTabState);
-            }
-        }
-    }
-
-    private void setSelectedTab(TabState tab) {
-        mSelectedTab = tab;
-
-        if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
-            switch (mSelectedTab) {
-                case FAVORITES:
-                    mFavoritesView.setVisibility(View.VISIBLE);
-                    mBrowserView.setVisibility(View.GONE);
-                    mDetailsView.setVisibility(View.GONE);
-                    break;
-                case GROUPS:
-                case ALL:
-                    mFavoritesView.setVisibility(View.GONE);
-                    mBrowserView.setVisibility(View.VISIBLE);
-                    mDetailsView.setVisibility(View.VISIBLE);
-                    break;
-            }
-        }
-    }
-
     @Override
     protected void onPause() {
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.setListener(null);
-        }
-
         mOptionsMenuContactsAvailable = false;
 
         mProviderStatus = -1;
@@ -466,11 +332,12 @@
     @Override
     protected void onResume() {
         super.onResume();
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.setListener(this);
-        }
         mProviderStatusLoader.setProviderStatusListener(this);
         updateFragmentVisibility();
+
+        // Re-register the listener, which may have been cleared when onSaveInstanceState was
+        // called.  See also: onSaveInstanceState
+        mActionBarAdapter.setListener(this);
     }
 
     @Override
@@ -479,6 +346,12 @@
         super.onStart();
     }
 
+    @Override
+    protected void onDestroy() {
+        mActionBarAdapter.setListener(null);
+        super.onDestroy();
+    }
+
     private void configureFragments(boolean fromRequest) {
         if (fromRequest) {
             ContactListFilter filter = null;
@@ -503,7 +376,7 @@
                     break;
                 case ContactsRequest.ACTION_VIEW_CONTACT:
                     if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
-                        getActionBar().setSelectedNavigationItem(TabState.ALL.ordinal());
+                        mActionBarAdapter.setCurrentTab(TabState.ALL);
                     }
             }
 
@@ -562,33 +435,12 @@
     public void onAction(Action action) {
         switch (action) {
             case START_SEARCH_MODE:
-                // Checking if multi fragments are being displayed
-                if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
-                    mFavoritesView.setVisibility(View.GONE);
-                    mBrowserView.setVisibility(View.VISIBLE);
-                    mDetailsView.setVisibility(View.VISIBLE);
-                }
-                // Bring the contact list fragment (and detail fragment if applicable) to the front
-                FragmentTransaction ft = getFragmentManager().beginTransaction();
-                ft.show(mAllFragment);
-                if (mContactDetailFragment != null) ft.show(mContactDetailFragment);
-                ft.commit();
                 clearSearch();
+                updateFragmentsVisibility();
                 break;
             case STOP_SEARCH_MODE:
-                // Refresh the fragments because search mode was using them to display search
-                // results.
                 clearSearch();
-
-                // If the last selected tab was not the "All contacts" tab, then hide these
-                // fragments because we need to show favorites or groups.
-                if (mSelectedTab != null && !mSelectedTab.equals(TabState.ALL)) {
-                    FragmentTransaction transaction = getFragmentManager().beginTransaction();
-                    transaction.hide(mAllFragment);
-                    if (mContactDetailFragment != null) transaction.hide(mContactDetailFragment);
-                    transaction.commit();
-                }
-                if (mSelectedTab != null) setSelectedTab(mSelectedTab);
+                updateFragmentsVisibility();
                 break;
             case CHANGE_SEARCH_QUERY:
                 loadSearch(mActionBarAdapter.getQueryString());
@@ -598,6 +450,72 @@
         }
     }
 
+    @Override
+    public void onSelectedTabChanged() {
+        updateFragmentsVisibility();
+    }
+
+    /**
+     * Updates the fragment/view visibility according to the current mode, such as
+     * {@link ActionBarAdapter#isSearchMode()} and {@link ActionBarAdapter#getCurrentTab()}.
+     */
+    private void updateFragmentsVisibility() {
+        TabState tab = mActionBarAdapter.getCurrentTab();
+
+        // If in search mode, we use the all list + contact details to show the result.
+        if (mActionBarAdapter.isSearchMode()) {
+            tab = TabState.ALL;
+        }
+        if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
+            switch (tab) {
+                case FAVORITES:
+                    mFavoritesView.setVisibility(View.VISIBLE);
+                    mBrowserView.setVisibility(View.GONE);
+                    mDetailsView.setVisibility(View.GONE);
+                    break;
+                case GROUPS:
+                case ALL:
+                    mFavoritesView.setVisibility(View.GONE);
+                    mBrowserView.setVisibility(View.VISIBLE);
+                    mDetailsView.setVisibility(View.VISIBLE);
+                    break;
+            }
+        }
+        FragmentManager fragmentManager = getFragmentManager();
+        FragmentTransaction ft = fragmentManager.beginTransaction();
+
+        switch (tab) {
+            case FAVORITES:
+                showFragment(ft, mFavoritesFragment);
+                showFragment(ft, mFrequentFragment);
+                hideFragment(ft, mAllFragment);
+                hideFragment(ft, mContactDetailFragment);
+                hideFragment(ft, mGroupsFragment);
+                hideFragment(ft, mGroupDetailFragment);
+                break;
+            case ALL:
+                hideFragment(ft, mFavoritesFragment);
+                hideFragment(ft, mFrequentFragment);
+                showFragment(ft, mAllFragment);
+                showFragment(ft, mContactDetailFragment);
+                hideFragment(ft, mGroupsFragment);
+                hideFragment(ft, mGroupDetailFragment);
+                break;
+            case GROUPS:
+                hideFragment(ft, mFavoritesFragment);
+                hideFragment(ft, mFrequentFragment);
+                hideFragment(ft, mAllFragment);
+                hideFragment(ft, mContactDetailFragment);
+                showFragment(ft, mGroupsFragment);
+                showFragment(ft, mGroupDetailFragment);
+                break;
+        }
+        if (!ft.isEmpty()) {
+            ft.commit();
+            fragmentManager.executePendingTransactions();
+        }
+    }
+
     private void clearSearch() {
         loadSearch("");
     }
@@ -1034,7 +952,7 @@
                 searchMenu.setVisible(false); // Don't show the search menu in search mode.
             }
         } else {
-            switch (mSelectedTab) {
+            switch (mActionBarAdapter.getCurrentTab()) {
                 case FAVORITES:
                     // TODO: Fall through until we determine what the menu items should be for
                     // this tab
@@ -1283,21 +1201,21 @@
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putBoolean(KEY_SEARCH_MODE, mSearchMode);
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.onSaveInstanceState(outState);
-        }
+        mActionBarAdapter.onSaveInstanceState(outState);
         if (mContactDetailLayoutController != null) {
             mContactDetailLayoutController.onSaveInstanceState(outState);
         }
+
+        // Clear the listener to make sure we don't get callbacks after onSaveInstanceState,
+        // in order to avoid doing fragment transactions after it.
+        // TODO Figure out a better way to deal with the issue.
+        mActionBarAdapter.setListener(null);
     }
 
     @Override
     protected void onRestoreInstanceState(Bundle inState) {
         super.onRestoreInstanceState(inState);
         mSearchMode = inState.getBoolean(KEY_SEARCH_MODE);
-        if (mActionBarAdapter != null) {
-            mActionBarAdapter.onRestoreInstanceState(inState);
-        }
         if (mContactDetailLayoutController != null) {
             mContactDetailLayoutController.onRestoreInstanceState(inState);
         }