Add list event clearcut logging (1/3)

- Update logging previous screen when QuickContact is opened.
- Log various list events.
- All actions are logged when finished.
- "Load" action is logged when load is finished and when account
  filter is changed, so as to avoid unnecessary repeated logging.
- Some of the "/*...*/" comments are omitted if the variable
  name is the same as the parameter name.

Bug 28718104

Change-Id: Ib59d8d40eb9e9d68b8ad418c1a83ffba1d7ef7de
diff --git a/src/com/android/contacts/activities/GroupMembersActivity.java b/src/com/android/contacts/activities/GroupMembersActivity.java
index e27664d..9b9e8b0 100644
--- a/src/com/android/contacts/activities/GroupMembersActivity.java
+++ b/src/com/android/contacts/activities/GroupMembersActivity.java
@@ -41,6 +41,9 @@
 import com.android.contacts.GroupMemberLoader.GroupEditorQuery;
 import com.android.contacts.R;
 import com.android.contacts.common.editor.SelectAccountDialogFragment;
+import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.logging.ListEvent;
+import com.android.contacts.common.logging.ScreenEvent.ScreenType;
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
@@ -347,6 +350,15 @@
                 return true;
             }
             case R.id.menu_remove_from_group: {
+                if (mMembersListFragment == null) {
+                    return false;
+                }
+                final int count = mMembersListFragment.getAdapter().getCount();
+                final int numSelected =
+                        mMembersListFragment.getAdapter().getSelectedContactIdsArray().length;
+                Logger.logListEvent(ListEvent.ActionType.REMOVE_LABEL,
+                        mMembersListFragment.getListType(), count, /* clickedIndex */ -1,
+                        numSelected);
                 removeSelectedContacts();
                 return true;
             }
@@ -570,8 +582,13 @@
     }
 
     @Override
-    public void onGroupMemberListItemClicked(Uri contactLookupUri) {
-        startActivity(ImplicitIntentsUtil.composeQuickContactIntent(
-                contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED));
+    public void onGroupMemberListItemClicked(int position, Uri contactLookupUri) {
+        final int count = mMembersListFragment.getAdapter().getCount();
+        Logger.logListEvent(ListEvent.ActionType.CLICK, ListEvent.ListType.GROUP, count,
+                /* clickedIndex */ position, /* numSelected */ 0);
+        final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
+                contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED);
+        intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, ScreenType.LIST_GROUP);
+        startActivity(intent);
     }
 }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 93d3f84..2b96f5a 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -72,6 +72,7 @@
 import com.android.contacts.common.list.ContactListFilterController;
 import com.android.contacts.common.list.DirectoryListLoader;
 import com.android.contacts.common.list.ViewPagerTabs;
+import com.android.contacts.common.logging.ListEvent;
 import com.android.contacts.common.logging.Logger;
 import com.android.contacts.common.logging.ScreenEvent.ScreenType;
 import com.android.contacts.common.preference.ContactsPreferenceActivity;
@@ -129,6 +130,8 @@
 
     private static final String ENABLE_DEBUG_OPTIONS_HIDDEN_CODE = "debug debug!";
 
+    private static final int ACTIVITY_REQUEST_CODE_SHARE = 0;
+
     private final DialogManager mDialogManager = new DialogManager(this);
 
     private ContactsIntentResolver mIntentResolver;
@@ -398,6 +401,10 @@
 
         mAllFragment.setOnContactListActionListener(new ContactBrowserActionListener());
         mAllFragment.setCheckBoxListListener(new CheckBoxListListener());
+        final int listType =  mContactListFilterController.getFilter().filterType ==
+                ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS
+                ? ListEvent.ListType.ALL_CONTACTS : ListEvent.ListType.ACCOUNT;
+        mAllFragment.setListType(listType);
 
         if (areGroupWritableAccountsAvailable() && mGroupsFragment != null) {
             mGroupsFragment.setListener(this);
@@ -1028,7 +1035,8 @@
         }
 
         @Override
