Adding "empty" message in empty state

Added the message "No Contacts"/"No Favorites"/"No Groups" when
There are no accounts and no contacts on the device according to
the tab selected.
Added a message on the groups view when no accounts are on the
device and a button to add a new account

Bug 5071818: Empty state when no accounts added to device

Change-Id: If736899f4549554693f832f78a1f22798f2beae2
diff --git a/res/layout/contact_tile_list.xml b/res/layout/contact_tile_list.xml
index 69ae1cc..c72386e 100644
--- a/res/layout/contact_tile_list.xml
+++ b/res/layout/contact_tile_list.xml
@@ -30,6 +30,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center_horizontal"
-        android:textAppearance="?android:attr/textAppearanceLarge"/>
+        android:layout_marginTop="@dimen/empty_message_top_margin"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
 
 </FrameLayout>
diff --git a/res/layout/contacts_unavailable_fragment.xml b/res/layout/contacts_unavailable_fragment.xml
index 44c51b5..5566589 100644
--- a/res/layout/contacts_unavailable_fragment.xml
+++ b/res/layout/contacts_unavailable_fragment.xml
@@ -35,7 +35,7 @@
             android:id="@+id/message"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textAppearance="?android:attr/textAppearanceMedium"
             android:layout_marginBottom="20dip" />
 
         <Button
diff --git a/res/layout/group_browse_list_fragment.xml b/res/layout/group_browse_list_fragment.xml
index 66059fe..9e6bd27 100644
--- a/res/layout/group_browse_list_fragment.xml
+++ b/res/layout/group_browse_list_fragment.xml
@@ -31,12 +31,40 @@
       android:cacheColorHint="@android:color/transparent"
       android:divider="@null" />
 
-   <TextView
-     android:id="@+id/empty"
-     android:layout_width="match_parent"
-     android:layout_height="match_parent"
-     android:gravity="center"
-     android:text="@string/noGroups"
-     android:visibility="gone"/>
+    <TextView
+      android:id="@+id/empty"
+      android:layout_marginTop="@dimen/empty_message_top_margin"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_horizontal"
+      android:textAppearance="?android:attr/textAppearanceMedium"
+      android:text="@string/noGroups" />
 
+    <LinearLayout
+      android:id="@+id/add_accounts"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical">
+
+      <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:layout_marginTop="@dimen/no_accounts_message_margin"
+        android:layout_marginBottom="@dimen/no_accounts_message_margin"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="@string/noAccounts" />
+
+      <Button
+        android:id="@+id/add_account_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="@dimen/add_account_button_left_margin"
+        android:layout_marginRight="@dimen/add_account_button_right_margin"
+        android:gravity="center"
+        android:layout_gravity="center_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text="@string/contacts_unavailable_add_account" />
+
+    </LinearLayout>
 </LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 18b86be..1dab5ef 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -226,4 +226,10 @@
     <dimen name="call_detail_contact_background_overlay_height">42dip</dimen>
     <dimen name="call_detail_contact_name_margin">24dip</dimen>
     <dimen name="call_detail_action_bar_height">60dip</dimen>
+
+    <!-- Empty message margins -->
+    <dimen name="empty_message_top_margin">43dip</dimen>
+    <dimen name="no_accounts_message_margin">15dip</dimen>
+    <dimen name="add_account_button_left_margin">50dip</dimen>
+    <dimen name="add_account_button_right_margin">50dip</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7bbeea1..0ab0f91 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -287,11 +287,14 @@
     <!-- The menu item that allows you to remove a photo from a contact [CHAR LIMIT=50] -->
     <string name="removePhoto">Remove photo</string>
 
-    <!-- The text displayed when the contacts list is empty while displaying all contacts -->
-    <string name="noContacts">No contacts.</string>
+    <!-- The text displayed when the contacts list is empty while displaying all contacts [CHAR LIMIT=NONE] -->
+    <string name="noContacts">No contacts</string>
 
     <!-- The text displayed when the groups list is empty while displaying all groups [CHAR LIMIT=NONE] -->
