1863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton/*
2863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * Copyright (C) 2010 Google Inc.
3863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton *
4863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License");
5863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * you may not use this file except in compliance with the License.
6863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * You may obtain a copy of the License at
7863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton *
8863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton *	    http://www.apache.org/licenses/LICENSE-2.0
9863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton *
10863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * Unless required by applicable law or agreed to in writing, software
11863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS,
12863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * See the License for the specific language governing permissions and
14863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton * limitations under the License
15863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton */
16863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
174e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamiltonpackage com.android.loaderapp.fragments;
18863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
19e15efb9074c5497aaca00d960c310fff07817925Jeff Hamiltonimport com.android.loaderapp.ContactHeaderWidget;
204e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamiltonimport com.android.loaderapp.R;
21863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.Collapser;
224e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamiltonimport com.android.loaderapp.model.ContactLoader;
23863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.ContactsSource;
24863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.Sources;
252ea5555755ffbfadf2f26b269b2af4def936d92aJeff Hamiltonimport com.android.loaderapp.model.TypePrecedence;
26863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.Collapser.Collapsible;
27863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.ContactLoader.ContactData;
28863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.model.ContactsSource.DataKind;
29863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.util.Constants;
30863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.util.ContactPresenceIconUtil;
31863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.util.ContactsUtils;
32863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.android.loaderapp.util.DataStatus;
33863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.google.android.collect.Lists;
34863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport com.google.android.collect.Maps;
35863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
36f6ffbae39b62c54c0a96914beaacfca213658a4fJeff Hamiltonimport android.app.LoaderManagingFragment;
37863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.ActivityNotFoundException;
38863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.ContentUris;
39863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.ContentValues;
40863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.Context;
41863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.Entity;
42863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.Intent;
43f6ffbae39b62c54c0a96914beaacfca213658a4fJeff Hamiltonimport android.content.Loader;
44863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.Entity.NamedContentValues;
45863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.content.res.Resources;
46863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.graphics.drawable.Drawable;
47863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.net.ParseException;
48863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.net.Uri;
49863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.net.WebAddress;
504e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamiltonimport android.os.Bundle;
51863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds;
52863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.Contacts;
53863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.Data;
54863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.DisplayNameSources;
55863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.RawContacts;
56863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.StatusUpdates;
57863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Email;
58863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Im;
59863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Nickname;
60863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Note;
61863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Organization;
62863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Phone;
63863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
64863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.provider.ContactsContract.CommonDataKinds.Website;
65863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.telephony.PhoneNumberUtils;
66863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.text.TextUtils;
67863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.util.Log;
68863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.view.LayoutInflater;
69863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.view.View;
70863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.view.ViewGroup;
71863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.view.View.OnClickListener;
72863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.widget.AdapterView;
73863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.widget.ImageView;
74863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.widget.ListView;
75863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.widget.TextView;
76863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport android.widget.AdapterView.OnItemClickListener;
77863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
78863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport java.util.ArrayList;
79863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamiltonimport java.util.HashMap;
80863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
814e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamiltonpublic class ContactFragment extends LoaderManagingFragment<ContactData>
824e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        implements OnClickListener, OnItemClickListener {
83cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton    private static final String TAG = "ContactCoupler";
84863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
854e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    static final String ARG_URI = "uri";
864e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    static final int LOADER_DETAILS = 1;
87cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton
884e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    Uri mUri;
894e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
90224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private static final boolean SHOW_SEPARATORS = false;
91224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
92224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected Uri mLookupUri;
93224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private ViewAdapter mAdapter;
94224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private int mNumPhoneNumbers = 0;
95224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private Controller mController;
96224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
97224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /**
98224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     * A list of distinct contact IDs included in the current contact.
99224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     */
100224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private ArrayList<Long> mRawContactIds = new ArrayList<Long>();
101224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
102224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mPhoneEntries = new ArrayList<ViewEntry>();
103224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mSmsEntries = new ArrayList<ViewEntry>();
104224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mEmailEntries = new ArrayList<ViewEntry>();
105224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mPostalEntries = new ArrayList<ViewEntry>();
106224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mImEntries = new ArrayList<ViewEntry>();
107224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mNicknameEntries = new ArrayList<ViewEntry>();
108224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mOrganizationEntries = new ArrayList<ViewEntry>();
109224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mGroupEntries = new ArrayList<ViewEntry>();
110224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ViewEntry> mOtherEntries = new ArrayList<ViewEntry>();
111224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /* package */ ArrayList<ArrayList<ViewEntry>> mSections = new ArrayList<ArrayList<ViewEntry>>();
112224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
113224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected ContactHeaderWidget mContactHeaderWidget;
114224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
115224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected LayoutInflater mInflater;
116224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
117224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected int mReadOnlySourcesCnt;
118224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected int mWritableSourcesCnt;
119224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected boolean mAllRestricted;
120224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
121224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected Uri mPrimaryPhoneUri = null;
122224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
123224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    protected ArrayList<Long> mWritableRawContactIds = new ArrayList<Long>();
124224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
125224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private long mNameRawContactId = -1;
126224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private int mDisplayNameSource = DisplayNameSources.UNDEFINED;
127224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
128224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private ArrayList<Entity> mEntities = Lists.newArrayList();
129224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private HashMap<Long, DataStatus> mStatuses = Maps.newHashMap();
130224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
131224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    /**
132224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     * The view shown if the detail list is empty.
133224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     * We set this to the list view when first bind the adapter, so that it won't be shown while
134224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     * we're loading data.
135224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton     */
136224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private View mEmptyView;
137224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
138224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private ListView mListView;
139224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    private boolean mShowSmsLinksForAllPhones;
140224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
141224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    public ContactFragment() {
142224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton    }
143224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton
1444e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    public ContactFragment(Uri uri, ContactFragment.Controller controller) {
1454e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        mUri = uri;
1464e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        mController = controller;
1474e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
1484e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1494e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    @Override
1504e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    public void onCreate(Bundle savedState) {
1514e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        super.onCreate(savedState);
1524e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
1534e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1544e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    @Override
15503d1db253c9e7fa1f83cf467cc25a6a28ba0bdc1Jeff Hamilton    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
1564e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        View view = inflater.inflate(R.layout.contact_details, container, false);
1574e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1584e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        mInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
159863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
160cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mContactHeaderWidget = (ContactHeaderWidget) view.findViewById(R.id.contact_header_widget);
161cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mContactHeaderWidget.setExcludeMimes(new String[] { Contacts.CONTENT_ITEM_TYPE });
162cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton
163cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mListView = (ListView) view.findViewById(android.R.id.list);
164cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
165cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mListView.setOnItemClickListener(this);
166cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        // Don't set it to mListView yet.  We do so later when we bind the adapter.
167cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mEmptyView = view.findViewById(android.R.id.empty);
168cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton
169cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        // Build the list of sections. The order they're added to mSections dictates the
170cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        // order they are displayed in the list.
171cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mPhoneEntries);
172cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mSmsEntries);
173cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mEmailEntries);
174cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mImEntries);
175cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mPostalEntries);
176cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mNicknameEntries);
177cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mOrganizationEntries);
178cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mGroupEntries);
179cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mSections.add(mOtherEntries);
180cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton
181cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        //TODO Read this value from a preference
182cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mShowSmsLinksForAllPhones = true;
1834e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1844e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        return view;
1854e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
1864e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1874e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    @Override
1884e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    public void onInitializeLoaders() {
1894e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        if (mUri != null) {
1904e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            loadContact(mUri);
1914e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        }
1924e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
1934e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
1944e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    @Override
1954e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    protected Loader onCreateLoader(int id, Bundle args) {
1964e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        switch (id) {
1974e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            case LOADER_DETAILS: {
1984e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton                Uri uri = args.getParcelable(ARG_URI);
1994e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton                return new ContactLoader(getActivity(), uri);
2004e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            }
2014e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        }
2024e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        return null;
2034e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
2044e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
2054e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    @Override
2064e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    public void onLoadFinished(Loader<ContactData> loader, ContactData data) {
2074e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        switch (loader.getId()) {
2084e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            case LOADER_DETAILS: {
2094e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton                setData(data);
2104e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton                break;
2114e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            }
2124e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        }
2134e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    }
2144e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton
2154e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton    public void loadContact(Uri uri) {
216224925d323a83e257fcd6bacedcc15aeeac03489Jeff Hamilton        mUri = uri;
2174e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        Bundle args = new Bundle();
2184e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        args.putParcelable(ARG_URI, uri);
2194e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        startLoading(LOADER_DETAILS, args);
220863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
221863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
222863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    public void setData(ContactData data) {
223863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mEntities = data.entities;
224863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mStatuses = data.statuses;
225863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
226863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mNameRawContactId = data.nameRawContactId;
227863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mDisplayNameSource = data.displayNameSource;
228863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
229863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mContactHeaderWidget.bindFromContactLookupUri(data.uri);
230863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        bindData();
231863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
232863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
233cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton    public interface Controller {
234cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        public void onPrimaryAction(ViewEntry entry);
235cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        public void onSecondaryAction(ViewEntry entry);
236863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
237863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
238cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton    public static final class DefaultController implements Controller {
239863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        private Context mContext;
240863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
241cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        public DefaultController(Context context) {
242863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            mContext = context;
243863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
244863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
245cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        public void onPrimaryAction(ViewEntry entry) {
246863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            Intent intent = entry.intent;
247863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (intent != null) {
248863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                try {
249863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mContext.startActivity(intent);
250863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } catch (ActivityNotFoundException e) {
251863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    Log.e(TAG, "No activity found for intent: " + intent);
252863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                }
253863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
254863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
255863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
256cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        public void onSecondaryAction(ViewEntry entry) {
257863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            Intent intent = entry.secondaryIntent;
258863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (intent != null) {
259863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                try {
260863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mContext.startActivity(intent);
261863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } catch (ActivityNotFoundException e) {
262863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    Log.e(TAG, "No activity found for intent: " + intent);
263863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                }
264863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
265863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
266863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
267863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
268cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton    public void setController(Controller controller) {
269cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        mController = controller;
270863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
271863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
272863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    public void onItemClick(AdapterView parent, View v, int position, long id) {
273cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        if (mController != null) {
274863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ViewEntry entry = ViewAdapter.getEntry(mSections, position, SHOW_SEPARATORS);
275863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (entry != null) {
276cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton                mController.onPrimaryAction(entry);
277863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
278863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
279863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
280863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
281863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    public void onClick(View v) {
282cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton        if (mController != null) {
283cd893d57e1e5e695fb26d14fb37f0fa3b3fe1971Jeff Hamilton            mController.onSecondaryAction((ViewEntry) v.getTag());
284863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
285863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
286863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
287863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    private void bindData() {
288863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
289863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        // Build up the contact entries
290863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        buildEntries();
291863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
292863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        // Collapse similar data items in select sections.
293863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        Collapser.collapseList(mPhoneEntries);
294863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        Collapser.collapseList(mSmsEntries);
295863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        Collapser.collapseList(mEmailEntries);
296863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        Collapser.collapseList(mPostalEntries);
297863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        Collapser.collapseList(mImEntries);
298863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
299863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        if (mAdapter == null) {
3004e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton            mAdapter = new ViewAdapter(getActivity(), mSections);
301863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            mListView.setAdapter(mAdapter);
302863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        } else {
303863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            mAdapter.setSections(mSections, SHOW_SEPARATORS);
304863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
305863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mListView.setEmptyView(mEmptyView);
306863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
307863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
308863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    /**
309863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     * Build up the entries to display on the screen.
310863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     *
311863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     * @param personCursor the URI for the contact being displayed
312863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     */
313863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    private final void buildEntries() {
314863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        // Clear out the old entries
315863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        final int numSections = mSections.size();
316863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        for (int i = 0; i < numSections; i++) {
317863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            mSections.get(i).clear();
318863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
319863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
320863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mRawContactIds.clear();
321863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
322863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mReadOnlySourcesCnt = 0;
323863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mWritableSourcesCnt = 0;
324863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mAllRestricted = true;
325863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mPrimaryPhoneUri = null;
326863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
327863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        mWritableRawContactIds.clear();
328863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
329863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        if (mEntities == null || mStatuses == null) {
330863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return;
331863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
332863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
3334e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton        final Context context = getActivity();
334863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        final Sources sources = Sources.getInstance(context);
335863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
336863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        // Build up method entries
337863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        for (Entity entity: mEntities) {
338863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final ContentValues entValues = entity.getEntityValues();
339863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final String accountType = entValues.getAsString(RawContacts.ACCOUNT_TYPE);
340863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final long rawContactId = entValues.getAsLong(RawContacts._ID);
341863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
342863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Mark when this contact has any unrestricted components
343863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final boolean isRestricted = entValues.getAsInteger(RawContacts.IS_RESTRICTED) != 0;
344863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!isRestricted) mAllRestricted = false;
345863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
346863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!mRawContactIds.contains(rawContactId)) {
347863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                mRawContactIds.add(rawContactId);
348863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
349863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ContactsSource contactsSource = sources.getInflatedSource(accountType,
350863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    ContactsSource.LEVEL_SUMMARY);
351863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (contactsSource != null && contactsSource.readOnly) {
352863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                mReadOnlySourcesCnt += 1;
353863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
354863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                mWritableSourcesCnt += 1;
355863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                mWritableRawContactIds.add(rawContactId);
356863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
357863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
358863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
359863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            for (NamedContentValues subValue : entity.getSubValues()) {
360863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final ContentValues entryValues = subValue.values;
361863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                entryValues.put(Data.RAW_CONTACT_ID, rawContactId);
362863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
363863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final long dataId = entryValues.getAsLong(Data._ID);
364863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final String mimeType = entryValues.getAsString(Data.MIMETYPE);
365863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                if (mimeType == null) continue;
366863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
367863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final DataKind kind = sources.getKindOrFallback(accountType, mimeType,
368863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        context, ContactsSource.LEVEL_MIMETYPES);
369863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                if (kind == null) continue;
370863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
371863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final ViewEntry entry = ViewEntry.fromValues(context, mimeType, kind,
372863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        rawContactId, dataId, entryValues);
373863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
374863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final boolean hasData = !TextUtils.isEmpty(entry.data);
375863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                final boolean isSuperPrimary = entryValues.getAsInteger(
376863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        Data.IS_SUPER_PRIMARY) != 0;
377863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
378863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                if (Phone.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
379863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build phone entries
380863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mNumPhoneNumbers++;
381863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
382863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
383863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            Uri.fromParts(Constants.SCHEME_TEL, entry.data, null));
384863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.secondaryIntent = new Intent(Intent.ACTION_SENDTO,
385863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null));
386863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
387863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Remember super-primary phone
388863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (isSuperPrimary) mPrimaryPhoneUri = entry.uri;
389863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
390863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.isPrimary = isSuperPrimary;
391863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mPhoneEntries.add(entry);
392863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
393863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (entry.type == CommonDataKinds.Phone.TYPE_MOBILE
394863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            || mShowSmsLinksForAllPhones) {
395863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        // Add an SMS entry
396863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        if (kind.iconAltRes > 0) {
397863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            entry.secondaryActionIcon = kind.iconAltRes;
398863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        }
399863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
400863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
401863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build email entries
402863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.intent = new Intent(Intent.ACTION_SENDTO,
403863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            Uri.fromParts(Constants.SCHEME_MAILTO, entry.data, null));
404863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.isPrimary = isSuperPrimary;
405863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mEmailEntries.add(entry);
406863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
407863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // When Email rows have status, create additional Im row
408863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final DataStatus status = mStatuses.get(entry.id);
409863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (status != null) {
410863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        final String imMime = Im.CONTENT_ITEM_TYPE;
411863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        final DataKind imKind = sources.getKindOrFallback(accountType,
412863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                                imMime, context, ContactsSource.LEVEL_MIMETYPES);
413863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        final ViewEntry imEntry = ViewEntry.fromValues(context,
414863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                                imMime, imKind, rawContactId, dataId, entryValues);
415863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        imEntry.intent = ContactsUtils.buildImIntent(entryValues);
416863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        imEntry.applyStatus(status, false);
417863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        mImEntries.add(imEntry);
418863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
419863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
420863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build postal entries
421863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.maxLines = 4;
422863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.intent = new Intent(Intent.ACTION_VIEW, entry.uri);
423863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mPostalEntries.add(entry);
424863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
425863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build IM entries
426863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.intent = ContactsUtils.buildImIntent(entryValues);
427863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (TextUtils.isEmpty(entry.label)) {
428863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.label = context.getString(R.string.chat).toLowerCase();
429863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
430863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
431863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Apply presence and status details when available
432863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final DataStatus status = mStatuses.get(entry.id);
433863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (status != null) {
434863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.applyStatus(status, false);
435863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
436863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mImEntries.add(entry);
437863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType) &&
438863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        (hasData || !TextUtils.isEmpty(entry.label))) {
439863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build organization entries
440863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final boolean isNameRawContact = (mNameRawContactId == rawContactId);
441863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
442863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final boolean duplicatesTitle =
443863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        isNameRawContact
444863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        && mDisplayNameSource == DisplayNameSources.ORGANIZATION
445863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        && (!hasData || TextUtils.isEmpty(entry.label));
446863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
447863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (!duplicatesTitle) {
448863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.uri = null;
449863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
450863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        if (TextUtils.isEmpty(entry.label)) {
451863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            entry.label = entry.data;
452863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            entry.data = "";
453863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        }
454863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
455863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        mOrganizationEntries.add(entry);
456863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
457863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
458863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build nickname entries
459863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final boolean isNameRawContact = (mNameRawContactId == rawContactId);
460863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
461863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final boolean duplicatesTitle =
462863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        isNameRawContact
463863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        && mDisplayNameSource == DisplayNameSources.NICKNAME;
464863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
465863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (!duplicatesTitle) {
466863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.uri = null;
467863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        mNicknameEntries.add(entry);
468863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
469863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
470863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build note entries
471863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.uri = null;
472863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.maxLines = 100;
473863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mOtherEntries.add(entry);
474863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
475863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Build note entries
476863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.uri = null;
477863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.maxLines = 10;
478863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    try {
479863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        WebAddress webAddress = new WebAddress(entry.data);
480863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.intent = new Intent(Intent.ACTION_VIEW,
481863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                                Uri.parse(webAddress.toString()));
482863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    } catch (ParseException e) {
483863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        Log.e(TAG, "Couldn't parse website: " + entry.data);
484863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
485863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mOtherEntries.add(entry);
486863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else {
487863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Handle showing custom rows
488863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    entry.intent = new Intent(Intent.ACTION_VIEW, entry.uri);
489863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
490863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Use social summary when requested by external source
491863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final DataStatus status = mStatuses.get(entry.id);
492863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    final boolean hasSocial = kind.actionBodySocial && status != null;
493863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (hasSocial) {
494863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        entry.applyStatus(status, true);
495863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
496863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
497863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    if (hasSocial || hasData) {
498863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        mOtherEntries.add(entry);
499863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    }
500863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                }
501863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
502863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
503863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
504863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
505863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    static String buildActionString(DataKind kind, ContentValues values, boolean lowerCase,
506863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            Context context) {
507863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        if (kind.actionHeader == null) {
508863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return null;
509863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
510863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        CharSequence actionHeader = kind.actionHeader.inflateUsing(context, values);
511863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        if (actionHeader == null) {
512863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return null;
513863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
514863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        return lowerCase ? actionHeader.toString().toLowerCase() : actionHeader.toString();
515863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
516863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
517863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    static String buildDataString(DataKind kind, ContentValues values, Context context) {
518863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        if (kind.actionBody == null) {
519863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return null;
520863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
521863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        CharSequence actionBody = kind.actionBody.inflateUsing(context, values);
522863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        return actionBody == null ? null : actionBody.toString();
523863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
524863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
525863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    /**
526863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     * A basic structure with the data for a contact entry in the list.
527863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton     */
528863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton   public static class ViewEntry extends ContactEntryAdapter.Entry implements Collapsible<ViewEntry> {
529863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public Context context = null;
530863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public String resPackageName = null;
531863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public int actionIcon = -1;
532863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public boolean isPrimary = false;
533863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public int secondaryActionIcon = -1;
534863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public Intent intent;
535863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public Intent secondaryIntent = null;
536863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public int maxLabelLines = 1;
537863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ArrayList<Long> ids = new ArrayList<Long>();
538863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public int collapseCount = 0;
539863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
540863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public int presence = -1;
541863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
542863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public CharSequence footerLine = null;
543863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
544863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        private ViewEntry() {
545863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
546863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
547863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        /**
548863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         * Build new {@link ViewEntry} and populate from the given values.
549863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         */
550863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public static ViewEntry fromValues(Context context, String mimeType, DataKind kind,
551863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                long rawContactId, long dataId, ContentValues values) {
552863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final ViewEntry entry = new ViewEntry();
553863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.context = context;
554863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.contactId = rawContactId;
555863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.id = dataId;
556863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.uri = ContentUris.withAppendedId(Data.CONTENT_URI, entry.id);
557863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.mimetype = mimeType;
558863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.label = buildActionString(kind, values, false, context);
559863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            entry.data = buildDataString(kind, values, context);
560863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
561863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (kind.typeColumn != null && values.containsKey(kind.typeColumn)) {
562863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                entry.type = values.getAsInteger(kind.typeColumn);
563863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
564863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (kind.iconRes > 0) {
565863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                entry.resPackageName = kind.resPackageName;
566863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                entry.actionIcon = kind.iconRes;
567863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
568863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
569863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return entry;
570863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
571863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
572863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        /**
573863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         * Apply given {@link DataStatus} values over this {@link ViewEntry}
574863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         *
575863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         * @param fillData When true, the given status replaces {@link #data}
576863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         *            and {@link #footerLine}. Otherwise only {@link #presence}
577863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         *            is updated.
578863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton         */
579863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ViewEntry applyStatus(DataStatus status, boolean fillData) {
580863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            presence = status.getPresence();
581863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (fillData && status.isValid()) {
582863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                this.data = status.getStatus().toString();
583863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                this.footerLine = status.getTimestampLabel(context);
584863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
585863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
586863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return this;
587863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
588863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
589863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public boolean collapseWith(ViewEntry entry) {
590863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // assert equal collapse keys
591863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!shouldCollapseWith(entry)) {
592863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                return false;
593863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
594863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
595863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Choose the label associated with the highest type precedence.
596863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (TypePrecedence.getTypePrecedence(mimetype, type)
597863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    > TypePrecedence.getTypePrecedence(entry.mimetype, entry.type)) {
598863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                type = entry.type;
599863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                label = entry.label;
600863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
601863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
602863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Choose the max of the maxLines and maxLabelLines values.
603863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            maxLines = Math.max(maxLines, entry.maxLines);
604863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            maxLabelLines = Math.max(maxLabelLines, entry.maxLabelLines);
605863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
606863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Choose the presence with the highest precedence.
607863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (StatusUpdates.getPresencePrecedence(presence)
608863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    < StatusUpdates.getPresencePrecedence(entry.presence)) {
609863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                presence = entry.presence;
610863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
611863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
612863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // If any of the collapsed entries are primary make the whole thing primary.
613863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            isPrimary = entry.isPrimary ? true : isPrimary;
614863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
615863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // uri, and contactdId, shouldn't make a difference. Just keep the original.
616863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
617863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Keep track of all the ids that have been collapsed with this one.
618863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ids.add(entry.id);
619863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            collapseCount++;
620863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return true;
621863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
622863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
623863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public boolean shouldCollapseWith(ViewEntry entry) {
624863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (entry == null) {
625863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                return false;
626863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
627863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
628863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!ContactsUtils.areDataEqual(context, mimetype, data, entry.mimetype, entry.data)) {
629863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                return false;
630863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
631863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
632863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!TextUtils.equals(mimetype, entry.mimetype)
633863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    || !ContactsUtils.areIntentActionEqual(intent, entry.intent)
634863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    || !ContactsUtils.areIntentActionEqual(secondaryIntent, entry.secondaryIntent)
635863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    || actionIcon != entry.actionIcon) {
636863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                return false;
637863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
638863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
639863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return true;
640863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
641863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
642863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
643863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    /** Cache of the children views of a row */
644863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    static class ViewCache {
645863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public TextView label;
646863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public TextView data;
647863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public TextView footer;
648863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ImageView actionIcon;
649863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ImageView presenceIcon;
650863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ImageView primaryIcon;
651863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public ImageView secondaryActionButton;
652863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public View secondaryActionDivider;
653863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
654863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        // Need to keep track of this too
655863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        ViewEntry entry;
656863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
657863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
658863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    private final class ViewAdapter extends ContactEntryAdapter<ViewEntry> {
659863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        ViewAdapter(Context context, ArrayList<ArrayList<ViewEntry>> sections) {
660863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            super(context, sections, SHOW_SEPARATORS);
661863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
662863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
663863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        @Override
664863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        public View getView(int position, View convertView, ViewGroup parent) {
665863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ViewEntry entry = getEntry(mSections, position, false);
666863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            View v;
667863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
668863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ViewCache views;
669863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
670863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Check to see if we can reuse convertView
671863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (convertView != null) {
672863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                v = convertView;
673863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views = (ViewCache) v.getTag();
674863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
675863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                // Create a new view if needed
676863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                v = mInflater.inflate(R.layout.list_item_text_icons, parent, false);
677863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
678863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                // Cache the children
679863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views = new ViewCache();
680863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.label = (TextView) v.findViewById(android.R.id.text1);
681863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.data = (TextView) v.findViewById(android.R.id.text2);
682863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.footer = (TextView) v.findViewById(R.id.footer);
683863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.actionIcon = (ImageView) v.findViewById(R.id.action_icon);
684863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.primaryIcon = (ImageView) v.findViewById(R.id.primary_icon);
685863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.presenceIcon = (ImageView) v.findViewById(R.id.presence_icon);
686863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.secondaryActionButton = (ImageView) v.findViewById(
687863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        R.id.secondary_action_button);
6884e5a9e4ee5c1ecab0a7a8eebee883f3f189f5cb4Jeff Hamilton                views.secondaryActionButton.setOnClickListener(ContactFragment.this);
689863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.secondaryActionDivider = v.findViewById(R.id.divider);
690863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                v.setTag(views);
691863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
692863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
693863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Update the entry in the view cache
694863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            views.entry = entry;
695863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
696863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Bind the data to the view
697863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            bindView(v, entry);
698863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            return v;
699863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
700863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
701863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        @Override
702863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        protected View newView(int position, ViewGroup parent) {
703863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // getView() handles this
704863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            throw new UnsupportedOperationException();
705863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
706863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
707863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        @Override
708863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        protected void bindView(View view, ViewEntry entry) {
709863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            final Resources resources = mContext.getResources();
710863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ViewCache views = (ViewCache) view.getTag();
711863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
712863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the label
713863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            TextView label = views.label;
714863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            setMaxLines(label, entry.maxLabelLines);
715863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            label.setText(entry.label);
716863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
717863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the data
718863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            TextView data = views.data;
719863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (data != null) {
720863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                if (entry.mimetype.equals(Phone.CONTENT_ITEM_TYPE)
721863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                        || entry.mimetype.equals(Constants.MIME_SMS_ADDRESS)) {
722863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    data.setText(PhoneNumberUtils.formatNumber(entry.data));
723863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else {
724863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    data.setText(entry.data);
725863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                }
726863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                setMaxLines(data, entry.maxLines);
727863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
728863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
729863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the footer
730863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (!TextUtils.isEmpty(entry.footerLine)) {
731863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.footer.setText(entry.footerLine);
732863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.footer.setVisibility(View.VISIBLE);
733863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
734863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.footer.setVisibility(View.GONE);
735863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
736863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
737863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the primary icon
738863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            views.primaryIcon.setVisibility(entry.isPrimary ? View.VISIBLE : View.GONE);
739863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
740863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the action icon
741863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ImageView action = views.actionIcon;
742863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (entry.actionIcon != -1) {
743863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                Drawable actionIcon;
744863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                if (entry.resPackageName != null) {
745863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    // Load external resources through PackageManager
746863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    actionIcon = mContext.getPackageManager().getDrawable(entry.resPackageName,
747863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                            entry.actionIcon, null);
748863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                } else {
749863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    actionIcon = resources.getDrawable(entry.actionIcon);
750863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                }
751863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                action.setImageDrawable(actionIcon);
752863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                action.setVisibility(View.VISIBLE);
753863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
754863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                // Things should still line up as if there was an icon, so make it invisible
755863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                action.setVisibility(View.INVISIBLE);
756863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
757863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
758863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the presence icon
759863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
760863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                    mContext, entry.presence);
761863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ImageView presenceIconView = views.presenceIcon;
762863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (presenceIcon != null) {
763863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                presenceIconView.setImageDrawable(presenceIcon);
764863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                presenceIconView.setVisibility(View.VISIBLE);
765863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
766863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                presenceIconView.setVisibility(View.GONE);
767863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
768863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
769863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            // Set the secondary action button
770863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            ImageView secondaryActionView = views.secondaryActionButton;
771863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            Drawable secondaryActionIcon = null;
772863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (entry.secondaryActionIcon != -1) {
773863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                secondaryActionIcon = resources.getDrawable(entry.secondaryActionIcon);
774863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
775863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (entry.secondaryIntent != null && secondaryActionIcon != null) {
776863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                secondaryActionView.setImageDrawable(secondaryActionIcon);
777863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                secondaryActionView.setTag(entry);
778863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                secondaryActionView.setVisibility(View.VISIBLE);
779863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.secondaryActionDivider.setVisibility(View.VISIBLE);
780863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
781863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                secondaryActionView.setVisibility(View.GONE);
782863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                views.secondaryActionDivider.setVisibility(View.GONE);
783863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
784863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
785863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton
786863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        private void setMaxLines(TextView textView, int maxLines) {
787863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            if (maxLines == 1) {
788863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                textView.setSingleLine(true);
789863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                textView.setEllipsize(TextUtils.TruncateAt.END);
790863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            } else {
791863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                textView.setSingleLine(false);
792863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                textView.setMaxLines(maxLines);
793863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton                textView.setEllipsize(null);
794863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton            }
795863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton        }
796863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton    }
797863e7a55dc45cd1210e4d07e5847f48dfe301876Jeff Hamilton}
798