-        public void onViewContactAction(Uri contactLookupUri, boolean isEnterpriseContact) {
+        public void onViewContactAction(int position, Uri contactLookupUri,
+                boolean isEnterpriseContact) {
             if (isEnterpriseContact) {
                 // No implicit intent as user may have a different contacts app in work profile.
                 QuickContact.showQuickContact(PeopleActivity.this, new Rect(), contactLookupUri,
@@ -1036,8 +1044,26 @@
             } else {
                 final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
                         contactLookupUri, QuickContactActivity.MODE_FULLY_EXPANDED);
-                intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE,
-                        mAllFragment.isSearchMode() ? ScreenType.SEARCH : ScreenType.ALL_CONTACTS);
+                final int previousScreen;
+                if (mAllFragment.isSearchMode()) {
+                    previousScreen = ScreenType.SEARCH;
+                } else {
+                    if (mAllFragment.getFilter().filterType ==
+                            ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
+                        if (position < mAllFragment.getAdapter().getNumberOfFavorites()) {
+                            previousScreen = ScreenType.FAVORITES;
+                        } else {
+                            previousScreen = ScreenType.ALL_CONTACTS;
+                        }
+                    } else {
+                        previousScreen = ScreenType.LIST_ACCOUNT;
+                    }
+                }
+                Logger.logListEvent(ListEvent.ActionType.CLICK,
+                        /* listType */ getListTypeIncludingSearch(),
+                        /* count */ mAllFragment.getAdapter().getCount(),
+                        /* clickedIndex */ position, /* numSelected */ 0);
+                intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, previousScreen);
                 ImplicitIntentsUtil.startActivityInApp(PeopleActivity.this, intent);
             }
         }
@@ -1208,6 +1234,10 @@
                 return true;
             }
             case R.id.menu_join: {
+                Logger.logListEvent(ListEvent.ActionType.LINK,
+                        /* listType */ getListTypeIncludingSearch(),
+                        /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
+                        /* numSelected */ mAllFragment.getAdapter().getSelectedContactIds().size());
                 joinSelectedContacts();
                 return true;
             }
@@ -1236,6 +1266,8 @@
                     ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE);
             intent.putExtra(ContactsPreferenceActivity.EXTRA_MODE_FULLY_EXPANDED,
                     QuickContactActivity.MODE_FULLY_EXPANDED);
+            intent.putExtra(ContactsPreferenceActivity.EXTRA_PREVIOUS_SCREEN_TYPE,
+                    QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE);
             startActivity(intent);
         } else if (id == R.id.nav_help) {
             HelpUtils.launchHelpAndFeedbackForMainScreen(this);
@@ -1312,7 +1344,13 @@
         final Intent intent = new Intent(Intent.ACTION_SEND);
         intent.setType(Contacts.CONTENT_VCARD_TYPE);
         intent.putExtra(Intent.EXTRA_STREAM, uri);
-        ImplicitIntentsUtil.startActivityOutsideApp(this, intent);
+        try {
+            // TODO(wenyiw): show different strings based on number of contacts.
+            startActivityForResult(Intent.createChooser(intent, getText(R.string.share_via)),
+                    ACTIVITY_REQUEST_CODE_SHARE);
+        } catch (final ActivityNotFoundException ex) {
+            Toast.makeText(this, R.string.share_error, Toast.LENGTH_SHORT).show();
+        }
     }
 
     private void joinSelectedContacts() {
@@ -1330,9 +1368,19 @@
 
     @Override
     public void onDeletionFinished() {
+        // The parameters count and numSelected are both the number of contacts before deletion.
+        Logger.logListEvent(ListEvent.ActionType.DELETE,
+                /* listType */ getListTypeIncludingSearch(),
+                /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
+                /* numSelected */ mAllFragment.getSelectedContactIds().size());
         mActionBarAdapter.setSelectionMode(false);
     }
 
+    private int getListTypeIncludingSearch() {
+        return mAllFragment.isSearchMode()
+                ? ListEvent.ListType.SEARCH_RESULT : mAllFragment.getListType();
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         switch (requestCode) {
@@ -1342,6 +1390,12 @@
                 if (resultCode == RESULT_OK) {
                     mAllFragment.onPickerResult(data);
                 }
+            case ACTIVITY_REQUEST_CODE_SHARE:
+                Logger.logListEvent(ListEvent.ActionType.SHARE,
+                    /* listType */ getListTypeIncludingSearch(),
+                    /* count */ mAllFragment.getAdapter().getCount(), /* clickedIndex */ -1,
+                    /* numSelected */ mAllFragment.getAdapter().getSelectedContactIds().size());
+
 
 // TODO fix or remove multipicker code
 //                else if (resultCode == RESULT_CANCELED && mMode == MODE_PICK_MULTIPLE_PHONES) {
diff --git a/src/com/android/contacts/group/GroupMembersListFragment.java b/src/com/android/contacts/group/GroupMembersListFragment.java
index 018f9f8..8553b9b 100644
--- a/src/com/android/contacts/group/GroupMembersListFragment.java
+++ b/src/com/android/contacts/group/GroupMembersListFragment.java
@@ -33,6 +33,7 @@
 import com.android.contacts.R;
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
+import com.android.contacts.common.logging.ListEvent.ListType;
 import com.android.contacts.list.MultiSelectContactsListFragment;
 
 /** Displays the members of a group. */
@@ -58,7 +59,7 @@
         void onGroupMetadataLoadFailed();
 
         /** Invoked when a group member in the list is clicked. */
-        void onGroupMemberListItemClicked(Uri contactLookupUri);
+        void onGroupMemberListItemClicked(int position, Uri contactLookupUri);
     }
 
     /** Step 1 of loading group metadata. */
@@ -158,6 +159,7 @@
         // Don't show the scrollbar until after group members have been loaded
         setVisibleScrollbarEnabled(false);
         setQuickContactEnabled(false);
+        setListType(ListType.GROUP);
     }
 
     public void setListener(GroupMembersListListener listener) {
@@ -268,7 +270,7 @@
         }
         if (mListener != null) {
             final Uri contactLookupUri = getAdapter().getContactLookupUri(position);
-            mListener.onGroupMemberListItemClicked(contactLookupUri);
+            mListener.onGroupMemberListItemClicked(position, contactLookupUri);
         }
     }
 }
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index ea55333..436c3a2 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -39,6 +39,7 @@
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
 import com.android.contacts.common.list.DirectoryPartition;