-    <string name="noGroups">No groups.</string>
+    <string name="noGroups">No groups</string>
+
+    <!-- The text displayed when the groups list is empty and no accounts are set on the device while displaying all groups [CHAR LIMIT=NONE] -->
+    <string name="noAccounts">To create groups you need an account</string>
 
     <!-- The text displayed when the contacts list is empty while displaying results after searching contacts -->
     <string name="noMatchingContacts">No matching contacts found.</string>
@@ -358,7 +361,7 @@
     <string name="listTotalAllContactsZeroCustom">No visible contacts</string>
 
     <!-- Displayed at the top of the contacts showing the zero total number of contacts visible when starred contact list is selected  [CHAR LIMIT=64]-->
-    <string name="listTotalAllContactsZeroStarred">No starred contacts</string>
+    <string name="listTotalAllContactsZeroStarred">No Favorites</string>
 
     <!-- Displayed at the top of the contacts showing the zero total number of contacts visible when a group or account is selected  [CHAR LIMIT=64]-->
     <string name="listTotalAllContactsZeroGroup">No contacts in <xliff:g id="name" example="Friends">%s</xliff:g></string>
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index b1b7e5e..06301eb 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -611,6 +611,10 @@
                 }
             }
             invalidateOptionsMenu();
+            showEmptyStateForTab(tab);
+            if (tab == TabState.GROUPS) {
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+            }
             return;
         }
 
@@ -627,6 +631,11 @@
                 mDetailsView.setVisibility(View.GONE);
                 break;
             case GROUPS:
+                mFavoritesView.setVisibility(View.GONE);
+                mBrowserView.setVisibility(View.VISIBLE);
+                mDetailsView.setVisibility(View.VISIBLE);
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+                break;
             case ALL:
                 mFavoritesView.setVisibility(View.GONE);
                 mBrowserView.setVisibility(View.VISIBLE);
@@ -674,6 +683,24 @@
             // fragment transaction does it implicitly.  We don't have to call invalidateOptionsMenu
             // manually.
         }
+        showEmptyStateForTab(tab);
+    }
+
+    private void showEmptyStateForTab(TabState tab) {
+        if (mContactsUnavailableFragment != null) {
+            switch (tab) {
+                case FAVORITES:
+                    mContactsUnavailableFragment.setMessageText(
+                            R.string.listTotalAllContactsZeroStarred);
+                    break;
+                case GROUPS:
+                    mContactsUnavailableFragment.setMessageText(R.string.noGroups);
+                    break;
+                case ALL:
+                    mContactsUnavailableFragment.setMessageText(R.string.noContacts);
+                    break;
+            }
+        }
     }
 
     private class TabPagerListener implements ViewPager.OnPageChangeListener {
@@ -689,7 +716,12 @@
         public void onPageSelected(int position) {
             // Make sure not in the search mode, in which case position != TabState.ordinal().
             if (!mTabPagerAdapter.isSearchMode()) {
-                mActionBarAdapter.setCurrentTab(TabState.fromInt(position), false);
+                TabState selectedTab = TabState.fromInt(position);
+                mActionBarAdapter.setCurrentTab(selectedTab, false);
+                showEmptyStateForTab(selectedTab);
+                if (selectedTab == TabState.GROUPS) {
+                    mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+                }
                 invalidateOptionsMenu();
             }
         }
@@ -913,6 +945,11 @@
             if (mainView != null) {
                 mainView.setVisibility(View.INVISIBLE);
             }
+
+            TabState tab = mActionBarAdapter.getCurrentTab();
+            if (tab == TabState.GROUPS) {
+                mGroupsFragment.setAddAccountsVisibility(!areAccountsAvailable());
+            }
         }
 
         invalidateOptionsMenuIfNeeded();
