Configuring empty list text for Loader/Fragment solution

Change-Id: I157a296e5fefeb6bdf5ffab9ebdc3883665c367a
diff --git a/res/layout-finger/contacts_search_content.xml b/res/layout-finger/contacts_search_content.xml
index d9479dc..680a891 100644
--- a/res/layout-finger/contacts_search_content.xml
+++ b/res/layout-finger/contacts_search_content.xml
@@ -26,7 +26,8 @@
     <include android:id="@+id/searchView"
         layout="@layout/search_bar"/>
 
-    <ListView
+    <view
+        class="com.android.contacts.ContactEntryListView" 
         android:id="@android:id/list"
         android:layout_width="match_parent"
         android:layout_height="0dip"
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index e0634ec..c48a1cc 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -411,7 +411,6 @@
     }
 
     // The size of a home screen shortcut icon.
-    private int mIconSize;
     private ContactsPreferences mContactsPrefs;
     public int mDisplayOrder;
     private int mSortOrder;
@@ -446,7 +445,6 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mIconSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
         mContactsPrefs = new ContactsPreferences(this);
 
         mQueryHandler = new QueryHandler(this);
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index accf42a..94585a0 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -15,6 +15,8 @@
  */
 package com.android.contacts.list;
 
+import com.android.contacts.R;
+
 import android.net.Uri;
 
 /**
@@ -26,6 +28,32 @@
 
     private OnContactBrowserActionListener mListener;
 
+    // TODO
+    private boolean mContactsWithPhoneNumbersOnly;
+
+    @Override
+    protected void prepareEmptyView() {
+        if (isSearchMode()) {
+            return;
+        } else if (isSearchResultsMode()) {
+            setEmptyText(R.string.noMatchingContacts);
+        } else if (mContactsWithPhoneNumbersOnly) {
+            setEmptyText(R.string.noContactsWithPhoneNumbers);
+        } else if (isSyncActive()) {
+            if (hasIccCard()) {
+                setEmptyText(R.string.noContactsHelpTextWithSync);
+            } else {
+                setEmptyText(R.string.noContactsNoSimHelpTextWithSync);
+            }
+        } else {
+            if (hasIccCard()) {
+                setEmptyText(R.string.noContactsHelpText);
+            } else {
+                setEmptyText(R.string.noContactsNoSimHelpText);
+            }
+        }
+    }
+
     public void setOnContactListActionListener(OnContactBrowserActionListener listener) {
         mListener = listener;
     }
@@ -71,5 +99,4 @@
         super.finish();
         mListener.onFinishAction();
     }
-
 }
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index c37010e..b6a4300 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -26,6 +26,7 @@
 import android.database.Cursor;
 import android.os.Bundle;
 import android.provider.ContactsContract.ContactCounts;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -53,6 +54,9 @@
     private boolean mSearchMode;
     private boolean mSearchResultsMode;
 
+    private boolean mLoading = true;
+    private boolean mEmptyListEnabled = true;
+
     public ContactEntryListAdapter(Context context) {
         super(context, R.layout.list_section, R.id.header_text,
                 context.getResources().getColor(R.color.pinned_header_background));
@@ -146,6 +150,14 @@
         mDisplayPhotos = displayPhotos;
     }
 
+    public boolean isEmptyListEnabled() {
+        return mEmptyListEnabled;
+    }
+
+    public void setEmptyListEnabled(boolean flag) {
+        mEmptyListEnabled = flag;
+    }
+
     /*
      * TODO change this method when loaders are introduced.
      */
@@ -157,6 +169,7 @@
 
     @Override
     public void changeCursor(Cursor cursor) {
+        mLoading = false;
         super.changeCursor(cursor);
 
         if (isSectionHeaderDisplayEnabled()) {
@@ -184,6 +197,25 @@
         }
     }
 
+    @Override
+    public boolean isEmpty() {
+        // TODO
+//        if (contactsListActivity.mProviderStatus != ProviderStatus.STATUS_NORMAL) {
+//            return true;
+//        }
+
+        if (!mEmptyListEnabled) {
+            return false;
+        } else if (isSearchMode()) {
+            return TextUtils.isEmpty(getQueryString());
+        } else if (mCursor == null || mLoading) {
+            // We don't want the empty state to show when loading.
+            return false;
+        } else {
+            return super.isEmpty();
+        }
+    }
+
     public void moveToPosition(int position) {
         // For side-effect
         getItem(position);
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 0316251..c279fa4 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -17,6 +17,7 @@
 package com.android.contacts.list;
 
 import com.android.contacts.ContactEntryListView;
+import com.android.contacts.ContactListEmptyView;
 import com.android.contacts.ContactPhotoLoader;
 import com.android.contacts.ContactsApplicationController;
 import com.android.contacts.ContactsListActivity;
@@ -25,18 +26,25 @@
 import com.android.contacts.widget.SearchEditText;
 import com.android.contacts.widget.SearchEditText.OnCloseListener;
 
+import android.accounts.Account;
+import android.accounts.AccountManager;
 import android.app.patterns.CursorLoader;
 import android.app.patterns.Loader;
 import android.app.patterns.LoaderManagingFragment;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.content.IContentService;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.os.RemoteException;
 import android.provider.ContactsContract;
+import android.telephony.TelephonyManager;
 import android.text.Editable;
 import android.text.Html;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -63,6 +71,8 @@
         OnScrollListener, TextWatcher, OnEditorActionListener, OnCloseListener,
         OnFocusChangeListener, OnTouchListener {
 
+    private static final String TAG = "ContactEntryListFragment";
+
     private static final String LIST_STATE_KEY = "liststate";
 
     private boolean mSectionHeaderDisplayEnabled;
@@ -89,6 +99,7 @@
     private ContextMenuAdapter mContextMenuAdapter;
     private ContactPhotoLoader mPhotoLoader;
     private SearchEditText mSearchEditText;
+    private ContactListEmptyView mEmptyView;
 
     protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
     protected abstract T createListAdapter();
@@ -129,6 +140,10 @@
         return mListView;
     }
 
+    public ContactListEmptyView getEmptyView() {
+        return mEmptyView;
+    }
+
     @Override
     protected Loader<Cursor> onCreateLoader(int id, Bundle args) {
         return new CursorLoader(getActivity(), null, null, null, null, null);
@@ -145,6 +160,10 @@
             return;
         }
 
+        if (mEmptyView != null && (data == null || data.getCount() == 0)) {
+            prepareEmptyView();
+        }
+
         mAdapter.changeCursor(data);
         showCount(data);
     }
