Avoid selecting group item every time when groups are loaded

* Cause: when there are a great number of contacts in the a newly-added
  account, onGroupsLoaded will be called many times during contacts
  sync. As we set seletced menu item in it, the navigation drawer
  menu will jump again and again.
* Solution: we notify listener only when the loaded groups are changed.

Bug 30306059

Change-Id: I93c039861fbe74e672d95d03c4644b6d31b8bbe5
diff --git a/src/com/android/contacts/group/GroupListItem.java b/src/com/android/contacts/group/GroupListItem.java
index f2359b6..3bfcdd3 100644
--- a/src/com/android/contacts/group/GroupListItem.java
+++ b/src/com/android/contacts/group/GroupListItem.java
@@ -15,6 +15,8 @@
  */
 package com.android.contacts.group;
 
+import java.util.Objects;
+
 /**
  * Meta-data for a contact group.  We load all groups associated with the contact's
  * constituent accounts.
@@ -83,4 +85,36 @@
     public String getSystemId() {
         return mSystemId;
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAccountName, mAccountType, mDataSet, mGroupId, mTitle,
+                mIsFirstGroupInAccount, mMemberCount, mIsReadOnly, mSystemId);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
+        if (!(other instanceof GroupListItem)) {
+            return false;
+        }
+
+        final GroupListItem otherGroup = (GroupListItem) other;
+        if (!Objects.equals(mAccountName, otherGroup.getAccountName())
+                || !Objects.equals(mAccountType, otherGroup.getAccountType())
+                || !Objects.equals(mDataSet, otherGroup.getDataSet())
+                || !(mGroupId == otherGroup.getGroupId())
+                || !Objects.equals(mTitle, otherGroup.getTitle())
+                || !(mIsFirstGroupInAccount == otherGroup.isFirstGroupInAccount())
+                || !(mMemberCount == otherGroup.getMemberCount())
+                || !(mIsReadOnly == otherGroup.isReadOnly())
+                || !Objects.equals(mSystemId, otherGroup.getSystemId())) {
+            return false;
+        }
+
+        return true;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/group/GroupsFragment.java b/src/com/android/contacts/group/GroupsFragment.java
index be1b44a..4c9e251 100644
--- a/src/com/android/contacts/group/GroupsFragment.java
+++ b/src/com/android/contacts/group/GroupsFragment.java
@@ -18,11 +18,11 @@
 
 import android.app.Fragment;
 import android.app.LoaderManager;
-import android.content.Context;
 import android.content.CursorLoader;
 import android.content.Loader;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.util.Log;
 
 import com.android.contacts.GroupListLoader;
 
@@ -34,6 +34,8 @@
  */
 public final class GroupsFragment extends Fragment {
 
+    private static final String TAG = GroupsFragment.class.getSimpleName();
+
     private static final int LOADER_GROUPS = 1;
 
     /**
@@ -57,12 +59,26 @@
 
                 @Override
                 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-                    mGroupListItems.clear();
+                    final List<GroupListItem> newGroupListItems = new ArrayList<>();
                     for (int i = 0; i < data.getCount(); i++) {
                         if (data.moveToNext()) {
-                            mGroupListItems.add(GroupUtil.getGroupListItem(data, i));
+                            newGroupListItems.add(GroupUtil.getGroupListItem(data, i));
                         }
                     }
+
+                    if (mGroupListItems.equals(newGroupListItems)) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "The same groups loaded, returning.");
+                        }
+                        return;
+                    }
+
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "New group(s) loaded.");
+                    }
+
+                    mGroupListItems.clear();
+                    mGroupListItems.addAll(newGroupListItems);
                     if (mListener != null) {
                         mListener.onGroupsLoaded(mGroupListItems);
                     }