+import com.android.contacts.common.logging.ListEvent.ListType;
 import com.android.contacts.common.util.ContactLoaderUtils;
 
 import java.util.List;
@@ -203,11 +204,16 @@
         }
 
         if (mFilter != null && mFilter.equals(filter)) {
+            setLogListEvents(false);
             return;
         }
 
         Log.v(TAG, "New filter: " + filter);
 
+        setListType(filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS
+                ? ListType.ALL_CONTACTS : ListType.ACCOUNT);
+        setLogListEvents(true);
+
         mFilter = filter;
         mLastSelectedPosition = -1;
         saveFilter();
@@ -604,9 +610,10 @@
         mListener = listener;
     }
 
-    public void viewContact(Uri contactUri, boolean isEnterpriseContact) {
+    public void viewContact(int position, Uri contactUri, boolean isEnterpriseContact) {
         setSelectedContactUri(contactUri, false, false, true, false);
-        if (mListener != null) mListener.onViewContactAction(contactUri, isEnterpriseContact);
+        if (mListener != null) mListener.onViewContactAction(position, contactUri,
+                isEnterpriseContact);
     }
 
     public void deleteContact(Uri contactUri) {
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 97bb86a..aad99d1 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -67,7 +67,7 @@
             super.onItemClick(position, id);
             return;
         }
-        viewContact(uri, getAdapter().isEnterpriseContact(position));
+        viewContact(position, uri, getAdapter().isEnterpriseContact(position));
     }
 
     @Override
diff --git a/src/com/android/contacts/list/MultiSelectContactsListFragment.java b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
index 53f5a74..682f39b 100644
--- a/src/com/android/contacts/list/MultiSelectContactsListFragment.java
+++ b/src/com/android/contacts/list/MultiSelectContactsListFragment.java
@@ -19,8 +19,9 @@
 import com.android.contacts.common.list.ContactEntryListFragment;
 import com.android.contacts.common.list.MultiSelectEntryContactListAdapter;
 import com.android.contacts.common.list.MultiSelectEntryContactListAdapter.SelectedContactsListener;
-import com.android.contacts.common.logging.SearchState;
+import com.android.contacts.common.logging.ListEvent.ActionType;
 import com.android.contacts.common.logging.Logger;
+import com.android.contacts.common.logging.SearchState;
 
 import android.database.Cursor;
 import android.os.Bundle;
@@ -148,8 +149,11 @@
                 mCheckBoxListListener.onStartDisplayingCheckBoxes();
             }
             getAdapter().toggleSelectionOfContactId(contactId);
+            Logger.logListEvent(ActionType.SELECT, getListType(),
+                    /* count */ getAdapter().getCount(), /* clickedIndex */ position,
+                    /* numSelected */ 1);
             // Manually send clicked event if there is a checkbox.
-            // See b/24098561.  TalkBack will not read it otherwise.
+            // See b/24098561. TalkBack will not read it otherwise.
             final int index = position + getListView().getHeaderViewsCount() - getListView()
                     .getFirstVisiblePosition();
             if (index >= 0 && index < getListView().getChildCount()) {
diff --git a/src/com/android/contacts/list/OnContactBrowserActionListener.java b/src/com/android/contacts/list/OnContactBrowserActionListener.java
index 59fc611..5c046d1 100644
--- a/src/com/android/contacts/list/OnContactBrowserActionListener.java
+++ b/src/com/android/contacts/list/OnContactBrowserActionListener.java
@@ -31,9 +31,10 @@
     /**
      * Opens the specified contact for viewing.
      *
-     * @param contactLookupUri The lookup-uri of the Contact that should be opened
+     * @param position The index of the contact that should be opened
+     * @param contactLookupUri The lookup-uri of the contact that should be opened
      */
-    void onViewContactAction(Uri contactLookupUri, boolean isEnterpriseContact);
+    void onViewContactAction(int position, Uri contactLookupUri, boolean isEnterpriseContact);
 
     /**
      * Initiates the contact deletion process.