@@ -155,6 +174,13 @@
     }
 
     /**
+     * Configures the empty view. It is called when we are about to populate
+     * the list with an empty cursor.
+     */
+    protected void prepareEmptyView() {
+    }
+
+    /**
      * Shows the count of entries included in the list. The default
      * implementation does nothing.
      */
@@ -284,6 +310,9 @@
         View emptyView = mView.findViewById(com.android.internal.R.id.empty);
         if (emptyView != null) {
             mListView.setEmptyView(emptyView);
+            if (emptyView instanceof ContactListEmptyView) {
+                mEmptyView = (ContactListEmptyView)emptyView;
+            }
         }
 
         mListView.setOnItemClickListener(this);
@@ -480,4 +509,34 @@
             return String.format(format, count);
         }
     }
+
+    protected void setEmptyText(int resourceId) {
+        TextView empty = (TextView) getEmptyView().findViewById(R.id.emptyText);
+        empty.setText(getActivity().getText(resourceId));
+        empty.setVisibility(View.VISIBLE);
+    }
+
+    // TODO redesign into an async task or loader
+    protected boolean isSyncActive() {
+        Account[] accounts = AccountManager.get(getActivity()).getAccounts();
+        if (accounts != null && accounts.length > 0) {
+            IContentService contentService = ContentResolver.getContentService();
+            for (Account account : accounts) {
+                try {
+                    if (contentService.isSyncActive(account, ContactsContract.AUTHORITY)) {
+                        return true;
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Could not get the sync status");
+                }
+            }
+        }
+        return false;
+    }
+
+    protected boolean hasIccCard() {
+        TelephonyManager telephonyManager =
+                (TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
+        return telephonyManager.hasIccCard();
+    }
 }
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index 3cafa58..e52a9a2 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -109,6 +109,9 @@
         adapter.setContactNameDisplayOrder(getContactNameDisplayOrder());
         adapter.setSortOrder(getSortOrder());
 
+        // If "Create new contact" is shown, don't display the empty list UI
+        adapter.setEmptyListEnabled(!isCreateContactEnabled());
+
         return adapter;
     }
 
@@ -123,6 +126,33 @@
         }
     }
 
+    @Override
+    protected void prepareEmptyView() {
+        if (isSearchMode()) {
+            return;
+        } else if (isSearchResultsMode()) {
+            setEmptyText(R.string.noMatchingContacts);
+        } else if (isSyncActive()) {
+            if (mShortcutRequested) {
+                // Help text is the same no matter whether there is SIM or not.
+                setEmptyText(R.string.noContactsHelpTextWithSyncForCreateShortcut);
+            } else if (hasIccCard()) {
+                setEmptyText(R.string.noContactsHelpTextWithSync);
+            } else {
+                setEmptyText(R.string.noContactsNoSimHelpTextWithSync);
+            }
+        } else {
+            if (mShortcutRequested) {
+                // Help text is the same no matter whether there is SIM or not.
+                setEmptyText(R.string.noContactsHelpTextWithSyncForCreateShortcut);
+            } else if (hasIccCard()) {
+                setEmptyText(R.string.noContactsHelpText);
+            } else {
+                setEmptyText(R.string.noContactsNoSimHelpText);
+            }
+        }
+    }
+
     public void onShortcutIntentCreated(Uri uri, Intent shortcutIntent) {
         mListener.onShortcutIntentCreated(shortcutIntent);
     }
diff --git a/src/com/android/contacts/list/StrequentContactListFragment.java b/src/com/android/contacts/list/StrequentContactListFragment.java
index f678aca..58f7de3 100644
--- a/src/com/android/contacts/list/StrequentContactListFragment.java
+++ b/src/com/android/contacts/list/StrequentContactListFragment.java
@@ -59,6 +59,11 @@
         return inflater.inflate(R.layout.contacts_list_content, null);
     }
 
+    @Override
+    protected void prepareEmptyView() {
+        setEmptyText(R.string.noFavoritesHelpText);
+    }
+
     public void onClick(View v) {
         int id = v.getId();
         switch (id) {