14cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann/*
2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project
34cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
44cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License");
54cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * you may not use this file except in compliance with the License.
64cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * You may obtain a copy of the License at
74cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
84cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *      http://www.apache.org/licenses/LICENSE-2.0
94cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Unless required by applicable law or agreed to in writing, software
114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS,
124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * See the License for the specific language governing permissions and
144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * limitations under the License
154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann */
164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.detail;
184cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1925a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmannimport android.app.Activity;
20222744ea3cd7233677f0ef88804eb3e2db710e43Daniel Lehmannimport android.app.Fragment;
210edd4071ddcb23bf2a7b95582df0657de9ff0c60Dmitri Plotnikovimport android.app.SearchManager;
224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.content.ContentUris;
234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.content.ContentValues;
244cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.content.Context;
254cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.content.Intent;
264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.content.res.Resources;
274cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.graphics.drawable.Drawable;
284cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.net.ParseException;
294cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.net.Uri;
304cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.net.WebAddress;
314cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.os.Bundle;
32db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuanimport android.os.Parcelable;
334cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.os.RemoteException;
344cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.os.ServiceManager;
359eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikovimport android.provider.ContactsContract;
364cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Email;
372deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
384cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Im;
394cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.provider.ContactsContract.CommonDataKinds.Phone;
40caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.provider.ContactsContract.Contacts;
41caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.provider.ContactsContract.Data;
42caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.provider.ContactsContract.Directory;
43caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
44caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
454cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.text.TextUtils;
464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.util.Log;
47627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaroimport android.view.ContextMenu;
48627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaroimport android.view.ContextMenu.ContextMenuInfo;
4913f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chuimport android.view.DragEvent;
504cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.view.KeyEvent;
514cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.view.LayoutInflater;
52627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaroimport android.view.MenuItem;
5313f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chuimport android.view.MotionEvent;
544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.view.View;
55c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmannimport android.view.View.OnClickListener;
5613f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chuimport android.view.View.OnDragListener;
5713f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chuimport android.view.View.OnTouchListener;
58caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.view.ViewGroup;
59a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuanimport android.widget.AbsListView.OnScrollListener;
604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.widget.AdapterView;
61627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaroimport android.widget.AdapterView.AdapterContextMenuInfo;
62caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.widget.AdapterView.OnItemClickListener;
63cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmannimport android.widget.BaseAdapter;
6418db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmannimport android.widget.Button;
654cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.widget.ImageView;
663e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onukiimport android.widget.ListAdapter;
673e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onukiimport android.widget.ListPopupWindow;
684cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.widget.ListView;
694cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.widget.TextView;
704cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
71e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.Collapser;
72e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.Collapser.Collapsible;
73e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactPresenceIconUtil;
74e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService;
75e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactsUtils;
76e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.GroupMetaData;
77e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
78e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.TypePrecedence;
79e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
80e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.SelectAccountDialogFragment;
81e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.model.AccountTypeManager;
82851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.Contact;
83851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContact;
84851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta;
85851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDelta.ValuesDelta;
86851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactDeltaList;
87851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.RawContactModifier;
88851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.account.AccountType;
89851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.account.AccountType.EditType;
90851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.account.AccountWithDataSet;
91851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.DataItem;
92851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.DataKind;
93851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.EmailDataItem;
94851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.EventDataItem;
95851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.GroupMembershipDataItem;
96851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.ImDataItem;
97851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.NicknameDataItem;
98851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.NoteDataItem;
99851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.OrganizationDataItem;
100851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.PhoneDataItem;
101851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.RelationDataItem;
102851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.SipAddressDataItem;
103851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.StructuredNameDataItem;
104851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.StructuredPostalDataItem;
105851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.dataitem.WebsiteDataItem;
106e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.AccountsListAdapter.AccountListFilter;
107e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.ClipboardUtils;
108e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.Constants;
109e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.DataStatus;
110e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.DateUtils;
111e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.PhoneCapabilityTester;
112e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.StructuredPostalUtils;
113e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.internal.telephony.ITelephony;
114e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.annotations.VisibleForTesting;
115851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.google.common.collect.Iterables;
116e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
1174cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport java.util.ArrayList;
1182deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikovimport java.util.Collections;
119515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuanimport java.util.HashMap;
1202deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikovimport java.util.List;
121515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuanimport java.util.Map;
1224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1237edad9dd95a411cc5ed69815e5f0be8a5d1e8b19Josh Garguspublic class ContactDetailFragment extends Fragment implements FragmentKeyListener,
124ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        SelectAccountDialogFragment.Listener, OnItemClickListener {
1254eeac7428b658ee7e6d9280c4e4b6fa02a79c3ddDmitri Plotnikov
126cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    private static final String TAG = "ContactDetailFragment";
1274cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
128627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    private interface ContextMenuIds {
129627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        static final int COPY_TEXT = 0;
130627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        static final int CLEAR_DEFAULT = 1;
131627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        static final int SET_DEFAULT = 2;
132627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    }
133627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
134174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    private static final String KEY_CONTACT_URI = "contactUri";
135db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan    private static final String KEY_LIST_STATE = "liststate";
136174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov
13725a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    private Context mContext;
1383ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov    private View mView;
139a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan    private OnScrollListener mVerticalScrollListener;
14025a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    private Uri mLookupUri;
141cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    private Listener mListener;
142c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmann
143851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    private Contact mContactData;
1446fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private ViewGroup mStaticPhotoContainer;
1456fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    private View mPhotoTouchOverlay;
1464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    private ListView mListView;
1474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    private ViewAdapter mAdapter;
1484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    private Uri mPrimaryPhoneUri = null;
149515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private ViewEntryDimensions mViewEntryDimensions;
1504cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
151187c8167d77687fbc04237c9ac1e87564b2d5f33Josh Gargus    private final ContactDetailPhotoSetter mPhotoSetter = new ContactDetailPhotoSetter();
1529758a92fac3e9f64892d893c992f6020d7fe3bfdJosh Gargus
1537ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private Button mQuickFixButton;
1547ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private QuickFix mQuickFix;
15509eb04f8765671c429d18b578ae163c917dad26aBai Tao    private String mDefaultCountryIso;
1569bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan    private boolean mContactHasSocialUpdates;
1579bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan    private boolean mShowStaticPhoto = true;
1584cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1597ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private final QuickFix[] mPotentialQuickFixes = new QuickFix[] {
1607ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            new MakeLocalCopyQuickFix(),
1616fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            new AddToMyContactsQuickFix()
1626fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro    };
1637ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
1644cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    /**
165f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann     * Device capability: Set during buildEntries and used in the long-press context menu
166f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann     */
167f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann    private boolean mHasPhone;
168f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann
169f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann    /**
170f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann     * Device capability: Set during buildEntries and used in the long-press context menu
171f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann     */
172f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann    private boolean mHasSms;
173f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann
174f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann    /**
1757781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann     * Device capability: Set during buildEntries and used in the long-press context menu
1767781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann     */
1777781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann    private boolean mHasSip;
1787781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann
1797781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann    /**
1804cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     * The view shown if the detail list is empty.
1814cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     * We set this to the list view when first bind the adapter, so that it won't be shown while
1824cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     * we're loading data.
1834cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     */
1844cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    private View mEmptyView;
1854cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1864cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    /**
187db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan     * Saved state of the {@link ListView}. This must be saved and applied to the {@ListView} only
188db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan     * when the adapter has been populated again.
189db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan     */
190db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan    private Parcelable mListState;
191db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan
192db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan    /**
193851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu     * Lists of specific types of entries to be shown in contact details.
1944cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     */
195938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mPhoneEntries = new ArrayList<DetailViewEntry>();
196938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mSmsEntries = new ArrayList<DetailViewEntry>();
197938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mEmailEntries = new ArrayList<DetailViewEntry>();
198938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mPostalEntries = new ArrayList<DetailViewEntry>();
199938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mImEntries = new ArrayList<DetailViewEntry>();
200938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mNicknameEntries = new ArrayList<DetailViewEntry>();
201938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mGroupEntries = new ArrayList<DetailViewEntry>();
202938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mRelationEntries = new ArrayList<DetailViewEntry>();
203938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mNoteEntries = new ArrayList<DetailViewEntry>();
204938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mWebsiteEntries = new ArrayList<DetailViewEntry>();
205938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mSipEntries = new ArrayList<DetailViewEntry>();
206938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<DetailViewEntry> mEventEntries = new ArrayList<DetailViewEntry>();
207515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private final Map<AccountType, List<DetailViewEntry>> mOtherEntriesMap =
208515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            new HashMap<AccountType, List<DetailViewEntry>>();
209938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private ArrayList<ViewEntry> mAllEntries = new ArrayList<ViewEntry>();
210cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    private LayoutInflater mInflater;
2114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
212826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro    private boolean mIsUniqueNumber;
213826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro    private boolean mIsUniqueEmail;
214826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro
2151adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki    private ListPopupWindow mPopup;
2161adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki
21713f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    /**
21813f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     * This is to forward touch events to the list view to enable users to scroll the list view
21913f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     * from the blank area underneath the static photo when the layout with static photo is used.
22013f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     */
22113f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    private OnTouchListener mForwardTouchToListView = new OnTouchListener() {
22213f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        @Override
22313f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        public boolean onTouch(View v, MotionEvent event) {
22413f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            if (mListView != null) {
22513f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu                mListView.dispatchTouchEvent(event);
22613f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu                return true;
22713f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            }
22813f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            return false;
22913f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        }
23013f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    };
23113f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu
23213f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    /**
23313f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     * This is to forward drag events to the list view to enable users to scroll the list view
23413f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     * from the blank area underneath the static photo when the layout with static photo is used.
23513f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu     */
23613f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    private OnDragListener mForwardDragToListView = new OnDragListener() {
23713f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        @Override
23813f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        public boolean onDrag(View v, DragEvent event) {
23913f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            if (mListView != null) {
24013f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu                mListView.dispatchDragEvent(event);
24113f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu                return true;
24213f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            }
24313f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu            return false;
24413f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        }
24513f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu    };
24613f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu
24725a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    public ContactDetailFragment() {
24825a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann        // Explicit constructor for inflation
24925a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    }
25025a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann
25125a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    @Override
252174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    public void onCreate(Bundle savedInstanceState) {
253174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov        super.onCreate(savedInstanceState);
254174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov        if (savedInstanceState != null) {
255174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov            mLookupUri = savedInstanceState.getParcelable(KEY_CONTACT_URI);
256db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan            mListState = savedInstanceState.getParcelable(KEY_LIST_STATE);
257174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov        }
258174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    }
259174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov
260174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    @Override
261174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    public void onSaveInstanceState(Bundle outState) {
262174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov        super.onSaveInstanceState(outState);
263174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov        outState.putParcelable(KEY_CONTACT_URI, mLookupUri);
264db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        if (mListView != null) {
265db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan            outState.putParcelable(KEY_LIST_STATE, mListView.onSaveInstanceState());
266db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        }
267174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    }
268174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov
269174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov    @Override
2708bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    public void onPause() {
2711adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        dismissPopupIfShown();
2728bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen        super.onPause();
2738bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    }
2748bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen
2758bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    @Override
2768bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    public void onResume() {
2778bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen        super.onResume();
2788bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    }
2798bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen
2808bd4065141c64a4ab249aec46e5f32d25a862f64Martijn Coenen    @Override
28125a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    public void onAttach(Activity activity) {
28225a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann        super.onAttach(activity);
28325a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann        mContext = activity;
28409eb04f8765671c429d18b578ae163c917dad26aBai Tao        mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(mContext);
285515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        mViewEntryDimensions = new ViewEntryDimensions(mContext.getResources());
28625a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    }
28725a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann
28825a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    @Override
28984df2b6fc59ad185a6fdc4f46f636e7783e5f1aeDianne Hackborn    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
2903ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        mView = inflater.inflate(R.layout.contact_detail_fragment, container, false);
29113f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        // Set the touch and drag listener to forward the event to the mListView so that
29213f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        // vertical scrolling can happen from outside of the list view.
29313f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        mView.setOnTouchListener(mForwardTouchToListView);
29413f6f26cb8b2f78f0b92dfc1d102222c13217300Maurice Chu        mView.setOnDragListener(mForwardDragToListView);
295c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmann
296cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        mInflater = inflater;
297cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
2986fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        mStaticPhotoContainer = (ViewGroup) mView.findViewById(R.id.static_photo_container);
2996fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        mPhotoTouchOverlay = mView.findViewById(R.id.photo_touch_intercept_overlay);
3008f0f3343e4363a5e1f11b35392c8393f263aaa41Katherine Kuan
3013ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        mListView = (ListView) mView.findViewById(android.R.id.list);
302ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        mListView.setOnItemClickListener(this);
30354eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        mListView.setItemsCanFocus(true);
304a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan        mListView.setOnScrollListener(mVerticalScrollListener);
30550c02ede09a757f69c80beb442aa32ee0010efc7Dmitri Plotnikov
306c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmann        // Don't set it to mListView yet.  We do so later when we bind the adapter.
3073ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        mEmptyView = mView.findViewById(android.R.id.empty);
308c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmann
3097ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        mQuickFixButton = (Button) mView.findViewById(R.id.contact_quick_fix);
3107ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        mQuickFixButton.setOnClickListener(new OnClickListener() {
31118db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann            @Override
31218db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann            public void onClick(View v) {
313073f1f9e0ba3b1195d1d56590decf62645f20b6aKatherine Kuan                if (mQuickFix != null) {
314073f1f9e0ba3b1195d1d56590decf62645f20b6aKatherine Kuan                    mQuickFix.execute();
315073f1f9e0ba3b1195d1d56590decf62645f20b6aKatherine Kuan                }
31618db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann            }
31718db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann        });
31818db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann
319d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov        mView.setVisibility(View.INVISIBLE);
3202eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
3212eb969cc399d87b659a45568fa951d394c216917Katherine Kuan        if (mContactData != null) {
3222eb969cc399d87b659a45568fa951d394c216917Katherine Kuan            bindData();
3232eb969cc399d87b659a45568fa951d394c216917Katherine Kuan        }
324db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan
3253ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        return mView;
32625a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    }
32725a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann
328cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public void setListener(Listener value) {
329cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        mListener = value;
33025a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann    }
33125a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann
33279700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    protected Context getContext() {
33379700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan        return mContext;
33479700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    }
33579700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan
33679700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    protected Listener getListener() {
33779700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan        return mListener;
33879700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    }
33979700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan
340851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    protected Contact getContactData() {
34179700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan        return mContactData;
342a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan    }
343a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan
344a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan    public void setVerticalScrollListener(OnScrollListener listener) {
345a1455a2288a7956ea9543177cee4a3be75745e32Katherine Kuan        mVerticalScrollListener = listener;
34679700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    }
34779700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan
3489cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov    public Uri getUri() {
3499cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov        return mLookupUri;
3509cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov    }
3519cd1708f333eda622dc6a4fed2a0df9058193a9dDmitri Plotnikov
3522eb969cc399d87b659a45568fa951d394c216917Katherine Kuan    /**
3539bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan     * Sets whether the static contact photo (that is not in a scrolling region), should be shown
3549bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan     * or not.
3552eb969cc399d87b659a45568fa951d394c216917Katherine Kuan     */
3569bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan    public void setShowStaticPhoto(boolean showPhoto) {
3579bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan        mShowStaticPhoto = showPhoto;
3582eb969cc399d87b659a45568fa951d394c216917Katherine Kuan    }
3592eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
3606e607d54ce08ebcc78d94963646a42605697f132Maurice Chu    /**
3616e607d54ce08ebcc78d94963646a42605697f132Maurice Chu     * Shows the contact detail with a message indicating there are no contact details.
3626e607d54ce08ebcc78d94963646a42605697f132Maurice Chu     */
363050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa    public void showEmptyState() {
364050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa        setData(null, null);
365050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa    }
366050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa
367851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    public void setData(Uri lookupUri, Contact result) {
36816c4b2943e02a0b919e7da7bb5e58ced7523b8f6Katherine Kuan        mLookupUri = lookupUri;
3692eb969cc399d87b659a45568fa951d394c216917Katherine Kuan        mContactData = result;
3702eb969cc399d87b659a45568fa951d394c216917Katherine Kuan        bindData();
3712eb969cc399d87b659a45568fa951d394c216917Katherine Kuan    }
3722eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
3736c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    /**
374ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan     * Reset the list adapter in this {@link Fragment} to get rid of any saved scroll position
375ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan     * from a previous contact.
376ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan     */
377ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan    public void resetAdapter() {
378ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan        if (mListView != null) {
379ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan            mListView.setAdapter(mAdapter);
380ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan        }
381ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan    }
382ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan
383ab5387bb8728c34bafcb554830961341f1f9daeaKatherine Kuan    /**
3846c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * Returns the top coordinate of the first item in the {@link ListView}. If the first item
3856c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * in the {@link ListView} is not visible or there are no children in the list, then return
3866c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * Integer.MIN_VALUE. Note that the returned value will be <= 0 because the first item in the
3876c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * list cannot have a positive offset.
3886c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     */
3896c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    public int getFirstListItemOffset() {
3906c0470e21d8506fb53915df7463634fd47288343Katherine Kuan        return ContactDetailDisplayUtils.getFirstListItemOffset(mListView);
3916c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    }
3926c0470e21d8506fb53915df7463634fd47288343Katherine Kuan
3936c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    /**
3946c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * Tries to scroll the first item to the given offset (this can be a no-op if the list is
3956c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * already in the correct position).
3966c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     * @param offset which should be <= 0
3976c0470e21d8506fb53915df7463634fd47288343Katherine Kuan     */
3986c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    public void requestToMoveToOffset(int offset) {
3996c0470e21d8506fb53915df7463634fd47288343Katherine Kuan        ContactDetailDisplayUtils.requestToMoveToOffset(mListView, offset);
4006c0470e21d8506fb53915df7463634fd47288343Katherine Kuan    }
4016c0470e21d8506fb53915df7463634fd47288343Katherine Kuan
40279700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    protected void bindData() {
4033ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        if (mView == null) {
4043ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov            return;
4053ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        }
4063ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov
4077bf064ec75d7557671cdc39df1f9c28d59d97f81Dmitri Plotnikov        if (isAdded()) {
4087bf064ec75d7557671cdc39df1f9c28d59d97f81Dmitri Plotnikov            getActivity().invalidateOptionsMenu();
4097bf064ec75d7557671cdc39df1f9c28d59d97f81Dmitri Plotnikov        }
4107bf064ec75d7557671cdc39df1f9c28d59d97f81Dmitri Plotnikov
4113ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        if (mContactData == null) {
4123ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov            mView.setVisibility(View.INVISIBLE);
4136e607d54ce08ebcc78d94963646a42605697f132Maurice Chu            if (mStaticPhotoContainer != null) {
4146e607d54ce08ebcc78d94963646a42605697f132Maurice Chu                mStaticPhotoContainer.setVisibility(View.GONE);
4156e607d54ce08ebcc78d94963646a42605697f132Maurice Chu            }
416050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa            mAllEntries.clear();
417050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa            if (mAdapter != null) {
418050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa                mAdapter.notifyDataSetChanged();
419050c3893fadaf6d02951a3fe29684f4cd94fa9c9Daisuke Miyakawa            }
4203ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov            return;
4213ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov        }
4223ad2f35559f81e0d1b5ff362795ae77c0493bd0aDmitri Plotnikov
4239bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan        // Figure out if the contact has social updates or not
4249bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan        mContactHasSocialUpdates = !mContactData.getStreamItems().isEmpty();
4259bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan
4268f0f3343e4363a5e1f11b35392c8393f263aaa41Katherine Kuan        // Setup the photo if applicable
4276fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        if (mStaticPhotoContainer != null) {
4286fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            // The presence of a static photo container is not sufficient to determine whether or
4296fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            // not we should show the photo. Check the mShowStaticPhoto flag which can be set by an
4309bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan            // outside class depending on screen size, layout, and whether the contact has social
4319bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan            // updates or not.
4329bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan            if (mShowStaticPhoto) {
4336fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                mStaticPhotoContainer.setVisibility(View.VISIBLE);
4342d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                final ImageView photoView = (ImageView) mStaticPhotoContainer.findViewById(
4352d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                        R.id.photo);
4362d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                final boolean expandPhotoOnClick = mContactData.getPhotoUri() != null;
4372d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
4382d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                        mContext, mContactData, photoView, expandPhotoOnClick);
4396fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                if (mPhotoTouchOverlay != null) {
4406fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                    mPhotoTouchOverlay.setVisibility(View.VISIBLE);
4412d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                    if (expandPhotoOnClick || mContactData.isWritableContact(mContext)) {
44284edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                        mPhotoTouchOverlay.setOnClickListener(listener);
44384edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                    } else {
44484edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                        mPhotoTouchOverlay.setClickable(false);
44584edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                    }
4466fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                }
4479bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan            } else {
4486fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                mStaticPhotoContainer.setVisibility(View.GONE);
4499bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan            }
4508f0f3343e4363a5e1f11b35392c8393f263aaa41Katherine Kuan        }
4518f0f3343e4363a5e1f11b35392c8393f263aaa41Katherine Kuan
4524cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        // Build up the contact entries
4534cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        buildEntries();
4544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
455938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        // Collapse similar data items for select {@link DataKind}s.
4564cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        Collapser.collapseList(mPhoneEntries);
4574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        Collapser.collapseList(mSmsEntries);
4584cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        Collapser.collapseList(mEmailEntries);
4594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        Collapser.collapseList(mPostalEntries);
4604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        Collapser.collapseList(mImEntries);
461f2cba50b052f4f6ea748d9c90753ef7ed3ec55c8Chiao Cheng        Collapser.collapseList(mEventEntries);
4624cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
463826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        mIsUniqueNumber = mPhoneEntries.size() == 1;
464826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        mIsUniqueEmail = mEmailEntries.size() == 1;
465826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro
466938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        // Make one aggregated list of all entries for display to the user.
467f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        setupFlattenedList();
468938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
4694cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        if (mAdapter == null) {
470cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            mAdapter = new ViewAdapter();
4714cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            mListView.setAdapter(mAdapter);
4724cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
473db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan
474db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        // Restore {@link ListView} state if applicable because the adapter is now populated.
475db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        if (mListState != null) {
476db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan            mListView.onRestoreInstanceState(mListState);
477db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan            mListState = null;
478db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        }
479db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan
480db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan        mAdapter.notifyDataSetChanged();
481db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan
4824cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        mListView.setEmptyView(mEmptyView);
48302cd4911cf69cf21a2cf612cf954f418a46f6a28Dmitri Plotnikov
4847ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        configureQuickFix();
4857ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
4867ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        mView.setVisibility(View.VISIBLE);
4877ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    }
4887ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
4897ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    /*
4907ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     * Sets {@link #mQuickFix} to a useful action and configures the visibility of
4917ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     * {@link #mQuickFixButton}
4927ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     */
4937ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private void configureQuickFix() {
4947ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        mQuickFix = null;
4957ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
4967ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        for (QuickFix fix : mPotentialQuickFixes) {
4977ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (fix.isApplicable()) {
4987ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                mQuickFix = fix;
4997ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                break;
50018db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann            }
5017ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
5027ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
5037ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        // Configure the button
5047ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        if (mQuickFix == null) {
5057ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            mQuickFixButton.setVisibility(View.GONE);
50618db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann        } else {
5077ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            mQuickFixButton.setVisibility(View.VISIBLE);
5087ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            mQuickFixButton.setText(mQuickFix.getTitle());
50918db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann        }
5107ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    }
51118db43d1aafdd565978f81c9462a90b86258cdc6Daniel Lehmann
5127ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    /** @return default group id or -1 if no group or several groups are marked as default */
5137ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private long getDefaultGroupId(List<GroupMetaData> groups) {
5147ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        long defaultGroupId = -1;
5157ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        for (GroupMetaData group : groups) {
5167ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (group.isDefaultGroup()) {
5177ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                // two default groups? return neither
5187ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                if (defaultGroupId != -1) return -1;
5197ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                defaultGroupId = group.getGroupId();
5207ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            }
5217ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
5227ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        return defaultGroupId;
5234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
5244cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5254cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    /**
5264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     * Build up the entries to display on the screen.
5274cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     */
5284cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    private final void buildEntries() {
5297779f490ccc2af98b5cd2cd537d1bdb36e173c94Daniel Lehmann        mHasPhone = PhoneCapabilityTester.isPhone(mContext);
530f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann        mHasSms = PhoneCapabilityTester.isSmsIntentRegistered(mContext);
5317781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann        mHasSip = PhoneCapabilityTester.isSipPhone(mContext);
532f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann
5334cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        // Clear out the old entries
534938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        mAllEntries.clear();
5354cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5364cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        mPrimaryPhoneUri = null;
5374cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5384cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        // Build up method entries
5394cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        if (mContactData == null) {
5404cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            return;
5414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
5424cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5432deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        ArrayList<String> groups = new ArrayList<String>();
544851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        for (RawContact rawContact: mContactData.getRawContacts()) {
545851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final long rawContactId = rawContact.getId();
546851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            for (DataItem dataItem : rawContact.getDataItems()) {
547851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                dataItem.setRawContactId(rawContactId);
5484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
549851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (dataItem.getMimeType() == null) continue;
5504cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
551851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (dataItem instanceof GroupMembershipDataItem) {
552851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    GroupMembershipDataItem groupMembership =
553851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                            (GroupMembershipDataItem) dataItem;
554851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    Long groupId = groupMembership.getGroupRowId();
5552deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    if (groupId != null) {
5562deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                        handleGroupMembership(groups, mContactData.getGroupMetaData(), groupId);
5572deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    }
5582deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    continue;
5592deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                }
5602deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov
561851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                final DataKind kind = dataItem.getDataKind();
5624cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                if (kind == null) continue;
5634cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
564851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, dataItem,
565851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
56630c130305cb8871e99767981270557c4b62474cbJosh Gargus                entry.maxLines = kind.maxLinesForDisplay;
5674cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5684cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                final boolean hasData = !TextUtils.isEmpty(entry.data);
569851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                final boolean isSuperPrimary = dataItem.isSuperPrimary();
5704cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
571851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (dataItem instanceof StructuredNameDataItem) {
572cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann                    // Always ignore the name. It is shown in the header if set
573851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof PhoneDataItem && hasData) {
574851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    PhoneDataItem phone = (PhoneDataItem) dataItem;
5754cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build phone entries
57610bf684e0c9022d80b04d9cc69665c6341677beaMaurice Chu                    entry.data = phone.getFormattedPhoneNumber();
577fadd5e1f1845b8d98e247bbd30535928dc5e0f81Daisuke Miyakawa                    final Intent phoneIntent = mHasPhone ?
578fadd5e1f1845b8d98e247bbd30535928dc5e0f81Daisuke Miyakawa                            ContactsUtils.getCallIntent(entry.data) : null;
579f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    final Intent smsIntent = mHasSms ? new Intent(Intent.ACTION_SENDTO,
580f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                            Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null)) : null;
581f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann
582ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                    // Configure Icons and Intents.
583f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    if (mHasPhone && mHasSms) {
584f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.intent = phoneIntent;
585f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.secondaryIntent = smsIntent;
586f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.secondaryActionIcon = kind.iconAltRes;
587ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                        entry.secondaryActionDescription = kind.iconAltDescriptionRes;
588f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    } else if (mHasPhone) {
589f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.intent = phoneIntent;
590f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    } else if (mHasSms) {
591f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.intent = smsIntent;
592f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    } else {
593f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                        entry.intent = null;
594f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann                    }
595f77b8e994f512e3d75d3169198183fde482614d8Daniel Lehmann
5964cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Remember super-primary phone
5974cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    if (isSuperPrimary) mPrimaryPhoneUri = entry.uri;
5984cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
5994cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    entry.isPrimary = isSuperPrimary;
6008a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu
6018a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    // If the entry is a primary entry, then render it first in the view.
6028a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    if (entry.isPrimary) {
6038a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        // add to beginning of list so that this phone number shows up first
6048a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        mPhoneEntries.add(0, entry);
6058a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    } else {
6068a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        // add to end of list
6078a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        mPhoneEntries.add(entry);
6088a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    }
609851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof EmailDataItem && hasData) {
6104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build email entries
6114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    entry.intent = new Intent(Intent.ACTION_SENDTO,
6124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                            Uri.fromParts(Constants.SCHEME_MAILTO, entry.data, null));
6134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    entry.isPrimary = isSuperPrimary;
6148a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    // If entry is a primary entry, then render it first in the view.
6158a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    if (entry.isPrimary) {
6168a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        mEmailEntries.add(0, entry);
6178a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    } else {
6188a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                        mEmailEntries.add(entry);
6198a0dd0f08ab11e9c6dad386e4411aeeb4c0cd73fMaurice Chu                    }
6204cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
6214cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // When Email rows have status, create additional Im row
6224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    final DataStatus status = mContactData.getStatuses().get(entry.id);
6234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    if (status != null) {
624851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        EmailDataItem email = (EmailDataItem) dataItem;
625851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        ImDataItem im = ImDataItem.createFromEmail(email);
626851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu
627851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        final DetailViewEntry imEntry = DetailViewEntry.fromValues(mContext, im,
628851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                                mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
629851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        buildImActions(mContext, imEntry, im);
6309daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann                        imEntry.setPresence(status.getPresence());
631851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        imEntry.maxLines = kind.maxLinesForDisplay;
6324cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        mImEntries.add(imEntry);
6334cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
634851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof StructuredPostalDataItem && hasData) {
6354cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build postal entries
636bfb59d8edce8c5604915a6e2ec288ad0becc7c7dMakoto Onuki                    entry.intent = StructuredPostalUtils.getViewPostalAddressIntent(entry.data);
6374cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    mPostalEntries.add(entry);
638851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof ImDataItem && hasData) {
6394cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build IM entries
640851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    buildImActions(mContext, entry, (ImDataItem) dataItem);
6414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
6429daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann                    // Apply presence when available
6434cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    final DataStatus status = mContactData.getStatuses().get(entry.id);
6444cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    if (status != null) {
6459daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann                        entry.setPresence(status.getPresence());
6464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
6474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    mImEntries.add(entry);
648851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof OrganizationDataItem) {
6491ad4d1ba1dcc473e1591e049da417dea009a33d6Daniel Lehmann                    // Organizations are not shown. The first one is shown in the header
6501ad4d1ba1dcc473e1591e049da417dea009a33d6Daniel Lehmann                    // and subsequent ones are not supported anymore
651851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof NicknameDataItem && hasData) {
6524cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build nickname entries
6534cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    final boolean isNameRawContact =
6544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        (mContactData.getNameRawContactId() == rawContactId);
6554cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
6564cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    final boolean duplicatesTitle =
6574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        isNameRawContact
6584cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        && mContactData.getDisplayNameSource() == DisplayNameSources.NICKNAME;
6594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
6604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    if (!duplicatesTitle) {
6614cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        entry.uri = null;
6624cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        mNicknameEntries.add(entry);
6634cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
664851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof NoteDataItem && hasData) {
6654cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Build note entries
6664cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    entry.uri = null;
667938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    mNoteEntries.add(entry);
668851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof WebsiteDataItem && hasData) {
6694423ca5a213476ddef361062f4252cdf2cf40bd8David Brown                    // Build Website entries
6704cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    entry.uri = null;
6714cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    try {
6724cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        WebAddress webAddress = new WebAddress(entry.data);
6734cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        entry.intent = new Intent(Intent.ACTION_VIEW,
6744cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                                Uri.parse(webAddress.toString()));
6754cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    } catch (ParseException e) {
6764cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        Log.e(TAG, "Couldn't parse website: " + entry.data);
6774cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
678938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    mWebsiteEntries.add(entry);
679851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof SipAddressDataItem && hasData) {
6804423ca5a213476ddef361062f4252cdf2cf40bd8David Brown                    // Build SipAddress entries
6814423ca5a213476ddef361062f4252cdf2cf40bd8David Brown                    entry.uri = null;
6827781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann                    if (mHasSip) {
683fadd5e1f1845b8d98e247bbd30535928dc5e0f81Daisuke Miyakawa                        entry.intent = ContactsUtils.getCallIntent(
6847781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann                                Uri.fromParts(Constants.SCHEME_SIP, entry.data, null));
6857781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann                    } else {
6867781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann                        entry.intent = null;
6877781ea12308e5c5d7bbeab175c31cc6cf1f19188Daniel Lehmann                    }
688938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    mSipEntries.add(entry);
689938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    // TODO: Now that SipAddress is in its own list of entries
690938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    // (instead of grouped in mOtherEntries), consider
691938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    // repositioning it right under the phone number.
69235769b804fbfd5a1fc0b2c36cd0a786d662c4334Daniel Lehmann                    // (Then, we'd also update FallbackAccountType.java to set
6934423ca5a213476ddef361062f4252cdf2cf40bd8David Brown                    // secondary=false for this field, and tweak the weight
6944423ca5a213476ddef361062f4252cdf2cf40bd8David Brown                    // of its DataKind.)
695851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof EventDataItem && hasData) {
69645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov                    entry.data = DateUtils.formatDate(mContext, entry.data);
69745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov                    entry.uri = null;
698938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    mEventEntries.add(entry);
699851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                } else if (dataItem instanceof RelationDataItem && hasData) {
7000edd4071ddcb23bf2a7b95582df0657de9ff0c60Dmitri Plotnikov                    entry.intent = new Intent(Intent.ACTION_SEARCH);
7010edd4071ddcb23bf2a7b95582df0657de9ff0c60Dmitri Plotnikov                    entry.intent.putExtra(SearchManager.QUERY, entry.data);
7020edd4071ddcb23bf2a7b95582df0657de9ff0c60Dmitri Plotnikov                    entry.intent.setType(Contacts.CONTENT_TYPE);
7030540f8b74a44f5d1da519cc54e598d75f0e572ddDaniel Lehmann                    mRelationEntries.add(entry);
7044cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                } else {
7054cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Handle showing custom rows
7069eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov                    entry.intent = new Intent(Intent.ACTION_VIEW);
7079eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov                    entry.intent.setDataAndType(entry.uri, entry.mimetype);
7084cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
709851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    entry.data = dataItem.buildDataString();
7104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
7110892205dd87cd85ea32db0f707dfcf73c73f176fKatherine Kuan                    if (!TextUtils.isEmpty(entry.data)) {
712515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        // If the account type exists in the hash map, add it as another entry for
713515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        // that account type
714851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                        AccountType type = dataItem.getAccountType();
715515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        if (mOtherEntriesMap.containsKey(type)) {
716515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            List<DetailViewEntry> listEntries = mOtherEntriesMap.get(type);
717515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            listEntries.add(entry);
718515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        } else {
719515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            // Otherwise create a new list with the entry and add it to the hash map
720515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            List<DetailViewEntry> listEntries = new ArrayList<DetailViewEntry>();
721515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            listEntries.add(entry);
722515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                            mOtherEntriesMap.put(type, listEntries);
723515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        }
7244cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
7254cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                }
7264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
7274cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
7282deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov
7292deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        if (!groups.isEmpty()) {
730938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            DetailViewEntry entry = new DetailViewEntry();
7312deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            Collections.sort(groups);
7322deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            StringBuilder sb = new StringBuilder();
7332deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            int size = groups.size();
7342deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            for (int i = 0; i < size; i++) {
7352deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                if (i != 0) {
7362deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    sb.append(", ");
7372deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                }
7382deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                sb.append(groups.get(i));
7392deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            }
7402deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            entry.mimetype = GroupMembership.MIMETYPE;
741ba3c2e541b17bc68ff86ed402e7ee2c0a84f7d80Dmitri Plotnikov            entry.kind = mContext.getString(R.string.groupsLabel);
7422deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            entry.data = sb.toString();
7432deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            mGroupEntries.add(entry);
7442deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        }
7452deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov    }
7462deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov
7472deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov    /**
748938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * Collapse all contact detail entries into one aggregated list with a {@link HeaderViewEntry}
749938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * at the top.
750938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     */
751f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private void setupFlattenedList() {
752938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        // All contacts should have a header view (even if there is no data for the contact).
753938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        mAllEntries.add(new HeaderViewEntry());
754938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
755f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        addPhoneticName();
756f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
757938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mPhoneEntries);
758938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mSmsEntries);
759938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mEmailEntries);
760938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mImEntries);
761938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mNicknameEntries);
762938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mWebsiteEntries);
763f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
764f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        addNetworks();
765f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
766938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mSipEntries);
767f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        flattenList(mPostalEntries);
768938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mEventEntries);
769938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        flattenList(mGroupEntries);
770f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        flattenList(mRelationEntries);
771f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        flattenList(mNoteEntries);
772f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    }
773f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
774f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    /**
775f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * Add phonetic name (if applicable) to the aggregated list of contact details. This has to be
776f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * done manually because phonetic name doesn't have a mimetype or action intent.
777f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     */
778f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private void addPhoneticName() {
779f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        String phoneticName = ContactDetailDisplayUtils.getPhoneticName(mContext, mContactData);
780f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        if (TextUtils.isEmpty(phoneticName)) {
781f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            return;
782f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
783f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
784f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add a title
785f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        String phoneticNameKindTitle = mContext.getString(R.string.name_phonetic);
786f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        mAllEntries.add(new KindTitleViewEntry(phoneticNameKindTitle.toUpperCase()));
787f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
788f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add the phonetic name
789f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        final DetailViewEntry entry = new DetailViewEntry();
790f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        entry.kind = phoneticNameKindTitle;
791f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        entry.data = phoneticName;
792f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        mAllEntries.add(entry);
793f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    }
794f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
795f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    /**
796f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * Add attribution and other third-party entries (if applicable) under the "networks" section
797f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * of the aggregated list of contact details. This has to be done manually because the
798f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * attribution does not have a mimetype and the third-party entries don't have actually belong
799f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * to the same {@link DataKind}.
800f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     */
801f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private void addNetworks() {
802f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        String attribution = ContactDetailDisplayUtils.getAttribution(mContext, mContactData);
803f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        boolean hasAttribution = !TextUtils.isEmpty(attribution);
804515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        int networksCount = mOtherEntriesMap.keySet().size();
805870a87e85e405ab469d61f11f24663219f3972b6Makoto Onuki
806870a87e85e405ab469d61f11f24663219f3972b6Makoto Onuki        // Note: invitableCount will always be 0 for me profile.  (ContactLoader won't set
807870a87e85e405ab469d61f11f24663219f3972b6Makoto Onuki        // invitable types for me profile.)
8082b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        int invitableCount = mContactData.getInvitableAccountTypes().size();
8093e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        if (!hasAttribution && networksCount == 0 && invitableCount == 0) {
810f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            return;
811f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
812f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
813f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add a title
8141ba8b6fea4c3f82ded19305874e72a326612aed1Katherine Kuan        String networkKindTitle = mContext.getString(R.string.connections);
815f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        mAllEntries.add(new KindTitleViewEntry(networkKindTitle.toUpperCase()));
816f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
817f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add the attribution if applicable
818f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        if (hasAttribution) {
819f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            final DetailViewEntry entry = new DetailViewEntry();
820f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            entry.kind = networkKindTitle;
821f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            entry.data = attribution;
822f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            mAllEntries.add(entry);
823515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
824515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            // Add a divider below the attribution if there are network details that will follow
825515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            if (networksCount > 0) {
826515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                mAllEntries.add(new SeparatorViewEntry());
827515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            }
828f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
829f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
830f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add the other entries from third parties
831515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        for (AccountType accountType : mOtherEntriesMap.keySet()) {
832515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
833515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            // Add a title for each third party app
83460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            mAllEntries.add(new NetworkTitleViewEntry(mContext, accountType));
835515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
836515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            for (DetailViewEntry detailEntry : mOtherEntriesMap.get(accountType)) {
837515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                // Add indented separator
838515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                SeparatorViewEntry separatorEntry = new SeparatorViewEntry();
839515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                separatorEntry.setIsInSubSection(true);
840515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                mAllEntries.add(separatorEntry);
841515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
842515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                // Add indented detail
843515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                detailEntry.setIsInSubSection(true);
844515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                mAllEntries.add(detailEntry);
845f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            }
846f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
847f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
848515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        mOtherEntriesMap.clear();
8493e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8503e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // Add the "More networks" button, which opens the invitable account type list popup.
8513e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        if (invitableCount > 0) {
8523e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            addMoreNetworks();
8533e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
8543e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    }
8553e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8563e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    /**
8573e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     * Add the "More networks" entry.  When clicked, show a popup containing a list of invitable
8583e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     * account types.
8593e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     */
8603e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    private void addMoreNetworks() {
8613e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // First, prepare for the popup.
8623e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8633e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // Adapter for the list popup.
8643e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        final InvitableAccountTypesAdapter popupAdapter = new InvitableAccountTypesAdapter(mContext,
8653e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                mContactData);
8663e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8673e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // Listener called when a popup item is clicked.
8683e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        final AdapterView.OnItemClickListener popupItemListener
8693e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                = new AdapterView.OnItemClickListener() {
8703e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            @Override
8713e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            public void onItemClick(AdapterView<?> parent, View view, int position,
8723e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                    long id) {
87308bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan                if (mListener != null && mContactData != null) {
87408bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan                    mListener.onItemClicked(ContactsUtils.getInvitableIntent(
87508bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan                            popupAdapter.getItem(position) /* account type */,
87608bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan                            mContactData.getLookupUri()));
8773e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                }
8783e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            }
8793e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        };
8803e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8813e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // Then create the click listener for the "More network" entry.  Open the popup.
8823e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        View.OnClickListener onClickListener = new OnClickListener() {
8833e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            @Override
8843e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            public void onClick(View v) {
8853e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                showListPopup(v, popupAdapter, popupItemListener);
8863e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            }
8873e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        };
8883e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
8893e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // Finally create the entry.
89060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        mAllEntries.add(new AddConnectionViewEntry(mContext, onClickListener));
891938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    }
892938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
893938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    /**
894938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * Iterate through {@link DetailViewEntry} in the given list and add it to a list of all
895f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * entries. Add a {@link KindTitleViewEntry} at the start if the length of the list is not 0.
896f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * Add {@link SeparatorViewEntry}s as dividers as appropriate. Clear the original list.
897938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     */
898938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    private void flattenList(ArrayList<DetailViewEntry> entries) {
899938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        int count = entries.size();
900938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
901f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add a title for this kind by extracting the kind from the first entry
902f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        if (count > 0) {
903f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            String kind = entries.get(0).kind;
904f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            mAllEntries.add(new KindTitleViewEntry(kind.toUpperCase()));
905938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
906938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
907f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        // Add all the data entries for this kind
908f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        for (int i = 0; i < count; i++) {
909f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            // For all entries except the first one, add a divider above the entry
910f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            if (i != 0) {
911f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan                mAllEntries.add(new SeparatorViewEntry());
912f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            }
913f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            mAllEntries.add(entries.get(i));
914938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
915938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
916938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        // Clear old list because it's not needed anymore.
917938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        entries.clear();
918938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    }
919938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
920938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    /**
9212deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov     * Maps group ID to the corresponding group name, collapses all synonymous groups.
9222deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov     * Ignores default groups (e.g. My Contacts) and favorites groups.
9232deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov     */
9242deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov    private void handleGroupMembership(
925e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov            ArrayList<String> groups, List<GroupMetaData> groupMetaData, long groupId) {
9262deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        if (groupMetaData == null) {
9272deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            return;
9282deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        }
9292deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov
930e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov        for (GroupMetaData group : groupMetaData) {
9312deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            if (group.getGroupId() == groupId) {
9322deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                if (!group.isDefaultGroup() && !group.isFavorites()) {
9332deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    String title = group.getTitle();
93493a0025b87079e0d36431a2c096f96e145053a28Makoto Onuki                    if (!TextUtils.isEmpty(title) && !groups.contains(title)) {
9352deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                        groups.add(title);
9362deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                    }
9372deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                }
9382deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov                break;
9392deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov            }
9402deaee154c04cc9dddce2923085246984269b31aDmitri Plotnikov        }
9414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
9424cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
9434cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    /**
944cbc819134526286093eb6833385851e4d08fb2c2Daniel Lehmann     * Writes the Instant Messaging action into the given entry value.
945dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov     */
946cbc819134526286093eb6833385851e4d08fb2c2Daniel Lehmann    @VisibleForTesting
947cbc819134526286093eb6833385851e4d08fb2c2Daniel Lehmann    public static void buildImActions(Context context, DetailViewEntry entry,
948851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            ImDataItem im) {
949851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        final boolean isEmail = im.isCreatedFromEmail();
950dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
951851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        if (!isEmail && !im.isProtocolValid()) {
952dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            return;
953dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        }
954dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
955851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        final String data = im.getData();
956dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        if (TextUtils.isEmpty(data)) {
957dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            return;
958dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        }
959dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
960851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : im.getProtocol();
961dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
962dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        if (protocol == Im.PROTOCOL_GOOGLE_TALK) {
963851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final int chatCapability = im.getChatCapability();
964dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            entry.chatCapability = chatCapability;
965cbc819134526286093eb6833385851e4d08fb2c2Daniel Lehmann            entry.typeString = Im.getProtocolLabel(context.getResources(), Im.PROTOCOL_GOOGLE_TALK,
966cbc819134526286093eb6833385851e4d08fb2c2Daniel Lehmann                    null).toString();
967dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
968dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.intent =
969dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
970dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.secondaryIntent =
971dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
972dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            } else if ((chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
973dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                // Allow Talking and Texting
974dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.intent =
975dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
976dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.secondaryIntent =
977dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
978dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            } else {
979dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.intent =
980dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
981dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            }
982dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        } else {
983dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            // Build an IM Intent
984851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            String host = im.getCustomProtocol();
985dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
986dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            if (protocol != Im.PROTOCOL_CUSTOM) {
987dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                // Try bringing in a well-known host for specific protocols
988dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                host = ContactsUtils.lookupProviderNameFromId(protocol);
989dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            }
990dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
991dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            if (!TextUtils.isEmpty(host)) {
992dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                final String authority = host.toLowerCase();
993dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
994dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                        authority).appendPath(data).build();
995dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov                entry.intent = new Intent(Intent.ACTION_SENDTO, imUri);
996dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov            }
997dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        }
998dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov    }
999dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
1000dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov    /**
10013e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     * Show a list popup.  Used for "popup-able" entry, such as "More networks".
10023e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     */
10033e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    private void showListPopup(View anchorView, ListAdapter adapter,
10043e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final AdapterView.OnItemClickListener onItemClickListener) {
10051adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        dismissPopupIfShown();
10061adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup = new ListPopupWindow(mContext, null);
10071adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.setAnchorView(anchorView);
10081adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.setWidth(anchorView.getWidth());
10091adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.setAdapter(adapter);
10101adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.setModal(true);
10113e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
10123e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // We need to wrap the passed onItemClickListener here, so that we can dismiss() the
10133e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        // popup afterwards.  Otherwise we could directly use the passed listener.
10141adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
10153e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            @Override
10163e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            public void onItemClick(AdapterView<?> parent, View view, int position,
10173e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                    long id) {
10183e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                onItemClickListener.onItemClick(parent, view, position, id);
10191adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki                dismissPopupIfShown();
10203e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            }
10213e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        });
10221adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup.show();
10231adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki    }
10241adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki
10251adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki    private void dismissPopupIfShown() {
10261adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        if (mPopup != null && mPopup.isShowing()) {
10271adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki            mPopup.dismiss();
10281adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        }
10291adc29d847af0e217b13ce707bb806cfc86e3ae2Makoto Onuki        mPopup = null;
10303e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    }
10313e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
10323e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    /**
1033938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * Base class for an item in the {@link ViewAdapter} list of data, which is
1034938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * supplied to the {@link ListView}.
1035938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     */
1036938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    static class ViewEntry {
1037938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        private final int viewTypeForAdapter;
1038938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        protected long id = -1;
1039938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        /** Whether or not the entry can be focused on or not. */
1040938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        protected boolean isEnabled = false;
1041938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1042938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        ViewEntry(int viewType) {
1043938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            viewTypeForAdapter = viewType;
1044938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1045938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1046938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        int getViewType() {
1047938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return viewTypeForAdapter;
1048938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1049938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1050938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        long getId() {
1051938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return id;
1052938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1053938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1054938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        boolean isEnabled(){
1055938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return isEnabled;
1056938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
10573e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
10583e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        /**
10593e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         * Called when the entry is clicked.  Only {@link #isEnabled} entries can get clicked.
10603e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         *
10613e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         * @param clickedView  {@link View} that was clicked  (Used, for example, as the anchor view
10623e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         *        for a popup.)
10633e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         * @param fragmentListener  {@link Listener} set to {@link ContactDetailFragment}
10643e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki         */
10653e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public void click(View clickedView, Listener fragmentListener) {
10663e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
1067938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    }
1068938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1069938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    /**
1070938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * Header item in the {@link ViewAdapter} list of data.
10714cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann     */
1072f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private static class HeaderViewEntry extends ViewEntry {
1073938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1074938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        HeaderViewEntry() {
1075938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            super(ViewAdapter.VIEW_TYPE_HEADER_ENTRY);
1076938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1077938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1078938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    }
1079938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1080938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    /**
1081938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * Separator between items of the same {@link DataKind} in the
1082938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * {@link ViewAdapter} list of data.
1083938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     */
1084f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private static class SeparatorViewEntry extends ViewEntry {
1085938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1086515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        /**
1087515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan         * Whether or not the entry is in a subsection (if true then the contents will be indented
1088515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan         * to the right)
1089515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan         */
1090515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private boolean mIsInSubSection = false;
1091515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1092938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        SeparatorViewEntry() {
1093938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            super(ViewAdapter.VIEW_TYPE_SEPARATOR_ENTRY);
1094938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1095938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1096515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public void setIsInSubSection(boolean isInSubSection) {
1097515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mIsInSubSection = isInSubSection;
1098515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1099515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1100515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public boolean isInSubSection() {
1101515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mIsInSubSection;
1102515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1103938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    }
1104938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1105938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    /**
1106f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * Title entry for items of the same {@link DataKind} in the
1107f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     * {@link ViewAdapter} list of data.
1108f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan     */
1109f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    private static class KindTitleViewEntry extends ViewEntry {
1110f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1111515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final String mTitle;
1112f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1113f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        KindTitleViewEntry(String titleText) {
1114f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            super(ViewAdapter.VIEW_TYPE_KIND_TITLE_ENTRY);
1115515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mTitle = titleText;
1116f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
1117f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1118515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public String getTitle() {
1119515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mTitle;
1120515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1121515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    }
1122515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1123515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    /**
112460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu     * A title for a section of contact details from a single 3rd party network.
1125515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     */
1126515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private static class NetworkTitleViewEntry extends ViewEntry {
11273e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        private final Drawable mIcon;
11283e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        private final CharSequence mLabel;
1129515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
113060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public NetworkTitleViewEntry(Context context, AccountType type) {
1131515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            super(ViewAdapter.VIEW_TYPE_NETWORK_TITLE_ENTRY);
113260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.mIcon = type.getDisplayIcon(context);
113360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.mLabel = type.getDisplayLabel(context);
11348e683e8ef2f27140a94f6c41ea83d8889097522fFlavio Lerda            this.isEnabled = false;
11353e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
11363e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
113760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public Drawable getIcon() {
113860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            return mIcon;
11393e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
11403e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
114160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public CharSequence getLabel() {
114260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            return mLabel;
114360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        }
114460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    }
114560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
114660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    /**
114760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu     * This is used for the "Add Connections" entry.
114860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu     */
114960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    private static class AddConnectionViewEntry extends ViewEntry {
115060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private final Drawable mIcon;
115160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private final CharSequence mLabel;
115260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private final View.OnClickListener mOnClickListener;
115360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
115460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private AddConnectionViewEntry(Context context, View.OnClickListener onClickListener) {
115560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            super(ViewAdapter.VIEW_TYPE_ADD_CONNECTION_ENTRY);
115660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.mIcon = context.getResources().getDrawable(
115760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                    R.drawable.ic_menu_add_field_holo_light);
115860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.mLabel = context.getString(R.string.add_connection_button);
115960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.mOnClickListener = onClickListener;
116060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            this.isEnabled = true;
11613e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
11623e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
11633e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
11643e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public void click(View clickedView, Listener fragmentListener) {
11653e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            if (mOnClickListener == null) return;
11663e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            mOnClickListener.onClick(clickedView);
1167515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1168515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
11693e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public Drawable getIcon() {
11703e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return mIcon;
11713e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
11723e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
11733e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public CharSequence getLabel() {
11743e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return mLabel;
1175515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1176f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    }
1177f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1178f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan    /**
1179938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * An item with a single detail for a contact in the {@link ViewAdapter}
1180938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     * list of data.
1181938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan     */
1182938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan    static class DetailViewEntry extends ViewEntry implements Collapsible<DetailViewEntry> {
1183515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        // TODO: Make getters/setters for these fields
1184cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public int type = -1;
11850f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann        public String kind;
11860f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann        public String typeString;
1187cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public String data;
1188cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public Uri uri;
1189cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public int maxLines = 1;
1190cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public String mimetype;
1191cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
11924cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public Context context = null;
11934cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public boolean isPrimary = false;
11944cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public int secondaryActionIcon = -1;
1195ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan        public int secondaryActionDescription = -1;
11964cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public Intent intent;
11974cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public Intent secondaryIntent = null;
11984cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public ArrayList<Long> ids = new ArrayList<Long>();
11994cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public int collapseCount = 0;
12004cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
12014cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public int presence = -1;
1202dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov        public int chatCapability = 0;
12034cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1204515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private boolean mIsInSubSection = false;
1205515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1206851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        @Override
1207851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        public String toString() {
1208851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            StringBuilder sb = new StringBuilder();
1209851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("== DetailViewEntry ==\n");
1210851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  type: " + type + "\n");
1211851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  kind: " + kind + "\n");
1212851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  typeString: " + typeString + "\n");
1213851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  data: " + data + "\n");
1214851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  uri: " + uri.toString() + "\n");
1215851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  maxLines: " + maxLines + "\n");
1216851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  mimetype: " + mimetype + "\n");
1217851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  isPrimary: " + (isPrimary ? "true" : "false") + "\n");
1218851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  secondaryActionIcon: " + secondaryActionIcon + "\n");
1219851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  secondaryActionDescription: " + secondaryActionDescription + "\n");
1220851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (intent == null) {
1221851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                sb.append("  intent: " + intent.toString() + "\n");
1222851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            } else {
1223851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                sb.append("  intent: " + intent.toString() + "\n");
1224851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            }
1225851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (secondaryIntent == null) {
1226851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                sb.append("  secondaryIntent: (null)\n");
1227851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            } else {
1228851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                sb.append("  secondaryIntent: " + secondaryIntent.toString() + "\n");
1229851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            }
1230851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  ids: " + Iterables.toString(ids) + "\n");
1231851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  collapseCount: " + collapseCount + "\n");
1232851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  presence: " + presence + "\n");
1233851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  chatCapability: " + chatCapability + "\n");
1234851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            sb.append("  mIsInSubsection: " + (mIsInSubSection ? "true" : "false") + "\n");
1235851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            return sb.toString();
1236851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        }
1237851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu
1238938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        DetailViewEntry() {
1239938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            super(ViewAdapter.VIEW_TYPE_DETAIL_ENTRY);
1240938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            isEnabled = true;
12414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
12424cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
12434cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        /**
1244938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan         * Build new {@link DetailViewEntry} and populate from the given values.
12454cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann         */
1246851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        public static DetailViewEntry fromValues(Context context, DataItem item,
1247851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                boolean isDirectoryEntry, long directoryId) {
1248938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            final DetailViewEntry entry = new DetailViewEntry();
1249851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            entry.id = item.getId();
1250938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            entry.context = context;
12514cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            entry.uri = ContentUris.withAppendedId(Data.CONTENT_URI, entry.id);
12529eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov            if (isDirectoryEntry) {
12539eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov                entry.uri = entry.uri.buildUpon().appendQueryParameter(
12549eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov                        ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
12559eda503de088811bbde2999050426cc8d3ebac63Dmitri Plotnikov            }
1256851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            entry.mimetype = item.getMimeType();
1257851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            entry.kind = item.getKindString();
1258851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            entry.data = item.buildDataString();
12594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1260851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (item.hasKindTypeColumn()) {
1261851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                entry.type = item.getKindTypeColumn();
12620f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann
12630f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                // get type string
12640f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                entry.typeString = "";
1265851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                for (EditType type : item.getDataKind().typeList) {
12660f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                    if (type.rawValue == entry.type) {
12672179037e606ef55fa2d6bfa009371eaa522906f1Daniel Lehmann                        if (type.customColumn == null) {
12682179037e606ef55fa2d6bfa009371eaa522906f1Daniel Lehmann                            // Non-custom type. Get its description from the resource
12692179037e606ef55fa2d6bfa009371eaa522906f1Daniel Lehmann                            entry.typeString = context.getString(type.labelRes);
12702179037e606ef55fa2d6bfa009371eaa522906f1Daniel Lehmann                        } else {
12712179037e606ef55fa2d6bfa009371eaa522906f1Daniel Lehmann                            // Custom type. Read it from the database
1272851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                            entry.typeString =
1273851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                                    item.getContentValues().getAsString(type.customColumn);
12740f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                        }
12750f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                        break;
12760f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                    }
12770f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                }
12780f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann            } else {
12790f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                entry.typeString = "";
12804cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
12810f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann
12824cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            return entry;
12834cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
12844cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
12859daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann        public void setPresence(int presence) {
12869daca14706f3699c9e9d46dfb522132fc566e57eDaniel Lehmann            this.presence = presence;
12874cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
12884cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1289515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public void setIsInSubSection(boolean isInSubSection) {
1290515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mIsInSubSection = isInSubSection;
1291515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1292515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1293515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public boolean isInSubSection() {
1294515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mIsInSubSection;
1295515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1296515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
12971624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
1298938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public boolean collapseWith(DetailViewEntry entry) {
12994cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // assert equal collapse keys
13004cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (!shouldCollapseWith(entry)) {
13014cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                return false;
13024cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13034cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13044cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Choose the label associated with the highest type precedence.
13054cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (TypePrecedence.getTypePrecedence(mimetype, type)
13064cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    > TypePrecedence.getTypePrecedence(entry.mimetype, entry.type)) {
13074cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                type = entry.type;
13080f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                kind = entry.kind;
13090f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                typeString = entry.typeString;
13104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Choose the max of the maxLines and maxLabelLines values.
13134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            maxLines = Math.max(maxLines, entry.maxLines);
13144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Choose the presence with the highest precedence.
13164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (StatusUpdates.getPresencePrecedence(presence)
13174cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    < StatusUpdates.getPresencePrecedence(entry.presence)) {
13184cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                presence = entry.presence;
13194cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13204cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13214cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // If any of the collapsed entries are primary make the whole thing primary.
13224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            isPrimary = entry.isPrimary ? true : isPrimary;
13234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13244cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // uri, and contactdId, shouldn't make a difference. Just keep the original.
13254cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Keep track of all the ids that have been collapsed with this one.
1327938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            ids.add(entry.getId());
13284cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            collapseCount++;
13294cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            return true;
13304cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
13314cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13321624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
1333938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public boolean shouldCollapseWith(DetailViewEntry entry) {
13344cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (entry == null) {
13354cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                return false;
13364cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13374cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
133801a9fac7bd963d29c607cb17d579b68a71aa8854Dave Santoro            if (!ContactsUtils.shouldCollapse(mimetype, data, entry.mimetype, entry.data)) {
13394cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                return false;
13404cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13424cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (!TextUtils.equals(mimetype, entry.mimetype)
13434cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    || !ContactsUtils.areIntentActionEqual(intent, entry.intent)
1344ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                    || !ContactsUtils.areIntentActionEqual(
1345ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                            secondaryIntent, entry.secondaryIntent)) {
13464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                return false;
13474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
13484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
13494cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            return true;
13504cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
13513e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
13523e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
13533e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public void click(View clickedView, Listener fragmentListener) {
13543e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            if (fragmentListener == null || intent == null) return;
13553e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            fragmentListener.onItemClicked(intent);
13563e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
13574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
13584cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1359515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    /**
1360d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan     * Cache of the children views for a view that displays a header view entry.
1361d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan     */
13627edad9dd95a411cc5ed69815e5f0be8a5d1e8b19Josh Gargus    private static class HeaderViewCache {
1363d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        public final TextView displayNameView;
1364d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        public final TextView companyView;
1365d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        public final ImageView photoView;
13666fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        public final View photoOverlayView;
1367c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann        public final ImageView starredView;
1368d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        public final int layoutResourceId;
1369d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan
1370d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        public HeaderViewCache(View view, int layoutResourceInflated) {
1371d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            displayNameView = (TextView) view.findViewById(R.id.name);
1372d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            companyView = (TextView) view.findViewById(R.id.company);
1373d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            photoView = (ImageView) view.findViewById(R.id.photo);
13746fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            photoOverlayView = view.findViewById(R.id.photo_touch_intercept_overlay);
1375c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann            starredView = (ImageView) view.findViewById(R.id.star);
1376d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            layoutResourceId = layoutResourceInflated;
1377d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan        }
13786fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro
13797edad9dd95a411cc5ed69815e5f0be8a5d1e8b19Josh Gargus        public void enablePhotoOverlay(OnClickListener listener) {
138084edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus            if (photoOverlayView != null) {
138184edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                photoOverlayView.setOnClickListener(listener);
13826fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro                photoOverlayView.setVisibility(View.VISIBLE);
13836fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro            }
13846fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro        }
1385d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan    }
1386d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan
138760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    private static class KindTitleViewCache {
138860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public final TextView titleView;
138960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
139060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public KindTitleViewCache(View view) {
139160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            titleView = (TextView)view.findViewById(R.id.title);
139260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        }
139360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    }
139460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
1395d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan    /**
1396515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * Cache of the children views for a view that displays a {@link NetworkTitleViewEntry}
1397515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     */
1398515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private static class NetworkTitleViewCache {
1399515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public final TextView name;
1400515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public final ImageView icon;
1401515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1402515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public NetworkTitleViewCache(View view) {
1403515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            name = (TextView) view.findViewById(R.id.network_title);
1404515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            icon = (ImageView) view.findViewById(R.id.network_icon);
1405515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1406515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    }
1407515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1408515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    /**
140960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu     * Cache of the children views for a view that displays a {@link AddConnectionViewEntry}
141060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu     */
141160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    private static class AddConnectionViewCache {
141260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public final TextView name;
141360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public final ImageView icon;
141460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public final View primaryActionView;
141560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
141660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public AddConnectionViewCache(View view) {
141760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            name = (TextView) view.findViewById(R.id.add_connection_label);
141860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            icon = (ImageView) view.findViewById(R.id.add_connection_icon);
141960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            primaryActionView = view.findViewById(R.id.primary_action_view);
142060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        }
142160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    }
142260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
142360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu    /**
1424515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * Cache of the children views of a contact detail entry represented by a
1425515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * {@link DetailViewEntry}
1426515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     */
1427515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private static class DetailViewCache {
142854eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final TextView type;
142954eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final TextView data;
143054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final ImageView presenceIcon;
143154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final ImageView secondaryActionButton;
143244d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda        public final View actionsViewContainer;
143344d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda        public final View primaryActionView;
143454eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final View secondaryActionViewContainer;
143554eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final View secondaryActionDivider;
143654eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public final View primaryIndicator;
143754eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
143854eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        public DetailViewCache(View view,
143954eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                OnClickListener primaryActionClickListener,
144054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                OnClickListener secondaryActionClickListener) {
1441515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            type = (TextView) view.findViewById(R.id.type);
1442515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            data = (TextView) view.findViewById(R.id.data);
1443627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            primaryIndicator = view.findViewById(R.id.primary_indicator);
1444515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
144554eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
144644d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            actionsViewContainer = view.findViewById(R.id.actions_view_container);
144744d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            actionsViewContainer.setOnClickListener(primaryActionClickListener);
144844d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            primaryActionView = view.findViewById(R.id.primary_action_view);
144954eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
145054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            secondaryActionViewContainer = view.findViewById(
145154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    R.id.secondary_action_view_container);
145254eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            secondaryActionViewContainer.setOnClickListener(
145354eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    secondaryActionClickListener);
1454515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            secondaryActionButton = (ImageView) view.findViewById(
1455515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    R.id.secondary_action_button);
145654eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
1457515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            secondaryActionDivider = view.findViewById(R.id.vertical_divider);
1458515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
14594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
14604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1461cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    private final class ViewAdapter extends BaseAdapter {
1462938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1463938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public static final int VIEW_TYPE_DETAIL_ENTRY = 0;
1464938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public static final int VIEW_TYPE_HEADER_ENTRY = 1;
1465f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        public static final int VIEW_TYPE_KIND_TITLE_ENTRY = 2;
1466515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public static final int VIEW_TYPE_NETWORK_TITLE_ENTRY = 3;
146760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public static final int VIEW_TYPE_ADD_CONNECTION_ENTRY = 4;
146860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        public static final int VIEW_TYPE_SEPARATOR_ENTRY = 5;
146960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private static final int VIEW_TYPE_COUNT = 6;
1470938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
14711624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
14724cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        public View getView(int position, View convertView, ViewGroup parent) {
1473938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            switch (getItemViewType(position)) {
1474938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                case VIEW_TYPE_HEADER_ENTRY:
1475938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    return getHeaderEntryView(convertView, parent);
1476938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                case VIEW_TYPE_SEPARATOR_ENTRY:
1477515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    return getSeparatorEntryView(position, convertView, parent);
1478f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan                case VIEW_TYPE_KIND_TITLE_ENTRY:
1479f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan                    return getKindTitleEntryView(position, convertView, parent);
1480938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                case VIEW_TYPE_DETAIL_ENTRY:
1481938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    return getDetailEntryView(position, convertView, parent);
1482515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                case VIEW_TYPE_NETWORK_TITLE_ENTRY:
1483515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    return getNetworkTitleEntryView(position, convertView, parent);
148460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                case VIEW_TYPE_ADD_CONNECTION_ENTRY:
148560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                    return getAddConnectionEntryView(position, convertView, parent);
1486938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                default:
1487938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    throw new IllegalStateException("Invalid view type ID " +
1488938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                            getItemViewType(position));
1489938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            }
1490938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1491938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1492938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        private View getHeaderEntryView(View convertView, ViewGroup parent) {
1493d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            final int desiredLayoutResourceId = mContactHasSocialUpdates ?
14949bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan                    R.layout.detail_header_contact_with_updates :
14959bd85b3ecd9129feb2f317784a3d8023aa211d42Katherine Kuan                    R.layout.detail_header_contact_without_updates;
1496d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            View result = null;
1497d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            HeaderViewCache viewCache = null;
1498d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan
1499d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            // Only use convertView if it has the same layout resource ID as the one desired
1500d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            // (the two can be different on wide 2-pane screens where the detail fragment is reused
1501d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            // for many different contacts that do and do not have social updates).
1502d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            if (convertView != null) {
1503d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                viewCache = (HeaderViewCache) convertView.getTag();
1504d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                if (viewCache.layoutResourceId == desiredLayoutResourceId) {
1505d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                    result = convertView;
1506d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                }
1507d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            }
15082eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
1509d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            // Otherwise inflate a new header view and create a new view cache.
1510d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            if (result == null) {
1511d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                result = mInflater.inflate(desiredLayoutResourceId, parent, false);
1512d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                viewCache = new HeaderViewCache(result, desiredLayoutResourceId);
1513d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                result.setTag(viewCache);
1514d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            }
15152eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
1516d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            ContactDetailDisplayUtils.setDisplayName(mContext, mContactData,
1517d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                    viewCache.displayNameView);
1518d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            ContactDetailDisplayUtils.setCompanyName(mContext, mContactData, viewCache.companyView);
15192eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
15202eb969cc399d87b659a45568fa951d394c216917Katherine Kuan            // Set the photo if it should be displayed
1521d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            if (viewCache.photoView != null) {
15222d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                final boolean expandOnClick = mContactData.getPhotoUri() != null;
15232d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
15249758a92fac3e9f64892d893c992f6020d7fe3bfdJosh Gargus                        mContext, mContactData, viewCache.photoView, expandOnClick);
152584edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus
152684edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                if (expandOnClick || mContactData.isWritableContact(mContext)) {
15277edad9dd95a411cc5ed69815e5f0be8a5d1e8b19Josh Gargus                    viewCache.enablePhotoOverlay(listener);
152884edfd9a76657a653491faac53b5976adf9fd2cbJosh Gargus                }
15292eb969cc399d87b659a45568fa951d394c216917Katherine Kuan            }
15302eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
15312eb969cc399d87b659a45568fa951d394c216917Katherine Kuan            // Set the starred state if it should be displayed
1532c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann            final ImageView favoritesStar = viewCache.starredView;
1533d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            if (favoritesStar != null) {
1534c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                ContactDetailDisplayUtils.configureStarredImageView(favoritesStar,
1535c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                        mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
1536c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                        mContactData.getStarred());
15372eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                final Uri lookupUri = mContactData.getLookupUri();
1538d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan                favoritesStar.setOnClickListener(new OnClickListener() {
15392eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                    @Override
15402eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                    public void onClick(View v) {
15412eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                        // Toggle "starred" state
15422eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                        // Make sure there is a contact
15432eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                        if (lookupUri != null) {
1544c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // Read the current starred value from the UI instead of using the last
1545c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // loaded state. This allows rapid tapping without writing the same
1546c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // value several times
1547c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            final Object tag = favoritesStar.getTag();
1548c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            final boolean isStarred = tag == null
1549c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                                    ? false : (Boolean) favoritesStar.getTag();
1550c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann
1551c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // To improve responsiveness, swap out the picture (and tag) in the UI
1552c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // already
1553c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            ContactDetailDisplayUtils.configureStarredImageView(favoritesStar,
1554c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                                    mContactData.isDirectoryEntry(), mContactData.isUserProfile(),
1555c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                                    !isStarred);
1556c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann
1557c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                            // Now perform the real save
15582eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                            Intent intent = ContactSaveService.createSetStarredIntent(
1559c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann                                    getContext(), lookupUri, !isStarred);
15602eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                            getContext().startService(intent);
15612eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                        }
15622eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                    }
15632eb969cc399d87b659a45568fa951d394c216917Katherine Kuan                });
15642eb969cc399d87b659a45568fa951d394c216917Katherine Kuan            }
15652eb969cc399d87b659a45568fa951d394c216917Katherine Kuan
1566d69ed3875736f6ed56ea1e07f90da9d81b58a70fKatherine Kuan            return result;
1567938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1568938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1569515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private View getSeparatorEntryView(int position, View convertView, ViewGroup parent) {
1570515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final SeparatorViewEntry entry = (SeparatorViewEntry) getItem(position);
1571515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final View result = (convertView != null) ? convertView :
1572515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    mInflater.inflate(R.layout.contact_detail_separator_entry_view, parent, false);
1573515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1574515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            result.setPadding(entry.isInSubSection() ? mViewEntryDimensions.getWidePaddingLeft() :
1575515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    mViewEntryDimensions.getPaddingLeft(), 0,
1576515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    mViewEntryDimensions.getPaddingRight(), 0);
1577515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1578515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return result;
1579f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        }
1580f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1581f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan        private View getKindTitleEntryView(int position, View convertView, ViewGroup parent) {
1582f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            final KindTitleViewEntry entry = (KindTitleViewEntry) getItem(position);
158360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            final View result;
158460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            final KindTitleViewCache viewCache;
1585f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
158660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            if (convertView != null) {
158760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result = convertView;
158860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                viewCache = (KindTitleViewCache)result.getTag();
158960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            } else {
159060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result = mInflater.inflate(R.layout.list_separator, parent, false);
159160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                viewCache = new KindTitleViewCache(result);
159260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result.setTag(viewCache);
159360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            }
159460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
159560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            viewCache.titleView.setText(entry.getTitle());
1596515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1597515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return result;
1598515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
1599515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1600515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private View getNetworkTitleEntryView(int position, View convertView, ViewGroup parent) {
1601515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final NetworkTitleViewEntry entry = (NetworkTitleViewEntry) getItem(position);
1602515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final View result;
1603515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final NetworkTitleViewCache viewCache;
1604515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
1605515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            if (convertView != null) {
1606515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                result = convertView;
1607515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                viewCache = (NetworkTitleViewCache) result.getTag();
1608515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            } else {
1609515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                result = mInflater.inflate(R.layout.contact_detail_network_title_entry_view,
1610515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                        parent, false);
1611515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                viewCache = new NetworkTitleViewCache(result);
1612515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                result.setTag(viewCache);
1613515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            }
1614515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
16153e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            viewCache.name.setText(entry.getLabel());
16163e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            viewCache.icon.setImageDrawable(entry.getIcon());
1617f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan
1618f81e4c688d86d3905738d9d1caf934179e69304eKatherine Kuan            return result;
1619938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1620938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
162160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        private View getAddConnectionEntryView(int position, View convertView, ViewGroup parent) {
162260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            final AddConnectionViewEntry entry = (AddConnectionViewEntry) getItem(position);
162360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            final View result;
162460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            final AddConnectionViewCache viewCache;
162560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
162660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            if (convertView != null) {
162760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result = convertView;
162860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                viewCache = (AddConnectionViewCache) result.getTag();
162960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            } else {
163060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result = mInflater.inflate(R.layout.contact_detail_add_connection_entry_view,
163160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                        parent, false);
163260c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                viewCache = new AddConnectionViewCache(result);
163360c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu                result.setTag(viewCache);
163460c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            }
163560c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            viewCache.name.setText(entry.getLabel());
163660c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            viewCache.icon.setImageDrawable(entry.getIcon());
163760c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            viewCache.primaryActionView.setOnClickListener(entry.mOnClickListener);
163860c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
163960c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu            return result;
164060c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu        }
164160c6cbab97c7ad8306ec6ff23e0b75f041c616b9Maurice Chu
1642938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        private View getDetailEntryView(int position, View convertView, ViewGroup parent) {
1643938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            final DetailViewEntry entry = (DetailViewEntry) getItem(position);
16444cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            final View v;
1645515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            final DetailViewCache viewCache;
16464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
16474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Check to see if we can reuse convertView
16484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (convertView != null) {
16494cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                v = convertView;
1650515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                viewCache = (DetailViewCache) v.getTag();
16514cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            } else {
16524cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                // Create a new view if needed
16530f428ae59c24d95288da6acbf2757c400c04838eDaniel Lehmann                v = mInflater.inflate(R.layout.contact_detail_list_item, parent, false);
16544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
16554cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                // Cache the children
165654eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                viewCache = new DetailViewCache(v,
165754eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                        mPrimaryActionClickListener, mSecondaryActionClickListener);
1658c3a00085193e474c69ff0f455dd5d6086ff72e69Daniel Lehmann                v.setTag(viewCache);
16594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
16604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
166154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            bindDetailView(position, v, entry);
16624cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            return v;
16634cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
16644cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
166554eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        private void bindDetailView(int position, View view, DetailViewEntry entry) {
16664cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            final Resources resources = mContext.getResources();
1667515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            DetailViewCache views = (DetailViewCache) view.getTag();
16684cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
16692719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan            if (!TextUtils.isEmpty(entry.typeString)) {
16702719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan                views.type.setText(entry.typeString.toUpperCase());
16712719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan                views.type.setVisibility(View.VISIBLE);
16722719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan            } else {
16732719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan                views.type.setVisibility(View.GONE);
16742719ab07911c7f6476ae881bcf38699ef98b85d6Katherine Kuan            }
16755ad20a6b1c0552234e58d9bccb99cb0ba7cc9a0cDaniel Lehmann
167650c02ede09a757f69c80beb442aa32ee0010efc7Dmitri Plotnikov            views.data.setText(entry.data);
167750c02ede09a757f69c80beb442aa32ee0010efc7Dmitri Plotnikov            setMaxLines(views.data, entry.maxLines);
16784cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1679627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            // Set the default contact method
1680627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            views.primaryIndicator.setVisibility(entry.isPrimary ? View.VISIBLE : View.GONE);
1681627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
16824cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Set the presence icon
1683cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            final Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
16844cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    mContext, entry.presence);
1685cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            final ImageView presenceIconView = views.presenceIcon;
16864cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (presenceIcon != null) {
16874cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                presenceIconView.setImageDrawable(presenceIcon);
16884cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                presenceIconView.setVisibility(View.VISIBLE);
16894cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            } else {
16904cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                presenceIconView.setVisibility(View.GONE);
16914cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
16924cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
169344d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            final ActionsViewContainer actionsButtonContainer =
169444d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                    (ActionsViewContainer) views.actionsViewContainer;
169544d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            actionsButtonContainer.setTag(entry);
169644d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            actionsButtonContainer.setPosition(position);
169744d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            registerForContextMenu(actionsButtonContainer);
169854eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
16994cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            // Set the secondary action button
1700cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            final ImageView secondaryActionView = views.secondaryActionButton;
17014cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            Drawable secondaryActionIcon = null;
1702ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan            String secondaryActionDescription = null;
17034cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (entry.secondaryActionIcon != -1) {
17044cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                secondaryActionIcon = resources.getDrawable(entry.secondaryActionIcon);
1705ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                secondaryActionDescription = resources.getString(entry.secondaryActionDescription);
1706ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov            } else if ((entry.chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
1707ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov                secondaryActionIcon =
1708ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov                        resources.getDrawable(R.drawable.sym_action_videochat_holo_light);
1709ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                secondaryActionDescription = resources.getString(R.string.video_chat);
1710ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov            } else if ((entry.chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
1711ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov                secondaryActionIcon =
1712ff69c07777187580060a19170a9bf34028c5c63cDmitri Plotnikov                        resources.getDrawable(R.drawable.sym_action_audiochat_holo_light);
1713ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                secondaryActionDescription = resources.getString(R.string.audio_chat);
17144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
1715dfe20250b9f3d2cf134ba2a8a97399322ad48010Dmitri Plotnikov
171654eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            final View secondaryActionViewContainer = views.secondaryActionViewContainer;
17174cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (entry.secondaryIntent != null && secondaryActionIcon != null) {
17184cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                secondaryActionView.setImageDrawable(secondaryActionIcon);
1719ee05dcdd4b066ad909322c10919fb1812214673bKatherine Kuan                secondaryActionView.setContentDescription(secondaryActionDescription);
172054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                secondaryActionViewContainer.setTag(entry);
172154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                secondaryActionViewContainer.setVisibility(View.VISIBLE);
17224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                views.secondaryActionDivider.setVisibility(View.VISIBLE);
17234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            } else {
172454eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                secondaryActionViewContainer.setVisibility(View.GONE);
17254cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                views.secondaryActionDivider.setVisibility(View.GONE);
17264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
1727515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
172844d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            // Right and left padding should not have "pressed" effect.
172944d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            view.setPadding(
173044d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                    entry.isInSubSection()
173144d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                            ? mViewEntryDimensions.getWidePaddingLeft()
173244d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                            : mViewEntryDimensions.getPaddingLeft(),
173344d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                    0, mViewEntryDimensions.getPaddingRight(), 0);
173444d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            // Top and bottom padding should have "pressed" effect.
173544d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            final View primaryActionView = views.primaryActionView;
173644d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda            primaryActionView.setPadding(
173744d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                    primaryActionView.getPaddingLeft(),
173854eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    mViewEntryDimensions.getPaddingTop(),
173944d8fbe0c972706200f407eb078e421bca62cb97Flavio Lerda                    primaryActionView.getPaddingRight(),
174054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    mViewEntryDimensions.getPaddingBottom());
174154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            secondaryActionViewContainer.setPadding(
174254eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    secondaryActionViewContainer.getPaddingLeft(),
1743515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    mViewEntryDimensions.getPaddingTop(),
174454eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                    secondaryActionViewContainer.getPaddingRight(),
1745515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    mViewEntryDimensions.getPaddingBottom());
17464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
17474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
17484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        private void setMaxLines(TextView textView, int maxLines) {
17494cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            if (maxLines == 1) {
17504cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                textView.setSingleLine(true);
17514cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                textView.setEllipsize(TextUtils.TruncateAt.END);
17524cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            } else {
17534cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                textView.setSingleLine(false);
17544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                textView.setMaxLines(maxLines);
17554cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                textView.setEllipsize(null);
17564cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
17574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
17584cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
175954eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        private final OnClickListener mPrimaryActionClickListener = new OnClickListener() {
17601624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann            @Override
176154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            public void onClick(View view) {
1762cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann                if (mListener == null) return;
176354eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                final ViewEntry entry = (ViewEntry) view.getTag();
176454eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                if (entry == null) return;
176554eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                entry.click(view, mListener);
176654eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            }
176754eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        };
176854eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa
176954eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa        private final OnClickListener mSecondaryActionClickListener = new OnClickListener() {
177054eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            @Override
177154eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa            public void onClick(View view) {
177254eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                if (mListener == null) return;
177354eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                if (view == null) return;
177454eb1ea74b71fc4f8248e649b37fdb737aea920eDaisuke Miyakawa                final ViewEntry entry = (ViewEntry) view.getTag();
1775938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                if (entry == null || !(entry instanceof DetailViewEntry)) return;
1776938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                final DetailViewEntry detailViewEntry = (DetailViewEntry) entry;
1777938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                final Intent intent = detailViewEntry.secondaryIntent;
1778cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann                if (intent == null) return;
1779cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann                mListener.onItemClicked(intent);
1780cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            }
1781cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        };
1782cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
17831624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
1784cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public int getCount() {
1785938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return mAllEntries.size();
1786938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1787938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1788938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        @Override
1789938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public ViewEntry getItem(int position) {
1790938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return mAllEntries.get(position);
1791938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1792938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1793938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        @Override
1794938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public int getItemViewType(int position) {
1795938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return mAllEntries.get(position).getViewType();
1796cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        }
1797cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
17981624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
1799938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public int getViewTypeCount() {
1800938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return VIEW_TYPE_COUNT;
1801cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        }
1802cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
18031624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann        @Override
1804cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public long getItemId(int position) {
1805938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            final ViewEntry entry = mAllEntries.get(position);
1806cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            if (entry != null) {
1807938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                return entry.getId();
1808cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann            }
18091624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann            return -1;
1810cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        }
1811cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
1812938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        @Override
1813938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public boolean areAllItemsEnabled() {
1814938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            // Header will always be an item that is not enabled.
1815938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return false;
1816938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        }
1817938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan
1818938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        @Override
1819938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan        public boolean isEnabled(int position) {
1820938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan            return getItem(position).isEnabled();
18214cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
18224cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
18234cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1824caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    @Override
1825caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    public void onAccountSelectorCancelled() {
1826caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    }
1827caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov
1828caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    @Override
182977c20e8355e5bcd3f1106b87abc2b6d582f9b0bfMakoto Onuki    public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
1830caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov        createCopy(account);
1831caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    }
1832caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov
18332b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro    private void createCopy(AccountWithDataSet account) {
1834caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov        if (mListener != null) {
1835caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov            mListener.onCreateRawContactRequested(mContactData.getContentValues(), account);
1836caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov        }
1837caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov    }
1838caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov
1839ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki    /**
1840ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     * Default (fallback) list item click listener.  Note the click event for DetailViewEntry is
1841ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     * caught by individual views in the list item view to distinguish the primary action and the
1842ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     * secondary action, so this method won't be invoked for that.  (The listener is set in the
1843ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     * bindview in the adapter)
1844ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     * This listener is used for other kind of entries.
1845ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki     */
1846ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki    @Override
1847ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
1848ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        if (mListener == null) return;
1849ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        final ViewEntry entry = mAdapter.getItem(position);
1850ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        if (entry == null) return;
1851ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki        entry.click(view, mListener);
1852ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki    }
1853ec1395638edb9eeb90aaf9c036a38fbb38c9a2abMakoto Onuki
1854d364314c460152db7089b304beec81b3675893baDmitri Plotnikov    @Override
1855627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
1856627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        super.onCreateContextMenu(menu, view, menuInfo);
1857627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1858627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
1859627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        DetailViewEntry selectedEntry = (DetailViewEntry) mAllEntries.get(info.position);
1860627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1861627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        menu.setHeaderTitle(selectedEntry.data);
1862627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        menu.add(ContextMenu.NONE, ContextMenuIds.COPY_TEXT,
1863627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                ContextMenu.NONE, getString(R.string.copy_text));
1864627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1865627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        String selectedMimeType = selectedEntry.mimetype;
1866627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1867826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        // Defaults to true will only enable the detail to be copied to the clipboard.
1868826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        boolean isUniqueMimeType = true;
1869627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1870826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        // Only allow primary support for Phone and Email content types
1871826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        if (Phone.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
1872826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro            isUniqueMimeType = mIsUniqueNumber;
1873826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        } else if (Email.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
1874826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro            isUniqueMimeType = mIsUniqueEmail;
1875826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        }
1876826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro
1877826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        // Checking for previously set default
1878826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        if (selectedEntry.isPrimary) {
1879826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro            menu.add(ContextMenu.NONE, ContextMenuIds.CLEAR_DEFAULT,
1880826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro                    ContextMenu.NONE, getString(R.string.clear_default));
1881826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro        } else if (!isUniqueMimeType) {
1882826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro            menu.add(ContextMenu.NONE, ContextMenuIds.SET_DEFAULT,
1883826b6ee041537b9476b4cf23e13334dc3d9b4f7eFrank Sposaro                    ContextMenu.NONE, getString(R.string.set_default));
1884627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        }
1885627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    }
1886627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1887627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    @Override
1888627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    public boolean onContextItemSelected(MenuItem item) {
1889627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        AdapterView.AdapterContextMenuInfo menuInfo;
1890627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        try {
1891627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
1892627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        } catch (ClassCastException e) {
1893627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            Log.e(TAG, "bad menuInfo", e);
1894627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            return false;
1895627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        }
1896627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1897627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        switch (item.getItemId()) {
1898627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            case ContextMenuIds.COPY_TEXT:
1899627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                copyToClipboard(menuInfo.position);
1900627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                return true;
1901627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            case ContextMenuIds.SET_DEFAULT:
1902627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                setDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
1903627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                return true;
1904627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            case ContextMenuIds.CLEAR_DEFAULT:
1905627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                clearDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
1906627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                return true;
1907627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro            default:
1908627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro                throw new IllegalArgumentException("Unknown menu option " + item.getItemId());
1909627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        }
1910627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    }
1911627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1912627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    private void setDefaultContactMethod(long id) {
1913627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        Intent setIntent = ContactSaveService.createSetSuperPrimaryIntent(mContext, id);
1914627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        mContext.startService(setIntent);
1915627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    }
1916627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1917627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    private void clearDefaultContactMethod(long id) {
1918627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        Intent clearIntent = ContactSaveService.createClearPrimaryIntent(mContext, id);
1919627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        mContext.startService(clearIntent);
1920627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    }
1921627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1922627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro    private void copyToClipboard(int viewEntryPosition) {
1923627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        // Getting the text to copied
1924627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        DetailViewEntry detailViewEntry = (DetailViewEntry) mAllEntries.get(viewEntryPosition);
1925627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        CharSequence textToCopy = detailViewEntry.data;
1926627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
1927627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        // Checking for empty string
1928627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro        if (TextUtils.isEmpty(textToCopy)) return;
1929627e5dde4fc76c8bde01cc0db7f56c344c1758b8Frank Sposaro
19305ff2dfcc4aa050d7a062725b562e22c2727167b8Makoto Onuki        ClipboardUtils.copyText(getActivity(), detailViewEntry.typeString, textToCopy, true);
193150c02ede09a757f69c80beb442aa32ee0010efc7Dmitri Plotnikov    }
193250c02ede09a757f69c80beb442aa32ee0010efc7Dmitri Plotnikov
193379700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan    @Override
19341624964ef877dc7d67452cbdacfb4d811c245c17Daniel Lehmann    public boolean handleKeyDown(int keyCode) {
19354cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        switch (keyCode) {
19364cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            case KeyEvent.KEYCODE_CALL: {
19374cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                try {
19384cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    ITelephony phone = ITelephony.Stub.asInterface(
19394cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                            ServiceManager.checkService("phone"));
19404cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    if (phone != null && !phone.isIdle()) {
19414cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        // Skip out and let the key be handled at a higher level
19424cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        break;
19434cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
19444cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                } catch (RemoteException re) {
19454cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // Fall through and try to call the contact
19464cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                }
19474cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
19484cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                int index = mListView.getSelectedItemPosition();
19494cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                if (index != -1) {
1950938097786d31e97a9354238f69d9de85cedf6551Katherine Kuan                    final DetailViewEntry entry = (DetailViewEntry) mAdapter.getItem(index);
19510deb6d35d1d9620f9cc539bbd31c52f2fe97916bDaniel Lehmann                    if (entry != null && entry.intent != null &&
19524cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                            entry.intent.getAction() == Intent.ACTION_CALL_PRIVILEGED) {
19534cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        mContext.startActivity(entry.intent);
19544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                        return true;
19554cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    }
19564cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                } else if (mPrimaryPhoneUri != null) {
19574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    // There isn't anything selected, call the default number
1958fadd5e1f1845b8d98e247bbd30535928dc5e0f81Daisuke Miyakawa                    mContext.startActivity(ContactsUtils.getCallIntent(mPrimaryPhoneUri));
19594cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                    return true;
19604cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                }
19614cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann                return false;
19624cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann            }
19634cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann        }
19644cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
1965c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmann        return false;
19664cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann    }
196718f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann
19687ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    /**
19697ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     * Base class for QuickFixes. QuickFixes quickly fix issues with the Contact without
19707ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     * requiring the user to go to the editor. Example: Add to My Contacts.
19717ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann     */
19727ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private static abstract class QuickFix {
19737ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public abstract boolean isApplicable();
19747ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public abstract String getTitle();
19757ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public abstract void execute();
19767ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    }
19777ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
19787ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private class AddToMyContactsQuickFix extends QuickFix {
19797ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
19807ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public boolean isApplicable() {
19817ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // Only local contacts
19827ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (mContactData == null || mContactData.isDirectoryEntry()) return false;
19837ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
1984ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson            // User profile cannot be added to contacts
1985ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson            if (mContactData.isUserProfile()) return false;
1986ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson
19877ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // Only if exactly one raw contact
1988851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            if (mContactData.getRawContacts().size() != 1) return false;
19897ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
19907ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // test if the default group is assigned
19917ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final List<GroupMetaData> groups = mContactData.getGroupMetaData();
19927ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
19937ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // For accounts without group support, groups is null
19947ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (groups == null) return false;
19957ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
19967ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // remember the default group id. no default group? bail out early
19977ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final long defaultGroupId = getDefaultGroupId(groups);
19987ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (defaultGroupId == -1) return false;
19997ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
2000851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContact rawContact = (RawContact) mContactData.getRawContacts().get(0);
2001851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final AccountType type = rawContact.getAccountType();
20027ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // Offline or non-writeable account? Nothing to fix
200396e87fd6e808e9d853263ffeb5104f3253a18639Daniel Lehmann            if (type == null || !type.areContactsWritable()) return false;
20047ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20057ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // Check whether the contact is in the default group
20067ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            boolean isInDefaultGroup = false;
2007851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            for (DataItem dataItem : Iterables.filter(
2008851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    rawContact.getDataItems(), GroupMembershipDataItem.class)) {
2009851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                GroupMembershipDataItem groupMembership = (GroupMembershipDataItem) dataItem;
2010851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                final Long groupId = groupMembership.getGroupRowId();
2011851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                if (groupId == defaultGroupId) {
2012851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    isInDefaultGroup = true;
2013851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                    break;
20147ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                }
20157ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            }
20167ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20177ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            return !isInDefaultGroup;
20187ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
20197ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20207ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
20217ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public String getTitle() {
20227ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            return getString(R.string.add_to_my_contacts);
20237ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
20247ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20257ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
20267ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public void execute() {
20277ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final long defaultGroupId = getDefaultGroupId(mContactData.getGroupMetaData());
20287ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // there should always be a default group (otherwise the button would be invisible),
20297ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // but let's be safe here
20307ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (defaultGroupId == -1) return;
20317ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20327ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // add the group membership to the current state
2033851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDeltaList contactDeltaList = mContactData.createRawContactDeltaList();
2034851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final RawContactDelta rawContactEntityDelta = contactDeltaList.get(0);
20357ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20367ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
2037851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final AccountType type = rawContactEntityDelta.getAccountType(accountTypes);
20387ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final DataKind groupMembershipKind = type.getKindForMimetype(
20397ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    GroupMembership.CONTENT_ITEM_TYPE);
2040851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            final ValuesDelta entry = RawContactModifier.insertChild(rawContactEntityDelta,
20417ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    groupMembershipKind);
2042851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu            entry.setGroupRowId(defaultGroupId);
20437ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20447ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // and fire off the intent. we don't need a callback, as the database listener
20457ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // should update the ui
20467ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            final Intent intent = ContactSaveService.createSaveContactIntent(getActivity(),
2047ead19c5eafee0ffb43b02a4ae75ac5244ad3f853Isaac Katzenelson                    contactDeltaList, "", 0, false, getActivity().getClass(),
2048e692e010ca02200087997280e7c239ebf94aa8f9Josh Gargus                    Intent.ACTION_VIEW, null);
20497ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            getActivity().startService(intent);
20507ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
20517ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    }
20527ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20537ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    private class MakeLocalCopyQuickFix extends QuickFix {
20547ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
20557ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public boolean isApplicable() {
20567ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // Not a directory contact? Nothing to fix here
20577ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (mContactData == null || !mContactData.isDirectoryEntry()) return false;
20587ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20597ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            // No export support? Too bad
20607ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (mContactData.getDirectoryExportSupport() == Directory.EXPORT_SUPPORT_NONE) {
20617ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                return false;
20627ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            }
20637ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20647ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            return true;
20657ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
20667ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20677ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
20687ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public String getTitle() {
20697ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            return getString(R.string.menu_copyContact);
20707ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
20717ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20727ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        @Override
20737ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        public void execute() {
20747ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            if (mListener == null) {
20757ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                return;
20767ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            }
20777ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20787ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            int exportSupport = mContactData.getDirectoryExportSupport();
20797ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            switch (exportSupport) {
20807ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                case Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY: {
20812b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                    createCopy(new AccountWithDataSet(mContactData.getDirectoryAccountName(),
20822b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                                    mContactData.getDirectoryAccountType(), null));
20837ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    break;
20847ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                }
20857ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                case Directory.EXPORT_SUPPORT_ANY_ACCOUNT: {
20862b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                    final List<AccountWithDataSet> accounts =
20877ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                            AccountTypeManager.getInstance(mContext).getAccounts(true);
20887ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    if (accounts.isEmpty()) {
20897ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                        createCopy(null);
20907ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                        return;  // Don't show a dialog.
20917ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    }
20927ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
20937ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    // In the common case of a single writable account, auto-select
20947ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    // it without showing a dialog.
20957ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    if (accounts.size() == 1) {
20967ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                        createCopy(accounts.get(0));
20977ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                        return;  // Don't show a dialog.
20987ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    }
20997ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
210077c20e8355e5bcd3f1106b87abc2b6d582f9b0bfMakoto Onuki                    SelectAccountDialogFragment.show(getFragmentManager(),
210177c20e8355e5bcd3f1106b87abc2b6d582f9b0bfMakoto Onuki                            ContactDetailFragment.this, R.string.dialog_new_contact_account,
210277c20e8355e5bcd3f1106b87abc2b6d582f9b0bfMakoto Onuki                            AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, null);
21037ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                    break;
21047ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann                }
21057ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann            }
21067ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann        }
21077ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann    }
21087ed92eeedcc2275fc7b4f257c6ca03a4d4120cc6Daniel Lehmann
2109515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    /**
2110515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * This class loads the correct padding values for a contact detail item so they can be applied
2111515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * dynamically. For example, this supports the case where some detail items can be indented and
2112515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     * need extra padding.
2113515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan     */
2114515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    private static class ViewEntryDimensions {
2115515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2116515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final int mWidePaddingLeft;
2117515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final int mPaddingLeft;
2118515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final int mPaddingRight;
2119515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final int mPaddingTop;
2120515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        private final int mPaddingBottom;
2121515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2122515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public ViewEntryDimensions(Resources resources) {
2123515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mPaddingLeft = resources.getDimensionPixelSize(
2124515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    R.dimen.detail_item_side_margin);
2125515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mPaddingTop = resources.getDimensionPixelSize(
2126515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    R.dimen.detail_item_vertical_margin);
21278bec90963b31074164321b5e7712fdb33f4fa134Katherine Kuan            mWidePaddingLeft = mPaddingLeft +
21288bec90963b31074164321b5e7712fdb33f4fa134Katherine Kuan                    resources.getDimensionPixelSize(R.dimen.detail_item_icon_margin) +
2129515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan                    resources.getDimensionPixelSize(R.dimen.detail_network_icon_size);
2130515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mPaddingRight = mPaddingLeft;
2131515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            mPaddingBottom = mPaddingTop;
2132515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2133515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2134515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public int getWidePaddingLeft() {
2135515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mWidePaddingLeft;
2136515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2137515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2138515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public int getPaddingLeft() {
2139515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mPaddingLeft;
2140515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2141515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2142515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public int getPaddingRight() {
2143515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mPaddingRight;
2144515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2145515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2146515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public int getPaddingTop() {
2147515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mPaddingTop;
2148515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2149515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2150515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        public int getPaddingBottom() {
2151515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan            return mPaddingBottom;
2152515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan        }
2153515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan    }
2154515f9d178d60dc52e5474f78d5f08efcebe9238dKatherine Kuan
2155cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann    public static interface Listener {
215618f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann        /**
215708bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan         * User clicked a single item (e.g. mail). The intent passed in could be null.
215818f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann         */
2159cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        public void onItemClicked(Intent intent);
2160cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann
2161cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann        /**
2162caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov         * User requested creation of a new contact with the specified values.
2163caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov         *
2164caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov         * @param values ContentValues containing data rows for the new contact.
21652b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro         * @param account Account where the new contact should be created.
2166caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov         */
21672b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro        public void onCreateRawContactRequested(ArrayList<ContentValues> values,
21682b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                AccountWithDataSet account);
216918f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann    }
21703e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
21713e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    /**
21723e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     * Adapter for the invitable account types; used for the invitable account type list popup.
21733e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki     */
21743e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    private final static class InvitableAccountTypesAdapter extends BaseAdapter {
21753e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        private final Context mContext;
21763e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        private final LayoutInflater mInflater;
21773e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        private final ArrayList<AccountType> mAccountTypes;
21783e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
2179851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        public InvitableAccountTypesAdapter(Context context, Contact contactData) {
21803e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            mContext = context;
21813e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            mInflater = LayoutInflater.from(context);
21822b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro            final List<AccountType> types = contactData.getInvitableAccountTypes();
21833e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            mAccountTypes = new ArrayList<AccountType>(types.size());
21843e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
21853e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            for (int i = 0; i < types.size(); i++) {
21862b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                mAccountTypes.add(types.get(i));
21873e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            }
21883e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
21893e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            Collections.sort(mAccountTypes, new AccountType.DisplayLabelComparator(mContext));
21903e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
21913e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
21923e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
21933e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public View getView(int position, View convertView, ViewGroup parent) {
21943e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final View resultView =
21953e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                    (convertView != null) ? convertView
21963e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                    : mInflater.inflate(R.layout.account_selector_list_item, parent, false);
21973e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
21983e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final TextView text1 = (TextView)resultView.findViewById(android.R.id.text1);
21993e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final TextView text2 = (TextView)resultView.findViewById(android.R.id.text2);
22003e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final ImageView icon = (ImageView)resultView.findViewById(android.R.id.icon);
22013e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22023e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            final AccountType accountType = mAccountTypes.get(position);
22033e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22043e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            CharSequence action = accountType.getInviteContactActionLabel(mContext);
22053e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            CharSequence label = accountType.getDisplayLabel(mContext);
22063e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            if (TextUtils.isEmpty(action)) {
22073e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                text1.setText(label);
22083e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                text2.setVisibility(View.GONE);
22093e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            } else {
22103e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                text1.setText(action);
22113e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                text2.setVisibility(View.VISIBLE);
22123e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki                text2.setText(label);
22133e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            }
22143e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            icon.setImageDrawable(accountType.getDisplayIcon(mContext));
22153e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22163e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return resultView;
22173e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
22183e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22193e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
22203e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public int getCount() {
22213e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return mAccountTypes.size();
22223e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
22233e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22243e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
22253e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public AccountType getItem(int position) {
22263e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return mAccountTypes.get(position);
22273e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
22283e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki
22293e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        @Override
22303e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        public long getItemId(int position) {
22313e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki            return position;
22323e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki        }
22333e6991e5ee91ea2cc82a02bd3ea4ed7e941b08afMakoto Onuki    }
22344cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann}
2235