ContactListActivity is no longer a ListActivity

Change-Id: Iffc1abb88829598e060cc004795b111583a8abab
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 8303414..16f41b1 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -123,7 +123,7 @@
  * Displays a list of contacts. Usually is embedded into the ContactsActivity.
  */
 @SuppressWarnings("deprecation")
-public class ContactsListActivity extends ListActivity implements View.OnCreateContextMenuListener,
+public class ContactsListActivity extends Activity implements View.OnCreateContextMenuListener,
         View.OnClickListener, View.OnKeyListener, TextWatcher, TextView.OnEditorActionListener,
         OnFocusChangeListener, OnTouchListener, OnScrollListener, ContactsApplicationController {
 
@@ -501,6 +501,8 @@
     private ContactsIntentResolver mIntentResolver;
     protected ContactEntryListConfiguration mConfig;
 
+    private ListView mListView;
+
     public ContactsListActivity() {
         mIntentResolver = new ContactsIntentResolver(this, this);
     }
@@ -568,24 +570,15 @@
     }
 
     public void initContentView() {
-        if (mSearchMode) {
-            setContentView(R.layout.contacts_search_content);
-        } else if (mSearchResultsMode) {
-            setContentView(R.layout.contacts_list_search_results);
-            TextView titleText = (TextView)findViewById(R.id.search_results_for);
-            titleText.setText(Html.fromHtml(getString(R.string.search_results_for,
-                    "<b>" + mInitialFilter + "</b>")));
-        } else {
-            setContentView(R.layout.contacts_list_content);
-        }
+        setContentView(mConfig.createView());
 
-        mConfig.configureListView(getListView());
+        mListView = (ListView) findViewById(android.R.id.list);
 
         if (mSearchMode) {
             setupSearchView();
         }
 
-        View emptyView = mList.getEmptyView();
+        View emptyView = mListView.getEmptyView();
         if (emptyView instanceof ContactListEmptyView) {
             mEmptyView = (ContactListEmptyView)emptyView;
         }
@@ -593,9 +586,7 @@
 
     // TODO move this to the configuration object(s)
     @Deprecated
-    public void setupListView(ListAdapter adapter) {
-        final ListView list = getListView();
-        final LayoutInflater inflater = getLayoutInflater();
+    public void setupListView(ListAdapter adapter, ListView list) {
 
         mHighlightingAnimation =
                 new NameHighlightingAnimation(list, TEXT_HIGHLIGHTING_ANIMATION_DURATION);
@@ -606,7 +597,6 @@
         list.setOnCreateContextMenuListener(this);
 
         mAdapter = (ContactEntryListAdapter)adapter;
-        setListAdapter(mAdapter);
 
         list.setOnScrollListener(this);
         list.setOnKeyListener(this);
@@ -872,8 +862,8 @@
     protected void onSaveInstanceState(Bundle icicle) {
         super.onSaveInstanceState(icicle);
         // Save list state in the bundle so we can restore it after the QueryHandler has run
-        if (mList != null) {
-            icicle.putParcelable(LIST_STATE_KEY, mList.onSaveInstanceState());
+        if (mListView != null) {
+            icicle.putParcelable(LIST_STATE_KEY, mListView.onSaveInstanceState());
         }
     }
 
@@ -1253,7 +1243,7 @@
             return;
         }
 
-        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+        Cursor cursor = (Cursor) mAdapter.getItem(info.position);
         if (cursor == null) {
             // For some reason the requested item isn't available, do nothing
             return;
@@ -1302,7 +1292,7 @@
             return false;
         }
 
-        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+        Cursor cursor = (Cursor) mAdapter.getItem(info.position);
 
         switch (item.getItemId()) {
             case MENU_ITEM_TOGGLE_STAR: {
@@ -1402,7 +1392,7 @@
             return false;
         }
 
-        final int position = getListView().getSelectedItemPosition();
+        final int position = mListView.getSelectedItemPosition();
         if (position != ListView.INVALID_POSITION) {
             Uri contactUri = getContactUri(position);
             if (contactUri != null) {
@@ -1460,7 +1450,7 @@
      * Dismisses the soft keyboard when the list takes focus.
      */
     public void onFocusChange(View view, boolean hasFocus) {
-        if (view == getListView() && hasFocus) {
+        if (view == mListView && hasFocus) {
             hideSoftKeyboard();
         }
     }
@@ -1469,7 +1459,7 @@
      * Dismisses the soft keyboard when the list takes focus.
      */
     public boolean onTouch(View view, MotionEvent event) {
-        if (view == getListView()) {
+        if (view == mListView) {
             hideSoftKeyboard();
         }
         return false;
@@ -1541,7 +1531,7 @@
         // Hide soft keyboard, if visible
         InputMethodManager inputMethodManager = (InputMethodManager)
                 getSystemService(Context.INPUT_METHOD_SERVICE);
-        inputMethodManager.hideSoftInputFromWindow(mList.getWindowToken(), 0);
+        inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
     }
 
     /**
@@ -2236,7 +2226,7 @@
      * @return true if the call was initiated, false otherwise
      */
     boolean callSelection() {
-        ListView list = getListView();
+        ListView list = mListView;
         if (list.hasFocus()) {
             Cursor cursor = (Cursor) list.getSelectedItem();
             return callContact(cursor);
@@ -2362,12 +2352,11 @@
     }
 
     Cursor getItemForView(View view) {
-        ListView listView = getListView();
-        int index = listView.getPositionForView(view);
+        int index = mListView.getPositionForView(view);
         if (index < 0) {
             return null;
         }
-        return (Cursor) listView.getAdapter().getItem(index);
+        return (Cursor) mListView.getAdapter().getItem(index);
     }
 
     protected class QueryHandler extends AsyncQueryHandler {
@@ -2409,7 +2398,7 @@
 
         // Now that the cursor is populated again, it's possible to restore the list state
         if (mListState != null) {
-            mList.onRestoreInstanceState(mListState);
+            mListView.onRestoreInstanceState(mListState);
             mListState = null;
         }
     }
diff --git a/src/com/android/contacts/JoinContactActivity.java b/src/com/android/contacts/JoinContactActivity.java
index 5e737a7..e555523 100644
--- a/src/com/android/contacts/JoinContactActivity.java
+++ b/src/com/android/contacts/JoinContactActivity.java
@@ -32,6 +32,7 @@
 import android.provider.ContactsContract.Contacts.AggregationSuggestions;
 import android.text.TextUtils;
 import android.util.Log;
+import android.widget.ListView;
 import android.widget.TextView;
 
 /**
@@ -86,15 +87,16 @@
 
     @Override
     public void initContentView() {
-        setContentView(R.layout.contacts_list_content_join);
+        setContentView(mConfig.createView());
+
         TextView blurbView = (TextView)findViewById(R.id.join_contact_blurb);
 
         String blurb = getString(R.string.blurbJoinContactDataWith,
                 getContactDisplayName(mTargetContactId));
         blurbView.setText(blurb);
-        mConfig.configureListView(getListView());
 
-        mAdapter = (JoinContactListAdapter)getListView().getAdapter();
+        ListView listView = (ListView)findViewById(android.R.id.list);
+        mAdapter = (JoinContactListAdapter)listView.getAdapter();
         mAdapter.setJoinModeShowAllContacts(true);
     }
 
diff --git a/src/com/android/contacts/MultiplePhonePickerActivity.java b/src/com/android/contacts/MultiplePhonePickerActivity.java
index 6c27c3e..502e8f1 100644
--- a/src/com/android/contacts/MultiplePhonePickerActivity.java
+++ b/src/com/android/contacts/MultiplePhonePickerActivity.java
@@ -45,6 +45,7 @@
 import android.view.animation.AnimationUtils;
 import android.widget.Button;
 import android.widget.CheckBox;
+import android.widget.ListView;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -128,8 +129,8 @@
     @Override
     public void initContentView() {
         super.initContentView();
-        ((MultiplePhonePickerAdapter)getListView().getAdapter())
-                .setExtraAdapter(mPhoneNumberAdapter);
+        ListView listView = (ListView)findViewById(android.R.id.list);
+        ((MultiplePhonePickerAdapter)listView.getAdapter()).setExtraAdapter(mPhoneNumberAdapter);
         ViewStub stub = (ViewStub)findViewById(R.id.footer_stub);
         if (stub != null) {
             View stubView = stub.inflate();
@@ -160,7 +161,8 @@
     @Override
     protected void onSaveInstanceState(Bundle icicle) {
         super.onSaveInstanceState(icicle);
-        if (mList != null) {
+        ListView listView = (ListView)findViewById(android.R.id.list);
+        if (listView != null) {
             if (mUserSelection != null) {
                 mUserSelection.saveInstanceState(icicle);
             }
diff --git a/src/com/android/contacts/list/ContactEntryListConfiguration.java b/src/com/android/contacts/list/ContactEntryListConfiguration.java
index 26eeb72..88cf001 100644
--- a/src/com/android/contacts/list/ContactEntryListConfiguration.java
+++ b/src/com/android/contacts/list/ContactEntryListConfiguration.java
@@ -18,12 +18,15 @@
 
 import com.android.contacts.ContactsApplicationController;
 import com.android.contacts.ContactsListActivity;
+import com.android.contacts.R;
 import com.android.contacts.widget.PinnedHeaderListView;
 
 import android.content.Context;
+import android.text.Html;
 import android.view.View;
 import android.widget.ListAdapter;
 import android.widget.ListView;
+import android.widget.TextView;
 
 /**
  * Common base class for configurations of various contact-related lists, e.g.
@@ -35,6 +38,9 @@
     private final ContactsApplicationController mApplicationController;
     private boolean mSectionHeaderDisplayEnabled;
     private boolean mPhotoLoaderEnabled;
+    private boolean mSearchMode;
+    private boolean mSearchResultsMode;
+    private String mQueryString;
 
     public ContactEntryListConfiguration(Context context,
             ContactsApplicationController applicationController) {
@@ -50,20 +56,48 @@
         return mApplicationController;
     }
 
-    public abstract ListAdapter createListAdapter();
-    public abstract ContactEntryListController createController();
+    protected abstract View inflateView();
+    protected abstract ListAdapter createListAdapter();
+    protected abstract ContactEntryListController createController();
 
-    public void configureListView(ListView listView) {
+    public View createView() {
+        View view = inflateView();
         ListAdapter adapter = createListAdapter();
         ContactEntryListController controller = createController();
+        configureView(view, adapter, controller);
+        return view;
+    }
+
+    protected void configureView(View view, ListAdapter adapter,
+            ContactEntryListController controller) {
+        ListView listView = (ListView)view.findViewById(android.R.id.list);
+        if (listView == null) {
+            throw new RuntimeException(
+                    "Your content must have a ListView whose id attribute is " +
+                    "'android.R.id.list'");
+        }
+
+        View emptyView = view.findViewById(com.android.internal.R.id.empty);
+        if (emptyView != null) {
+            listView.setEmptyView(emptyView);
+        }
+
         controller.setAdapter(adapter);
         listView.setAdapter(adapter);
         listView.setOnItemClickListener(controller);
         controller.setListView(listView);
 
-        ((ContactsListActivity)mContext).setupListView(adapter);
+        ((ContactsListActivity)mContext).setupListView(adapter, listView);
 
         configurePinnedHeader(listView, adapter);
+
+        if (isSearchResultsMode()) {
+            TextView titleText = (TextView)view.findViewById(R.id.search_results_for);
+            if (titleText != null) {
+                titleText.setText(Html.fromHtml(getContext().getString(R.string.search_results_for,
+                        "<b>" + getQueryString() + "</b>")));
+            }
+        }
     }
 
     private void configurePinnedHeader(ListView listView, ListAdapter adapter) {
@@ -95,4 +129,28 @@
     public boolean isPhotoLoaderEnabled() {
         return mPhotoLoaderEnabled;
     }
+
+    public void setSearchMode(boolean flag) {
+        mSearchMode = flag;
+    }
+
+    public boolean isSearchMode() {
+        return mSearchMode;
+    }
+
+    public void setSearchResultsMode(boolean flag) {
+        mSearchResultsMode = flag;
+    }
+
+    public boolean isSearchResultsMode() {
+        return mSearchResultsMode;
+    }
+
+    public String getQueryString() {
+        return mQueryString;
+    }
+
+    public void setQueryString(String queryString) {
+        mQueryString = queryString;
+    }
 }
diff --git a/src/com/android/contacts/list/ContactsIntentResolver.java b/src/com/android/contacts/list/ContactsIntentResolver.java
index 034e64f..b5f8caf 100644
--- a/src/com/android/contacts/list/ContactsIntentResolver.java
+++ b/src/com/android/contacts/list/ContactsIntentResolver.java
@@ -479,7 +479,7 @@
         ContactEntryListConfiguration config;
         switch (mMode) {
             case MODE_DEFAULT: {
-                config = new MainContactListConfiguration(mContext, mAppController);
+                config = new DefaultContactListConfiguration(mContext, mAppController);
                 if (!mSearchMode) {
                     config.setSectionHeaderDisplayEnabled(true);
                 }
@@ -506,6 +506,10 @@
             }
         }
 
+        config.setSearchMode(mSearchMode);
+        config.setSearchResultsMode(mSearchResultsMode);
+        config.setQueryString(mInitialFilter);
+
         if ((mMode & MODE_MASK_SHOW_PHOTOS) == MODE_MASK_SHOW_PHOTOS) {
             config.setPhotoLoaderEnabled(true);
         }
diff --git a/src/com/android/contacts/list/DefaultContactListConfiguration.java b/src/com/android/contacts/list/DefaultContactListConfiguration.java
index a681f3a..52238aa 100644
--- a/src/com/android/contacts/list/DefaultContactListConfiguration.java
+++ b/src/com/android/contacts/list/DefaultContactListConfiguration.java
@@ -17,8 +17,11 @@
 
 import com.android.contacts.ContactsApplicationController;
 import com.android.contacts.ContactsListActivity;
+import com.android.contacts.R;
 
 import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
 import android.widget.ListAdapter;
 
 /**
@@ -44,4 +47,16 @@
     public ContactEntryListController createController() {
         return new DefaultContactListController(getContext(), getApplicationController());
     }
+
+    @Override
+    protected View inflateView() {
+        LayoutInflater inflater = LayoutInflater.from(getContext());
+        if (isSearchMode()) {
+            return inflater.inflate(R.layout.contacts_search_content, null);
+        } else if (isSearchResultsMode()) {
+            return inflater.inflate(R.layout.contacts_list_search_results, null);
+        } else {
+            return inflater.inflate(R.layout.contacts_list_content, null);
+        }
+    }
 }
diff --git a/src/com/android/contacts/list/JoinContactListConfiguration.java b/src/com/android/contacts/list/JoinContactListConfiguration.java
index 6c8443a..5839010 100644
--- a/src/com/android/contacts/list/JoinContactListConfiguration.java
+++ b/src/com/android/contacts/list/JoinContactListConfiguration.java
@@ -17,8 +17,11 @@
 
 import com.android.contacts.ContactsApplicationController;
 import com.android.contacts.JoinContactActivity;
+import com.android.contacts.R;
 
 import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
 import android.widget.ListAdapter;
 
 /**
@@ -46,4 +49,10 @@
         // TODO needs a separate controller
         return new DefaultContactListController(getContext(), getApplicationController());
     }
+
+    @Override
+    protected View inflateView() {
+        LayoutInflater inflater = LayoutInflater.from(getContext());
+        return inflater.inflate(R.layout.contacts_list_content_join, null);
+    }
 }
diff --git a/src/com/android/contacts/list/MainContactListConfiguration.java b/src/com/android/contacts/list/MainContactListConfiguration.java
deleted file mode 100644
index 565f7e1..0000000
--- a/src/com/android/contacts/list/MainContactListConfiguration.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.contacts.list;
-
-import com.android.contacts.ContactsApplicationController;
-import com.android.contacts.ContactsListActivity;
-
-import android.content.Context;
-import android.widget.ListAdapter;
-
-/**
- * Configuration for the default contact list.
- */
-public class MainContactListConfiguration extends ContactEntryListConfiguration {
-
-    public MainContactListConfiguration(Context context,
-            ContactsApplicationController applicationController) {
-        super(context, applicationController);
-    }
-
-    @Override
-    public ListAdapter createListAdapter() {
-        ContactItemListAdapter adapter =
-                new ContactItemListAdapter((ContactsListActivity)getContext());
-        adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled());
-        adapter.setDisplayPhotos(true);
-        return adapter;
-    }
-
-    @Override
-    public ContactEntryListController createController() {
-        return new MainContactListController(getContext(), getApplicationController());
-    }
-}
diff --git a/src/com/android/contacts/list/MainContactListController.java b/src/com/android/contacts/list/MainContactListController.java
deleted file mode 100644
index 7aae6b4..0000000
--- a/src/com/android/contacts/list/MainContactListController.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.list;
-
-import com.android.contacts.ContactsApplicationController;
-
-import android.content.Context;
-
-/**
- * Controller for the default contact list.
- */
-public class MainContactListController extends ContactEntryListController {
-
-    public MainContactListController(Context context,
-            ContactsApplicationController appController) {
-        super(context, appController);
-    }
-
-    @Override
-    protected void onItemClick(int position, long id) {
-        // TODO instead of delegating the entire procedure to the ContactsListActivity,
-        // figure out what the specific action is and delegate the specific action.
-        getContactsApplicationController().onListItemClick(position, id);
-    }
-}
diff --git a/src/com/android/contacts/list/MultiplePhonePickerConfiguration.java b/src/com/android/contacts/list/MultiplePhonePickerConfiguration.java
index 8331282..66c3d95 100644
--- a/src/com/android/contacts/list/MultiplePhonePickerConfiguration.java
+++ b/src/com/android/contacts/list/MultiplePhonePickerConfiguration.java
@@ -17,8 +17,11 @@
 
 import com.android.contacts.ContactsApplicationController;
 import com.android.contacts.MultiplePhonePickerActivity;
+import com.android.contacts.R;
 
 import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
 import android.widget.ListAdapter;
 
 /**
@@ -46,4 +49,11 @@
         // TODO this needs a separate controller
         return new DefaultContactListController(getContext(), getApplicationController());
     }
+
+    @Override
+    protected View inflateView() {
+        // TODO implement a proper search mode for MultiPicker
+        LayoutInflater inflater = LayoutInflater.from(getContext());
+        return inflater.inflate(R.layout.contacts_list_content, null);
+    }
 }
diff --git a/tests/src/com/android/contacts/ContactListModeTest.java b/tests/src/com/android/contacts/ContactListModeTest.java
index fe8ef5c..8a3a341 100644
--- a/tests/src/com/android/contacts/ContactListModeTest.java
+++ b/tests/src/com/android/contacts/ContactListModeTest.java
@@ -27,6 +27,8 @@
 import android.provider.ContactsContract.ProviderStatus;
 import android.provider.ContactsContract.StatusUpdates;
 import android.test.ActivityUnitTestCase;
+import android.widget.ListAdapter;
+import android.widget.ListView;
 
 /**
  * Tests for the contact list activity modes.
@@ -102,6 +104,8 @@
         activity.runQueriesSynchronously();
         activity.onResume();        // Trigger the queries
 
-        assertEquals(3, activity.getListAdapter().getCount());
+        ListView listView = (ListView)activity.findViewById(android.R.id.list);
+        ListAdapter adapter = listView.getAdapter();
+        assertEquals(3, adapter.getCount());
     }
 }