diff --git a/src/com/android/contacts/group/GroupBrowseListFragment.java b/src/com/android/contacts/group/GroupBrowseListFragment.java
index d0d370e..a1544cf 100644
--- a/src/com/android/contacts/group/GroupBrowseListFragment.java
+++ b/src/com/android/contacts/group/GroupBrowseListFragment.java
@@ -27,15 +27,19 @@
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.provider.ContactsContract;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
@@ -61,6 +65,7 @@
          * @param groupUri for the group that the user wishes to view.
          */
         void onViewGroupAction(Uri groupUri);
+
     }
 
     private static final String TAG = "GroupBrowseListFragment";
@@ -77,6 +82,8 @@
     private View mRootView;
     private AutoScrollListView mListView;
     private View mEmptyView;
+    private View mAddAccountsView;
+    private View mAddAccountButton;
 
     private GroupBrowseListAdapter mAdapter;
     private boolean mSelectionVisible;
@@ -113,6 +120,21 @@
             }
         });
 
+        mEmptyView = mRootView.findViewById(R.id.empty);
+        mAddAccountsView = mRootView.findViewById(R.id.add_accounts);
+        mAddAccountButton = mRootView.findViewById(R.id.add_account_button);
+        mAddAccountButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
+                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                intent.putExtra(Settings.EXTRA_AUTHORITIES,
+                        new String[] { ContactsContract.AUTHORITY });
+                startActivity(intent);
+            }
+        });
+        setAddAccountsVisibility(false);
+
         if (savedInstanceState != null) {
             String groupUriString = savedInstanceState.getString(EXTRA_KEY_GROUP_URI);
             if (groupUriString != null) {
@@ -281,4 +303,10 @@
             }
         }
     }
+
+    public void setAddAccountsVisibility(boolean visible) {
+        if (mAddAccountsView != null) {
+            mAddAccountsView.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
+    }
 }
diff --git a/src/com/android/contacts/list/ContactsUnavailableFragment.java b/src/com/android/contacts/list/ContactsUnavailableFragment.java
index e93687f..3bab3fd 100644
--- a/src/com/android/contacts/list/ContactsUnavailableFragment.java
+++ b/src/com/android/contacts/list/ContactsUnavailableFragment.java
@@ -45,6 +45,7 @@
     private Button mUninstallAppsButton;
     private Button mRetryUpgradeButton;
     private ProgressBar mProgress;
+    private int mNoContactsMsgResId = -1;
 
     private OnContactsUnavailableActionListener mListener;
 
@@ -81,8 +82,14 @@
         int providerStatus = mProviderStatusLoader.getProviderStatus();
         switch (providerStatus) {
             case ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS:
-                mMessageView.setGravity(Gravity.LEFT);
-                mMessageView.setVisibility(View.GONE);
+                if (mNoContactsMsgResId != -1) {
+                    mMessageView.setText(mNoContactsMsgResId);
+                    mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
+                    mMessageView.setVisibility(View.VISIBLE);
+                } else {
+                    mMessageView.setGravity(Gravity.LEFT);
+                    mMessageView.setVisibility(View.GONE);
+                }
                 mCreateContactButton.setVisibility(View.VISIBLE);
                 mAddAccountButton.setVisibility(View.VISIBLE);
                 mImportContactsButton.setVisibility(View.VISIBLE);
@@ -154,4 +161,19 @@
                 break;
         }
     }
+    /**
+     * Set the message to be shown if data is available for the selected tab
+     *
+     * @param resId - String resource ID of the message
+     */
+    public void setMessageText(int resId) {
+        mNoContactsMsgResId = resId;
+        if (mMessageView != null &&
+                mProviderStatusLoader.getProviderStatus() ==
+                    ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS) {
+            mMessageView.setText(mNoContactsMsgResId);
+            mMessageView.setGravity(Gravity.CENTER_HORIZONTAL);
+            mMessageView.setVisibility(View.VISIBLE);
+        }
+    }
 }