16b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee/*
2dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee * Copyright (C) 2013 The Android Open Source Project
36b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee *
46b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Licensed under the Apache License, Version 2.0 (the "License");
56b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * you may not use this file except in compliance with the License.
66b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * You may obtain a copy of the License at
76b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee *
86b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee *      http://www.apache.org/licenses/LICENSE-2.0
96b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee *
106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Unless required by applicable law or agreed to in writing, software
116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * distributed under the License is distributed on an "AS IS" BASIS,
126b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * See the License for the specific language governing permissions and
146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * limitations under the License.
156b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */
166b049128c51b90e17ae14856d98130a22d3a5433Yorke Leepackage com.android.dialer.list;
176b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
185b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.Animator;
195b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.AnimatorSet;
204fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chenimport android.animation.ArgbEvaluator;
215b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wangimport android.animation.ObjectAnimator;
224fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chenimport android.animation.ValueAnimator;
236b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.Activity;
246b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.Fragment;
256b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.app.LoaderManager;
2621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport android.content.Context;
276b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.content.CursorLoader;
286b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.content.Loader;
2921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport android.content.SharedPreferences;
30fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Leeimport android.content.res.Resources;
316b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.database.Cursor;
326b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.graphics.Rect;
336b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.net.Uri;
346b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.os.Bundle;
35c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Chengimport android.provider.CallLog;
366b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.util.Log;
376b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.LayoutInflater;
386b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.View;
39c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport android.view.ViewTreeObserver;
406b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.View.OnClickListener;
416b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.view.ViewGroup;
426b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AbsListView;
436b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AdapterView;
446b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.AdapterView.OnItemClickListener;
454911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wangimport android.widget.ImageView;
466b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport android.widget.ListView;
473eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Leeimport android.widget.RelativeLayout;
483eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Leeimport android.widget.RelativeLayout.LayoutParams;
496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
506b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.ContactPhotoManager;
516b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.ContactTileLoaderFactory;
52dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.contacts.common.GeoUtil;
53c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport com.android.contacts.common.list.ContactEntry;
54fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Leeimport com.android.contacts.common.list.ContactListItemView;
556b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.contacts.common.list.ContactTileView;
5621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport com.android.dialer.DialtactsActivity;
576b049128c51b90e17ae14856d98130a22d3a5433Yorke Leeimport com.android.dialer.R;
5821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Leeimport com.android.dialer.calllog.CallLogQuery;
59dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.dialer.calllog.ContactInfoHelper;
60fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Leeimport com.android.dialer.calllog.CallLogAdapter;
61dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Leeimport com.android.dialer.calllog.CallLogQueryHandler;
62c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
63704acc087ce359295475a46695c2821c55778344Chiao Chengimport com.android.dialerbind.ObjectFactory;
64c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
65c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport java.util.ArrayList;
66c36684277aa45085999284bfe71cb8be71b3a464Yorke Leeimport java.util.HashMap;
676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee/**
696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * Fragment for Phone UI's favorite screen.
706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee *
716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all"
726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * contacts. To show them at once, this merges results from {@link com.android.contacts.common.list.ContactTileAdapter} and
736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * {@link com.android.contacts.common.list.PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}.
746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee * A contact filter header is also inserted between those adapters' results.
756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee */
768898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Leepublic class PhoneFavoriteFragment extends Fragment implements OnItemClickListener,
77c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher,
78c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener {
79c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
804ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee    /**
814ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     * By default, the animation code assumes that all items in a list view are of the same height
824ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     * when animating new list items into view (e.g. from the bottom of the screen into view).
834ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     * This can cause incorrect translation offsets when a item that is larger or smaller than
844ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     * other list item is removed from the list. This key is used to provide the actual height
854ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     * of the removed object so that the actual translation appears correct to the user.
864ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee     */
874ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee    private static final long KEY_REMOVED_ITEM_HEIGHT = Long.MAX_VALUE;
884ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee
898898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Lee    private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
903ed80a357d780310777178ad589d7771d4f7bf2dYorke Lee    private static final boolean DEBUG = false;
91c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
924911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang    private int mAnimationDuration;
936b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
946b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    /**
956b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     * Used with LoaderManager.
966b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     */
976b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private static int LOADER_ID_CONTACT_TILE = 1;
98c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng    private static int MISSED_CALL_LOADER = 2;
996b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
10021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    private static final String KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE =
10121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee            "key_last_dismissed_call_shortcut_date";
10221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
1038dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee    public interface OnShowAllContactsListener {
1048dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee        public void onShowAllContacts();
1058dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee    }
1068dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee
1076b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public interface Listener {
1086b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onContactSelected(Uri contactUri);
1096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onCallNumberDirectly(String phoneNumber);
1106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
1116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
112c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng    private class MissedCallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
113c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng
114c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        @Override
115c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
116c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng            final Uri uri = CallLog.Calls.CONTENT_URI;
117c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng            final String[] projection = new String[] {CallLog.Calls.TYPE};
118c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng            final String selection = CallLog.Calls.TYPE + " = " + CallLog.Calls.MISSED_TYPE +
119c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng                    " AND " + CallLog.Calls.IS_READ + " = 0";
120c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng            return new CursorLoader(getActivity(), uri, projection, selection, null, null);
121c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        }
122c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng
123c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        @Override
124c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) {
125c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng            mCallLogAdapter.setMissedCalls(data);
126c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        }
127c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng
128c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        @Override
129c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        public void onLoaderReset(Loader<Cursor> cursorLoader) {
130c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        }
131c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng    }
132c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng
1336b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
1346b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1356b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public CursorLoader onCreateLoader(int id, Bundle args) {
1366b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader.");
1376b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity());
1386b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1396b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1406b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1416b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
1426b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished");
1436b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            mContactTileAdapter.setContactCursor(data);
1444fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen            setEmptyViewVisibility(mContactTileAdapter.getCount() == 0);
1456b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1466b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1476b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1486b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onLoaderReset(Loader<Cursor> loader) {
1496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. ");
1506b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1516b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
1526b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1536b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private class ContactTileAdapterListener implements ContactTileView.Listener {
1546b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1556b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onContactSelected(Uri contactUri, Rect targetRect) {
1566b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            if (mListener != null) {
1576b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee                mListener.onContactSelected(contactUri);
1586b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            }
1596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1616b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1626b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onCallNumberDirectly(String phoneNumber) {
1636b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            if (mListener != null) {
1646b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee                mListener.onCallNumberDirectly(phoneNumber);
1656b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            }
1666b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public int getApproximateTileWidth() {
1706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            return getView().getWidth() / mContactTileAdapter.getColumnCount();
1716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
1736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private class ScrollListener implements ListView.OnScrollListener {
1756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1766b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onScroll(AbsListView view,
1776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee                int firstVisibleItem, int visibleItemCount, int totalItemCount) {
1786b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        @Override
1816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        public void onScrollStateChanged(AbsListView view, int scrollState) {
182dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee            mActivityScrollListener.onListFragmentScrollStateChange(scrollState);
1836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
1846b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
1856b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
1866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private Listener mListener;
187dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee
188dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    private OnListFragmentScrolledListener mActivityScrollListener;
1898dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee    private OnShowAllContactsListener mShowAllContactsListener;
1908898cd0577d41cfa4e6acf785c9e904bd71fbdfdYorke Lee    private PhoneFavoriteMergedAdapter mAdapter;
191dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    private PhoneFavoritesTileAdapter mContactTileAdapter;
1926b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
193fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Lee    private CallLogAdapter mCallLogAdapter;
194dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    private CallLogQueryHandler mCallLogQueryHandler;
195dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee
1964fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen    private View mParentView;
1974fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen
198bf5b298b1a5752a56315131a22434185198370a8Hongwei Wang    private PhoneFavoriteListView mListView;
19918e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee
2006091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen    private View mShowAllContactsButton;
2014fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen    private View mShowAllContactsInEmptyViewButton;
2023eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee    private View mContactTileFrame;
2036b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2041f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen    private TileInteractionTeaserView mTileInteractionTeaserView;
2051f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen
206c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    private final HashMap<Long, Integer> mItemIdTopMap = new HashMap<Long, Integer>();
207c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    private final HashMap<Long, Integer> mItemIdLeftMap = new HashMap<Long, Integer>();
208c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
2096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    /**
21018e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee     * Layout used when there are no favorites.
2116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     */
21218e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee    private View mEmptyView;
2136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
21421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    /**
21521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee     * Call shortcuts older than this date (persisted in shared preferences) will not show up in
21621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee     * at the top of the screen
21721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee     */
21821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    private long mLastCallShortcutDate = 0;
21921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
22021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    /**
22121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee     * The date of the current call shortcut that is showing on screen.
22221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee     */
22321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    private long mCurrentCallShortcutDate = 0;
22421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
2256b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private final ContactTileView.Listener mContactTileAdapterListener =
2266b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            new ContactTileAdapterListener();
2276b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener =
2286b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            new ContactTileLoaderListener();
2296b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    private final ScrollListener mScrollListener = new ScrollListener();
2306b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2316b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
2326b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public void onAttach(Activity activity) {
2336b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        if (DEBUG) Log.d(TAG, "onAttach()");
2346b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        super.onAttach(activity);
2356b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2366b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
2376b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // We don't construct the resultant adapter at this moment since it requires LayoutInflater
2386b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // that will be available on onCreateView().
239dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener,
240c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                this,
241dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee                getResources().getInteger(R.integer.contact_tile_column_count_in_favorites_new),
242dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee                1);
2436b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
2446b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
2456b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2466b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
2476b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public void onCreate(Bundle savedState) {
2486b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        if (DEBUG) Log.d(TAG, "onCreate()");
2496b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        super.onCreate(savedState);
2506b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2514911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang        mAnimationDuration = getResources().getInteger(R.integer.fade_duration);
252dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(),
253dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee                this, 1);
254dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
255704acc087ce359295475a46695c2821c55778344Chiao Cheng        mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this,
256704acc087ce359295475a46695c2821c55778344Chiao Cheng                new ContactInfoHelper(getActivity(), currentCountryIso), true, false);
2576b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        setHasOptionsMenu(true);
2586b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
2596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
261dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    public void onResume() {
262dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        super.onResume();
26321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        final SharedPreferences prefs = getActivity().getSharedPreferences(
26421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee                DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
26521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
26621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        mLastCallShortcutDate = prefs.getLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, 0);
26721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
2684dc32bdf10bff18acbc1964d289354556950d2ebYorke Lee        fetchCalls();
269dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mCallLogAdapter.setLoading(true);
27011ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee        getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE).forceLoad();
2716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
2726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
2746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public View onCreateView(LayoutInflater inflater, ViewGroup container,
2756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            Bundle savedInstanceState) {
2764fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        mParentView = inflater.inflate(R.layout.phone_favorites_fragment, container, false);
2776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2784fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        mListView = (PhoneFavoriteListView) mParentView.findViewById(R.id.contact_tile_list);
2796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setItemsCanFocus(true);
2806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setOnItemClickListener(this);
2816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setVerticalScrollBarEnabled(false);
2826b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
2836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
28411ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee        mListView.setOnItemSwipeListener(mContactTileAdapter);
2857639fe9a3ecc9c197718a9f81d8a745d2f660cb3Hongwei Wang        mListView.setOnDragDropListener(mContactTileAdapter);
2866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
2874911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang        final ImageView dragShadowOverlay =
2884fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen                (ImageView) mParentView.findViewById(R.id.contact_tile_drag_shadow_overlay);
2894911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang        mListView.setDragShadowOverlay(dragShadowOverlay);
2904911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang
2914fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view);
2924fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen
2934fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        mShowAllContactsInEmptyViewButton = mParentView.findViewById(
2944fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen                R.id.show_all_contact_button_in_nofav);
295fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        prepareAllContactsButton(mShowAllContactsInEmptyViewButton);
29618e7fdd55f67e3636c161462cb54e7f5555a04deYorke Lee
2976091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen        mShowAllContactsButton = inflater.inflate(R.layout.show_all_contact_button, mListView,
2986091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen                false);
299fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee
300fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        prepareAllContactsButton(mShowAllContactsButton);
3016b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3023eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee        mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame);
3033eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee
3041f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen        mTileInteractionTeaserView = (TileInteractionTeaserView) inflater.inflate(
3051f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen                R.layout.tile_interactions_teaser_view, mListView, false);
3061f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen
30721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter,
3081f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen                mCallLogAdapter, mShowAllContactsButton, mTileInteractionTeaserView);
3091f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen
3101f06f0ad1229f3b4e00553c294e664ffa5234c90Christine Chen        mTileInteractionTeaserView.setAdapter(mAdapter);
3116b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3126b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setAdapter(mAdapter);
3136b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setOnScrollListener(mScrollListener);
3156b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setFastScrollEnabled(false);
3166b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        mListView.setFastScrollAlwaysVisible(false);
3176b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3184fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        return mParentView;
3196b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3206b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
321f420a5344995b2c450379159f679809690bc9880Yorke Lee    public boolean hasFrequents() {
322f420a5344995b2c450379159f679809690bc9880Yorke Lee        if (mContactTileAdapter == null) return false;
3236b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        return mContactTileAdapter.getNumFrequents() > 0;
3246b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3256b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3264fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen    /* package */ void setEmptyViewVisibility(final boolean visible) {
3274fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        final int previousVisibility = mEmptyView.getVisibility();
3284fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        final int newVisibility = visible ? View.VISIBLE : View.GONE;
3294fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen
3304fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        if (previousVisibility != newVisibility) {
3313eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee            final RelativeLayout.LayoutParams params = (LayoutParams) mContactTileFrame
3323eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee                    .getLayoutParams();
3333eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee            params.height = visible ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
3343eb8ab2ab09a9e742cde17e36381a6dde058c4beYorke Lee            mContactTileFrame.setLayoutParams(params);
335fe3fbd24097c51290b189f2788059c4083dd90a1Christine Chen            mEmptyView.setVisibility(newVisibility);
3364fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen        }
3374fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen    }
3384fdf594962b3928c6497b471dbb1ee7be56e18efChristine Chen
3396b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
3406b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public void onStart() {
3416b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        super.onStart();
3426b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
343dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        final Activity activity = getActivity();
344dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee
345dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        try {
346dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee            mActivityScrollListener = (OnListFragmentScrolledListener) activity;
347dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        } catch (ClassCastException e) {
348dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee            throw new ClassCastException(activity.toString()
349dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee                    + " must implement OnListFragmentScrolledListener");
350dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        }
3516b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3528dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee        try {
3538dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee            mShowAllContactsListener = (OnShowAllContactsListener) activity;
3548dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee        } catch (ClassCastException e) {
3558dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee            throw new ClassCastException(activity.toString()
3568dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee                    + " must implement OnShowAllContactsListener");
3578dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee        }
3588dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee
3596b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
3606b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
3616b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        // be called, on which we'll check if "all" contacts should be reloaded again or not.
3626b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
363c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng        getLoaderManager().initLoader(MISSED_CALL_LOADER, null, new MissedCallLogLoaderListener());
3646b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3656b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3666b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    /**
3676b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     * {@inheritDoc}
3686b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     *
3696b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     * This is only effective for elements provided by {@link #mContactTileAdapter}.
3706b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     * {@link #mContactTileAdapter} has its own logic for click events.
3716b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     */
3726b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    @Override
3736b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
3746b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        final int contactTileAdapterCount = mContactTileAdapter.getCount();
3756b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        if (position <= contactTileAdapterCount) {
3766b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee            Log.e(TAG, "onItemClick() event for unexpected position. "
3776b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee                    + "The position " + position + " is before \"all\" section. Ignored.");
3786b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee        }
3796b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3806b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
3816b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    /**
3826091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen     * Gets called when user click on the show all contacts button.
3836b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee     */
3846091473941d277ed3746143c1ca9bffdfbe2bd94Christine Chen    private void showAllContacts() {
3858dd6200bef2eb07486f4c7e288941cfcfed35e79Yorke Lee        mShowAllContactsListener.onShowAllContacts();
3866b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3876b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
388dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    public void setListener(Listener listener) {
389dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mListener = listener;
3906b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3916b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
392dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    @Override
393dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    public void onVoicemailStatusFetched(Cursor statusCursor) {
3944dc32bdf10bff18acbc1964d289354556950d2ebYorke Lee        // no-op
3956b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
3966b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
397dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    @Override
398dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    public void onCallsFetched(Cursor cursor) {
3994ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee        animateListView();
400dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mCallLogAdapter.setLoading(false);
40121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
40221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        // Save the date of the most recent call log item
40321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        if (cursor != null && cursor.moveToFirst()) {
40421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee            mCurrentCallShortcutDate = cursor.getLong(CallLogQuery.DATE);
40521299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        }
40621299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
407dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mCallLogAdapter.changeCursor(cursor);
408dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee        mAdapter.notifyDataSetChanged();
4096b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
4106b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee
411dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    @Override
412dfb2eee7d98f8540fd1614db66bb03e8e1f3a26aYorke Lee    public void fetchCalls() {
41321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL, mLastCallShortcutDate);
4146b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee    }
41511ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee
41611ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee    @Override
41711ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee    public void onPause() {
41811ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee        // If there are any pending contact entries that are to be removed, remove them
41911ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee        mContactTileAdapter.removePendingContactEntry();
4203b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee        // Wipe the cache to refresh the call shortcut item. This is not that expensive because
4213b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee        // it only contains one item.
4223b9d09c50b6ed52cbfe6d87cee06ecef5116d799Yorke Lee        mCallLogAdapter.invalidateCache();
42311ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee        super.onPause();
42411ee58b1b8711c6d3b2ade6a71835b6c102a08a7Yorke Lee    }
425c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
426c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    /**
427c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     * Saves the current view offsets into memory
428c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     */
429c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    @SuppressWarnings("unchecked")
4304ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee    private void saveOffsets(int removedItemHeight) {
431c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        final int firstVisiblePosition = mListView.getFirstVisiblePosition();
432c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        if (DEBUG) {
433c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            Log.d(TAG, "Child count : " + mListView.getChildCount());
434c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
435c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        for (int i = 0; i < mListView.getChildCount(); i++) {
436c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final View child = mListView.getChildAt(i);
437c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final int position = firstVisiblePosition + i;
438c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final long itemId = mAdapter.getItemId(position);
439c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final int itemViewType = mAdapter.getItemViewType(position);
440c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
441c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                // This is a tiled row, so save horizontal offsets instead
442c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>)
4434ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                        mAdapter.getItem(position));
444c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
445c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            if (DEBUG) {
446c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: "
447c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                        + child.getTop());
448c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
449c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            mItemIdTopMap.put(itemId, child.getTop());
450c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
4514ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee
4524ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee        mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight);
453c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
454c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
4554ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee    private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list) {
456c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        for (int i = 0; i < list.size(); i++) {
457c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final View child = row.getChildAt(i);
458c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final ContactEntry entry = list.get(i);
459c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);
460c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            if (DEBUG) {
461c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: "
462c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                        + child.getTop());
463c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
464c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            mItemIdLeftMap.put(itemId, child.getLeft());
465c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
466c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
467c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
468c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    /*
469c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     * Performs a animations for a row of tiles
470c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     */
471c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    private void performHorizontalAnimations(ContactTileRow row, ArrayList<ContactEntry> list,
472c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            long[] idsInPlace) {
473c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        if (mItemIdLeftMap.isEmpty()) {
474c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            return;
475c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
4765b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang        final AnimatorSet animSet = new AnimatorSet();
4775b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang        final ArrayList<Animator> animators = new ArrayList<Animator>();
478c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        for (int i = 0; i < list.size(); i++) {
479c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final View child = row.getChildAt(i);
480c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final ContactEntry entry = list.get(i);
481c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);
482c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
4834911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang            if (containsId(idsInPlace, itemId)) {
4845b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                animators.add(ObjectAnimator.ofFloat(
4855b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        child, "alpha", 0.0f, 1.0f));
4864911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang                break;
4875b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang            } else {
4885b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                Integer startLeft = mItemIdLeftMap.get(itemId);
4895b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                int left = child.getLeft();
4905b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                if (startLeft != null) {
4915b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    if (startLeft != left) {
4925b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        int delta = startLeft - left;
4935b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        if (DEBUG) {
4945b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i +
4955b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                    " Left: " + left +
4965b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                    " Delta: " + delta);
4975b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        }
4985b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        animators.add(ObjectAnimator.ofFloat(
4995b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                child, "translationX", delta, 0.0f));
5005b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    }
5015b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                } else {
5025b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    // In case the last square row is pushed up from the non-square section.
5035b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    animators.add(ObjectAnimator.ofFloat(
5045b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            child, "translationX", left, 0.0f));
5055b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                }
506c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
507c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
5085b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang        if (animators.size() > 0) {
5095b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang            animSet.setDuration(mAnimationDuration).playTogether(animators);
5105b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang            animSet.start();
5115b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang        }
512c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
513c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
514c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    /*
515c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     * Performs animations for the list view. If the list item is a row of tiles, horizontal
516c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     * animations will be performed instead.
517c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee     */
518c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    private void animateListView(final long... idsInPlace) {
51920d682f9a586da495f180bfb6a445520d027c74dHongwei Wang        if (mItemIdTopMap.isEmpty()) {
520c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            // Don't do animations if the database is being queried for the first time and
521c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            // the previous item offsets have not been cached, or the user hasn't done anything
522c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            // (dragging, swiping etc) that requires an animation.
523c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            return;
524c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
5254ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee
5264ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee        final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT);
5274ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee
528c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        final ViewTreeObserver observer = mListView.getViewTreeObserver();
529c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
530c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            @SuppressWarnings("unchecked")
531c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            @Override
532c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            public boolean onPreDraw() {
533c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                observer.removeOnPreDrawListener(this);
534c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                final int firstVisiblePosition = mListView.getFirstVisiblePosition();
5355b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                final AnimatorSet animSet = new AnimatorSet();
5365b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                final ArrayList<Animator> animators = new ArrayList<Animator>();
537c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                for (int i = 0; i < mListView.getChildCount(); i++) {
538c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    final View child = mListView.getChildAt(i);
539c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    int position = firstVisiblePosition + i;
540c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    final int itemViewType = mAdapter.getItemViewType(position);
541c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
542c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                        // This is a tiled row, so perform horizontal animations instead
543c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                        performHorizontalAnimations((ContactTileRow) child, (
544c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                                ArrayList<ContactEntry>) mAdapter.getItem(position), idsInPlace);
545c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    }
546c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
547c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    final long itemId = mAdapter.getItemId(position);
548c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
5494911300ae3fa7ab186ee271f8bc431b65a819a3cHongwei Wang                    if (containsId(idsInPlace, itemId)) {
5505b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        animators.add(ObjectAnimator.ofFloat(
5515b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                child, "alpha", 0.0f, 1.0f));
5525b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        break;
553f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                    } else {
554f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        Integer startTop = mItemIdTopMap.get(itemId);
555f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        final int top = child.getTop();
556f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        int delta = 0;
557f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        if (startTop != null) {
558f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            if (startTop != top) {
559f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                                delta = startTop - top;
560f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            }
561f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        } else if (!mItemIdLeftMap.containsKey(itemId)) {
562f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            // Animate new views along with the others. The catch is that they did
563f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            // not exist in the start state, so we must calculate their starting
564f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            // position based on neighboring views.
5654ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee
5664ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                            final int itemHeight;
5674ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                            if (removedItemHeight == 0) {
5684ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                                itemHeight = child.getHeight() + mListView.getDividerHeight();
5694ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                            } else {
5704ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                                itemHeight = removedItemHeight;
5714ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                            }
5724ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee                            startTop = top + (i > 0 ? itemHeight : -itemHeight);
573f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                            delta = startTop - top;
5745b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        } else {
57520d682f9a586da495f180bfb6a445520d027c74dHongwei Wang                            // In case the first non-square row is pushed down
5765b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            // from the square section.
5775b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            animators.add(ObjectAnimator.ofFloat(
57820d682f9a586da495f180bfb6a445520d027c74dHongwei Wang                                    child, "alpha", 0.0f, 1.0f));
5795b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        }
5805b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                        if (DEBUG) {
5815b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
5825b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                    " Top: " + top +
5835b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                    " Delta: " + delta);
584f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        }
585f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira
586f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        if (delta != 0) {
5875b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                            animators.add(ObjectAnimator.ofFloat(
5885b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                                    child, "translationY", delta, 0.0f));
589f59250951cf47d81fda125e9bab324d66ed75214Mindy Pereira                        }
590c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                    }
591c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                }
5925b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang
5935b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                if (animators.size() > 0) {
5945b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    animSet.setDuration(mAnimationDuration).playTogether(animators);
5955b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                    animSet.start();
5965b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang                }
5975b2e21098d84e94fd629e5e07c3bbb66bf9b5d95Hongwei Wang
598c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                mItemIdTopMap.clear();
599c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                mItemIdLeftMap.clear();
600c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                return true;
601c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
602c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        });
603c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
604c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
605c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    private boolean containsId(long[] ids, long target) {
606c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        // Linear search on array is fine because this is typically only 0-1 elements long
607c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        for (int i = 0; i < ids.length; i++) {
608c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            if (ids[i] == target) {
609c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee                return true;
610c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee            }
611c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        }
612c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        return false;
613c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
614c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
615c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    @Override
616c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    public void onDataSetChangedForAnimation(long... idsInPlace) {
617c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee        animateListView(idsInPlace);
618c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
619c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee
620c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    @Override
621c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    public void cacheOffsetsForDatasetChange() {
6224ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee        saveOffsets(0);
623c36684277aa45085999284bfe71cb8be71b3a464Yorke Lee    }
62421299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee
6254ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee    public void dismissShortcut(int height) {
6264ed7db87e6c0e71b2f656e77de938f3579bc36bfYorke Lee        saveOffsets(height);
62721299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        mLastCallShortcutDate = mCurrentCallShortcutDate;
62821299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        final SharedPreferences prefs = getActivity().getSharedPreferences(
62921299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee                DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
63021299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        prefs.edit().putLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, mLastCallShortcutDate)
63121299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee                .apply();
63221299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee        fetchCalls();
63321299c354c4178dd8f89eef42872cbd62cd4aaf0Yorke Lee    }
634fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee
635fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee    /**
636fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee     * Returns a view that is laid out and styled to look like a regular contact, with the correct
637fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee     * click behavior (to launch the all contacts activity when it is clicked).
638fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee     */
639fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee    private View prepareAllContactsButton(View v) {
640fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        final ContactListItemView view = (ContactListItemView) v;
641fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setOnClickListener(new OnClickListener() {
642fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee            @Override
643fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee            public void onClick(View view) {
644fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                showAllContacts();
645fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee            }
646fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        });
647fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee
648fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
649fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        final Resources resources = getResources();
650fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setBackgroundResource(R.drawable.contact_list_item_background);
651fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee
652fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setPaddingRelative(
653fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                resources.getDimensionPixelSize(R.dimen.favorites_row_start_padding),
654fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                resources.getDimensionPixelSize(R.dimen.favorites_row_end_padding),
655fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                resources.getDimensionPixelSize(R.dimen.favorites_row_top_padding),
656fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                resources.getDimensionPixelSize(R.dimen.favorites_row_bottom_padding));
657fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee
658fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setDisplayName(resources.getString(R.string.show_all_contacts_button_text));
659fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        view.setDrawableResource(R.drawable.list_item_avatar_bg,
660fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee                R.drawable.ic_menu_all_contacts_dk);
661fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee        return view;
662fb34fdaeb60eaa20dbc825983edc17b45d879440Yorke Lee    }
6636b049128c51b90e17ae14856d98130a22d3a5433Yorke Lee}
664