194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/* 294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Copyright (C) 2011 The Android Open Source Project 394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * you may not use this file except in compliance with the License. 694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * You may obtain a copy of the License at 794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 1094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Unless required by applicable law or agreed to in writing, software 1194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 1294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * See the License for the specific language governing permissions and 1494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * limitations under the License. 1594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 1694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpackage com.android.dialer.calllog; 1894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 195f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwellimport com.google.common.annotations.VisibleForTesting; 205f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell 2194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.Context; 22c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Chengimport android.content.Intent; 23bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chenimport android.content.SharedPreferences; 2494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.res.Resources; 2594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.database.Cursor; 2694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.net.Uri; 27267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Leeimport android.os.Bundle; 2849efd91e50a11dc7bdef8382a0ceac01bc060f77Andrew Leeimport android.os.Trace; 29bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chenimport android.preference.PreferenceManager; 3003aaf3894d8af53f241d1189c504e44c538100d4Nancy Chenimport android.provider.CallLog; 315f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwellimport android.provider.ContactsContract.CommonDataKinds.Phone; 325f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwellimport android.support.v7.widget.RecyclerView; 33492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Leeimport android.support.v7.widget.RecyclerView.ViewHolder; 349dc924c8bcc0bc8d996452e9ce3215b5f064962eTyler Gunnimport android.telecom.PhoneAccountHandle; 351e5325f43c98a92f8bfec1dbd9db3d32a91835e9Ihab Awadimport android.telephony.PhoneNumberUtils; 36bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chenimport android.telephony.TelephonyManager; 3794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.TextUtils; 38486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaaimport android.util.ArrayMap; 3994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.LayoutInflater; 4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.View; 41b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Leeimport android.view.View.AccessibilityDelegate; 4294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.ViewGroup; 43b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Leeimport android.view.accessibility.AccessibilityEvent; 4494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 45240523d3e1b4502326c8d0d313dd1787aa8ff024Victor Changimport com.android.contacts.common.ContactsUtils; 4617df9323e45ae5984b6df25b788a9cbffb51e8abBrandon Maxwellimport com.android.contacts.common.compat.CompatUtils; 478104b41f9ca85c2615e9aa52cb012b5868a0314fBrandon Maxwellimport com.android.contacts.common.compat.PhoneNumberUtilsCompat; 485f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwellimport com.android.contacts.common.preference.ContactsPreferences; 49c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Leeimport com.android.contacts.common.util.PermissionsUtil; 5017df9323e45ae5984b6df25b788a9cbffb51e8abBrandon Maxwellimport com.android.dialer.DialtactsActivity; 5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.PhoneCallDetails; 529554500572ba82fbd7adb0a1637206ef870ef09eChiao Chengimport com.android.dialer.R; 5337aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chenimport com.android.dialer.calllog.calllogcache.CallLogCache; 5474479d448bc39c3534585a627fba603aa89e93caAndrew Leeimport com.android.dialer.contactinfo.ContactInfoCache; 5574479d448bc39c3534585a627fba603aa89e93caAndrew Leeimport com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener; 569bd094118e920b732394c29657f26b062f3e916bAnne Rongimport com.android.dialer.database.FilteredNumberAsyncQueryHandler; 5717df9323e45ae5984b6df25b788a9cbffb51e8abBrandon Maxwellimport com.android.dialer.database.VoicemailArchiveContract; 58d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwellimport com.android.dialer.filterednumber.BlockNumberDialogFragment.Callback; 59d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwellimport com.android.dialer.logging.InteractionEvent; 60d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwellimport com.android.dialer.logging.Logger; 61486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaaimport com.android.dialer.service.ExtendedBlockingButtonRenderer; 62d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Leeimport com.android.dialer.util.PhoneNumberUtil; 63267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Leeimport com.android.dialer.voicemail.VoicemailPlaybackPresenter; 6456cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 65146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunnimport java.util.HashMap; 66486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaaimport java.util.Map; 6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/** 6994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Adapter class to fill in data for the Call Log. 7094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 71fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Leepublic class CallLogAdapter extends GroupingListAdapter 72601eadd8518b2a3683c50850af2a6db8147ec61aYorke Lee implements CallLogGroupBuilder.GroupCreator, 73486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa VoicemailPlaybackPresenter.OnVoicemailDeletedListener, 74486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa ExtendedBlockingButtonRenderer.Listener { 75c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 766b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi // Types of activities the call log adapter is used for 776b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi public static final int ACTIVITY_TYPE_CALL_LOG = 1; 786b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi public static final int ACTIVITY_TYPE_ARCHIVE = 2; 796b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi public static final int ACTIVITY_TYPE_DIALTACTS = 3; 806b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 8194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Interface used to initiate a refresh of the content. */ 8294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public interface CallFetcher { 8394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void fetchCalls(); 8494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 8594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 86affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee private static final int NO_EXPANDED_LIST_ITEM = -1; 87dfc69c43df7c46fb6f059c3ac7f61badd2a4b820Andrew Lee // ConcurrentHashMap doesn't store null values. Use this value for numbers which aren't blocked. 88dfc69c43df7c46fb6f059c3ac7f61badd2a4b820Andrew Lee private static final int NOT_BLOCKED = -1; 898ef8020b8b792026a8dd15e029055f7d5e2d48f6Tyler Gunn 90bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private static final int VOICEMAIL_PROMO_CARD_POSITION = 0; 91ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee 92ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee protected static final int VIEW_TYPE_NORMAL = 0; 93ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee private static final int VIEW_TYPE_VOICEMAIL_PROMO_CARD = 1; 94bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 95bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 96bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * The key for the show voicemail promo card preference which will determine whether the promo 97bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * card was permanently dismissed or not. 98bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 99bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private static final String SHOW_VOICEMAIL_PROMO_CARD = "show_voicemail_promo_card"; 100bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private static final boolean SHOW_VOICEMAIL_PROMO_CARD_DEFAULT = true; 101bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 102704acc087ce359295475a46695c2821c55778344Chiao Cheng protected final Context mContext; 10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final ContactInfoHelper mContactInfoHelper; 104a4adb2c035690a1c9600a20c2485886d9d5991d0Andrew Lee protected final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; 10594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final CallFetcher mCallFetcher; 1069bd094118e920b732394c29657f26b062f3e916bAnne Rong private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; 107486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa private final Map<String, Boolean> mBlockedNumberCache = new ArrayMap<>(); 10894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 10974479d448bc39c3534585a627fba603aa89e93caAndrew Lee protected ContactInfoCache mContactInfoCache; 11094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1116b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi private final int mActivityType; 11269705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee 113267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee private static final String KEY_EXPANDED_POSITION = "expanded_position"; 114267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee private static final String KEY_EXPANDED_ROW_ID = "expanded_row_id"; 115267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee 116affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // Tracks the position of the currently expanded list item. 117affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee private int mCurrentlyExpandedPosition = RecyclerView.NO_POSITION; 118affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // Tracks the rowId of the currently expanded list item, so the position can be updated if there 119affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // are any changes to the call log entries, such as additions or removals. 120affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee private long mCurrentlyExpandedRowId = NO_EXPANDED_LIST_ITEM; 1212d588b857347fda465a963742c4f61e4014f3441Nancy Chen private int mHiddenPosition = RecyclerView.NO_POSITION; 1222d588b857347fda465a963742c4f61e4014f3441Nancy Chen private Uri mHiddenItemUri = null; 1232d588b857347fda465a963742c4f61e4014f3441Nancy Chen private boolean mPendingHide = false; 124146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn 12594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 1264dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Hashmap, keyed by call Id, used to track the day group for a call. As call log entries are 1274dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * put into the primary call groups in {@link com.android.dialer.calllog.CallLogGroupBuilder}, 1284dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * they are also assigned a secondary "day group". This hashmap tracks the day group assigned 1294dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * to all calls in the call log. This information is used to trigger the display of a day 1304dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * group header above the call log entry at the start of a day group. 1314dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Note: Multiple calls are grouped into a single primary "call group" in the call log, and 1324dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * the cursor used to bind rows includes all of these calls. When determining if a day group 1334dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * change has occurred it is necessary to look at the last entry in the call log to determine 1344dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * its day group. This hashmap provides a means of determining the previous day group without 1354dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * having to reverse the cursor to the start of the previous day call log entry. 1364dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 1375f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell private HashMap<Long, Integer> mDayGroups = new HashMap<>(); 1384dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 13994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean mLoading = true; 14094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 141bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private SharedPreferences mPrefs; 142bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 1435f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell private ContactsPreferences mContactsPreferences; 1445f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell 1450599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee protected boolean mShowVoicemailPromoCard = false; 146bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 14794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Instance of helper class for managing views. */ 148d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee private final CallLogListItemHelper mCallLogListItemHelper; 149d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee 15037aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen /** Cache for repeated requests to Telecom/Telephony. */ 15137aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen protected final CallLogCache mCallLogCache; 15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Helper to group call log entries. */ 15494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final CallLogGroupBuilder mCallLogGroupBuilder; 15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 156146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn /** 157affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee * The OnClickListener used to expand or collapse the action buttons of a call log entry. 158146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn */ 159146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn private final View.OnClickListener mExpandCollapseListener = new View.OnClickListener() { 160146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn @Override 161146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn public void onClick(View v) { 162affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) v.getTag(); 163affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee if (viewHolder == null) { 164affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee return; 165affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } 166affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee 167053b9c7a4b2662588706211fd8aa1f8a03ec2901Andrew Lee if (mVoicemailPlaybackPresenter != null) { 168053b9c7a4b2662588706211fd8aa1f8a03ec2901Andrew Lee // Always reset the voicemail playback state on expand or collapse. 16985647649a10d680faeb2e73a3d191191058b7d66Nancy Chen mVoicemailPlaybackPresenter.resetAll(); 170053b9c7a4b2662588706211fd8aa1f8a03ec2901Andrew Lee } 171bae7b937b6cf6e7eb26d07bec95de38083923614Andrew Lee 172affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee if (viewHolder.getAdapterPosition() == mCurrentlyExpandedPosition) { 173affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // Hide actions, if the clicked item is the expanded item. 1742f05af35af03de67c1c474cd148719b24fac3552Andrew Lee viewHolder.showActions(false); 175bae7b937b6cf6e7eb26d07bec95de38083923614Andrew Lee 176affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee mCurrentlyExpandedPosition = RecyclerView.NO_POSITION; 177affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee mCurrentlyExpandedRowId = NO_EXPANDED_LIST_ITEM; 178affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } else { 179cdc14da9275c67d123b55e668f48f73c4b58d948Sarmad Hashmi if (viewHolder.callType == CallLog.Calls.MISSED_TYPE) { 180cdc14da9275c67d123b55e668f48f73c4b58d948Sarmad Hashmi CallLogAsyncTaskUtil.markCallAsRead(mContext, viewHolder.callIds); 1816b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi if (mActivityType == ACTIVITY_TYPE_DIALTACTS) { 182cb55981252b49e476e1adf9f2d5ec19a658d2aa4Sarmad Hashmi ((DialtactsActivity) v.getContext()).updateTabUnreadCounts(); 183cb55981252b49e476e1adf9f2d5ec19a658d2aa4Sarmad Hashmi } 184cdc14da9275c67d123b55e668f48f73c4b58d948Sarmad Hashmi } 185affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee expandViewHolderActions(viewHolder); 186affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } 187affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee 188b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee } 189b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee }; 19068e771378889a479a80aac29a9ec2136b7ef27b6Tyler Gunn 191bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 192bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Click handler used to dismiss the promo card when the user taps the "ok" button. 193bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 194bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private final View.OnClickListener mOkActionListener = new View.OnClickListener() { 195bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen @Override 196bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen public void onClick(View view) { 197bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen dismissVoicemailPromoCard(); 198bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 199bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen }; 200bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 201bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 202bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Click handler used to send the user to the voicemail settings screen and then dismiss the 203bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * promo card. 204bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 205bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private final View.OnClickListener mVoicemailSettingsActionListener = 206bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen new View.OnClickListener() { 207bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen @Override 208bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen public void onClick(View view) { 209bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL); 210bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen mContext.startActivity(intent); 211bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen dismissVoicemailPromoCard(); 212bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 213bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen }; 214bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 215affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee private void expandViewHolderActions(CallLogListItemViewHolder viewHolder) { 216affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // If another item is expanded, notify it that it has changed. Its actions will be 217affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // hidden when it is re-binded because we change mCurrentlyExpandedPosition below. 218affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee if (mCurrentlyExpandedPosition != RecyclerView.NO_POSITION) { 219affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee notifyItemChanged(mCurrentlyExpandedPosition); 220affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } 221affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee // Show the actions for the clicked list item. 2222f05af35af03de67c1c474cd148719b24fac3552Andrew Lee viewHolder.showActions(true); 223affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee mCurrentlyExpandedPosition = viewHolder.getAdapterPosition(); 224affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee mCurrentlyExpandedRowId = viewHolder.rowId; 225affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } 22674479d448bc39c3534585a627fba603aa89e93caAndrew Lee 227affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee /** 228affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee * Expand the actions on a list item when focused in Talkback mode, to aid discoverability. 229affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee */ 230b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() { 231b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee @Override 232c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee public boolean onRequestSendAccessibilityEvent( 233c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee ViewGroup host, View child, AccessibilityEvent event) { 234b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) { 235c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee // Only expand if actions are not already expanded, because triggering the expand 236c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee // function on clicks causes the action views to lose the focus indicator. 237c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) host.getTag(); 238cdd20a38dd669fea7de380fdc58fb526cb8d6581Nancy Chen if (mCurrentlyExpandedPosition != viewHolder.getAdapterPosition()) { 239d9c364df22e3f75d029ec12185f44fedb1aeacb1Nancy Chen if (mVoicemailPlaybackPresenter != null) { 240d9c364df22e3f75d029ec12185f44fedb1aeacb1Nancy Chen // Always reset the voicemail playback state on expand. 241d9c364df22e3f75d029ec12185f44fedb1aeacb1Nancy Chen mVoicemailPlaybackPresenter.resetAll(); 242d9c364df22e3f75d029ec12185f44fedb1aeacb1Nancy Chen } 243d9c364df22e3f75d029ec12185f44fedb1aeacb1Nancy Chen 244c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee expandViewHolderActions((CallLogListItemViewHolder) host.getTag()); 245c940eada912f952a95d693ae6aab48ef08ef7319Andrew Lee } 24668e771378889a479a80aac29a9ec2136b7ef27b6Tyler Gunn } 247b359699a1dd96a4581a47b11ef2a85ec4a8a9433Yorke Lee return super.onRequestSendAccessibilityEvent(host, child, event); 248146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn } 249146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn }; 250146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn 251affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee protected final OnContactInfoChangedListener mOnContactInfoChangedListener = 252affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee new OnContactInfoChangedListener() { 253affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee @Override 254affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee public void onContactInfoChanged() { 255affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee notifyDataSetChanged(); 256affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee } 257affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee }; 258affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee 259c6fde8d1b9a4e586ca65b82e9911089a9da14508Andrew Lee public CallLogAdapter( 260c6fde8d1b9a4e586ca65b82e9911089a9da14508Andrew Lee Context context, 261c6fde8d1b9a4e586ca65b82e9911089a9da14508Andrew Lee CallFetcher callFetcher, 262c6fde8d1b9a4e586ca65b82e9911089a9da14508Andrew Lee ContactInfoHelper contactInfoHelper, 263267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee VoicemailPlaybackPresenter voicemailPlaybackPresenter, 2646b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi int activityType) { 26594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng super(context); 26694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 26794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContext = context; 26894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallFetcher = callFetcher; 26994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContactInfoHelper = contactInfoHelper; 270267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee mVoicemailPlaybackPresenter = voicemailPlaybackPresenter; 2710bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee if (mVoicemailPlaybackPresenter != null) { 2720bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee mVoicemailPlaybackPresenter.setOnVoicemailDeletedListener(this); 2730bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee } 2746b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 2756b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi mActivityType = activityType; 276b77bf5df2b866dd40e330b7c2dedee4a1d51fc78Sai Cheemalapati 27774479d448bc39c3534585a627fba603aa89e93caAndrew Lee mContactInfoCache = new ContactInfoCache( 27874479d448bc39c3534585a627fba603aa89e93caAndrew Lee mContactInfoHelper, mOnContactInfoChangedListener); 279c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee if (!PermissionsUtil.hasContactsPermissions(context)) { 280c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee mContactInfoCache.disableRequestProcessing(); 281c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee } 28294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 28394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Resources resources = mContext.getResources(); 28494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallTypeHelper callTypeHelper = new CallTypeHelper(resources); 28594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 28637aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen mCallLogCache = CallLogCache.getCallLogCache(mContext); 28737aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen 288e80d62229bb11a92f0db8d4e4bac6533bbed9b66Nancy Chen PhoneCallDetailsHelper phoneCallDetailsHelper = 28937aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen new PhoneCallDetailsHelper(mContext, resources, mCallLogCache); 290d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee mCallLogListItemHelper = 29137aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen new CallLogListItemHelper(phoneCallDetailsHelper, resources, mCallLogCache); 29294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallLogGroupBuilder = new CallLogGroupBuilder(this); 2939bd094118e920b732394c29657f26b062f3e916bAnne Rong mFilteredNumberAsyncQueryHandler = 2949bd094118e920b732394c29657f26b062f3e916bAnne Rong new FilteredNumberAsyncQueryHandler(mContext.getContentResolver()); 295b980fc4386cdc24a605fc682d0fef0c5dc54c327Andrew Lee 296b980fc4386cdc24a605fc682d0fef0c5dc54c327Andrew Lee mPrefs = PreferenceManager.getDefaultSharedPreferences(context); 2975f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell mContactsPreferences = new ContactsPreferences(mContext); 298b980fc4386cdc24a605fc682d0fef0c5dc54c327Andrew Lee maybeShowVoicemailPromoCard(); 29994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 30094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 301267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee public void onSaveInstanceState(Bundle outState) { 302267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee outState.putInt(KEY_EXPANDED_POSITION, mCurrentlyExpandedPosition); 303267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee outState.putLong(KEY_EXPANDED_ROW_ID, mCurrentlyExpandedRowId); 304267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee } 305267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee 306267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee public void onRestoreInstanceState(Bundle savedInstanceState) { 307267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee if (savedInstanceState != null) { 308267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee mCurrentlyExpandedPosition = 309267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee savedInstanceState.getInt(KEY_EXPANDED_POSITION, RecyclerView.NO_POSITION); 310267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee mCurrentlyExpandedRowId = 311267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee savedInstanceState.getLong(KEY_EXPANDED_ROW_ID, NO_EXPANDED_LIST_ITEM); 312267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee } 313267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee } 314267e9ebd056ec4973c4b37c38f949e863de4f24cAndrew Lee 315486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa @Override 316486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa public void onBlockedNumber(String number,String countryIso) { 317486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa String cacheKey = PhoneNumberUtils.formatNumberToE164(number, countryIso); 318486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa if (!TextUtils.isEmpty(cacheKey)) { 319486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa mBlockedNumberCache.put(cacheKey, true); 320486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa notifyDataSetChanged(); 321486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa } 322486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa } 323486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa 324486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa @Override 325486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa public void onUnblockedNumber( String number, String countryIso) { 326486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa String cacheKey = PhoneNumberUtils.formatNumberToE164(number, countryIso); 327486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa if (!TextUtils.isEmpty(cacheKey)) { 328486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa mBlockedNumberCache.put(cacheKey, false); 329486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa notifyDataSetChanged(); 330486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa } 331486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa } 332486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa 33394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 33494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Requery on background thread when {@link Cursor} changes. 33594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 33694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 33794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng protected void onContentChanged() { 33894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallFetcher.fetchCalls(); 33994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 34094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 341fb585079cc4c522c27f6dd6bf03fd296535960f3Yorke Lee public void setLoading(boolean loading) { 34294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mLoading = loading; 34394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 34494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 34594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean isEmpty() { 34694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (mLoading) { 34794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // We don't want the empty state to show when loading. 34894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return false; 34994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 350492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee return getItemCount() == 0; 35194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 35294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 35394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 35494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void invalidateCache() { 35574479d448bc39c3534585a627fba603aa89e93caAndrew Lee mContactInfoCache.invalidate(); 35694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 35794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 358b980fc4386cdc24a605fc682d0fef0c5dc54c327Andrew Lee public void onResume() { 359142362f8253e7456640c14d6acaf1969afc4b68dYorke Lee if (PermissionsUtil.hasPermission(mContext, android.Manifest.permission.READ_CONTACTS)) { 360142362f8253e7456640c14d6acaf1969afc4b68dYorke Lee mContactInfoCache.start(); 361142362f8253e7456640c14d6acaf1969afc4b68dYorke Lee } 3625f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY); 363142362f8253e7456640c14d6acaf1969afc4b68dYorke Lee } 364142362f8253e7456640c14d6acaf1969afc4b68dYorke Lee 3652d588b857347fda465a963742c4f61e4014f3441Nancy Chen public void onPause() { 3662d588b857347fda465a963742c4f61e4014f3441Nancy Chen pauseCache(); 367b67294e72e074ee5b67c692f6674cee296fe8927Andrew Lee 3682d588b857347fda465a963742c4f61e4014f3441Nancy Chen if (mHiddenItemUri != null) { 3692d588b857347fda465a963742c4f61e4014f3441Nancy Chen CallLogAsyncTaskUtil.deleteVoicemail(mContext, mHiddenItemUri, null); 3702d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 3712d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 3722d588b857347fda465a963742c4f61e4014f3441Nancy Chen 3732d588b857347fda465a963742c4f61e4014f3441Nancy Chen @VisibleForTesting 3742d588b857347fda465a963742c4f61e4014f3441Nancy Chen /* package */ void pauseCache() { 37574479d448bc39c3534585a627fba603aa89e93caAndrew Lee mContactInfoCache.stop(); 37637aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen mCallLogCache.reset(); 37794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 37894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 37994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 38094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng protected void addGroups(Cursor cursor) { 38194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallLogGroupBuilder.addGroups(cursor); 38294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 38394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 38494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 3856b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi public void addVoicemailGroups(Cursor cursor) { 3866b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi mCallLogGroupBuilder.addVoicemailGroups(cursor); 3876b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi } 3886b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 3896b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi @Override 390492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 391a4adb2c035690a1c9600a20c2485886d9d5991d0Andrew Lee if (viewType == VIEW_TYPE_VOICEMAIL_PROMO_CARD) { 392bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen return createVoicemailPromoCardViewHolder(parent); 39369705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee } 3949afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn return createCallLogEntryViewHolder(parent); 3959afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn } 3969afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn 3979afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn /** 3989afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn * Creates a new call log entry {@link ViewHolder}. 3999afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn * 4009afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn * @param parent the parent view. 4019afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn * @return The {@link ViewHolder}. 4029afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn */ 4039afa723dcebf18759c63dc1c976b05050e348d2aTyler Gunn private ViewHolder createCallLogEntryViewHolder(ViewGroup parent) { 404492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee LayoutInflater inflater = LayoutInflater.from(mContext); 4052ff08a8f8d4762ab5d0aebb0b69079f0b8d20b3eYorke Lee View view = inflater.inflate(R.layout.call_log_list_item, parent, false); 406c1b7d0ae8cdfc0f0dddb5c2bb45c8239ffc6a264Andrew Lee CallLogListItemViewHolder viewHolder = CallLogListItemViewHolder.create( 407c1b7d0ae8cdfc0f0dddb5c2bb45c8239ffc6a264Andrew Lee view, 408c1b7d0ae8cdfc0f0dddb5c2bb45c8239ffc6a264Andrew Lee mContext, 409486ee39d0791d290411290af6d2e54f37436b09fGilles Franck Mevaa this, 410bae7b937b6cf6e7eb26d07bec95de38083923614Andrew Lee mExpandCollapseListener, 41137aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen mCallLogCache, 412d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee mCallLogListItemHelper, 4139bd094118e920b732394c29657f26b062f3e916bAnne Rong mVoicemailPlaybackPresenter, 4148d0847ca13ca46730756e1d3a3dff3d7d27fd18bAndrew Lee mFilteredNumberAsyncQueryHandler, 415d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell new Callback() { 416d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell @Override 417d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell public void onFilterNumberSuccess() { 418d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell Logger.logInteraction( 419d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell InteractionEvent.BLOCK_NUMBER_CALL_LOG); 420d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell } 421d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell 422d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell @Override 423d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell public void onUnfilterNumberSuccess() { 424d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell Logger.logInteraction( 425d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell InteractionEvent.UNBLOCK_NUMBER_CALL_LOG); 426d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell } 427d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell 428d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell @Override 429d81cc6c64f3213f571c1f1e7a5c7e59b71491fb0Brandon Maxwell public void onChangeFilteredNumberUndo() {} 4306b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi }, mActivityType == ACTIVITY_TYPE_ARCHIVE); 431affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee 432affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee viewHolder.callLogEntryView.setTag(viewHolder); 433affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate); 434affe8b7947dd58edc3d9f4685a3bdde53f46762bAndrew Lee 435c1b7d0ae8cdfc0f0dddb5c2bb45c8239ffc6a264Andrew Lee viewHolder.primaryActionView.setTag(viewHolder); 436c987e00fa84f8997c07e8cb2d413897ae1d41b14Andrew Lee 437c1b7d0ae8cdfc0f0dddb5c2bb45c8239ffc6a264Andrew Lee return viewHolder; 43894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 43994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 44094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 44194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Binds the views in the entry to the data in the call log. 442a9a82f52cbcadd0b9a4aafa0c785c0d6af629f1cSantos Cordon * TODO: This gets called 20-30 times when Dialer starts up for a single call log entry and 443a9a82f52cbcadd0b9a4aafa0c785c0d6af629f1cSantos Cordon * should not. It invokes cross-process methods and the repeat execution can get costly. 44494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 445a482522fb8fe4e9959c749f4ec616ae59cf06b28Brandon Maxwell * @param viewHolder The view corresponding to this entry. 446bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param position The position of the entry. 44794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 448240523d3e1b4502326c8d0d313dd1787aa8ff024Victor Chang @Override 449492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee public void onBindViewHolder(ViewHolder viewHolder, int position) { 45049efd91e50a11dc7bdef8382a0ceac01bc060f77Andrew Lee Trace.beginSection("onBindViewHolder: " + position); 451bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 452bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen switch (getItemViewType(position)) { 453bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen case VIEW_TYPE_VOICEMAIL_PROMO_CARD: 454bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen bindVoicemailPromoCardViewHolder(viewHolder); 455bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen break; 456bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen default: 457bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen bindCallLogListViewHolder(viewHolder, position); 458bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen break; 459bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 460bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 461bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen Trace.endSection(); 462bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 463bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 464bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 465bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Binds the promo card view holder. 466bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * 467bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param viewHolder The promo card view holder. 468bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 469bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen protected void bindVoicemailPromoCardViewHolder(ViewHolder viewHolder) { 470bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen PromoCardViewHolder promoCardViewHolder = (PromoCardViewHolder) viewHolder; 471bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 472ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee promoCardViewHolder.getSecondaryActionView() 473ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee .setOnClickListener(mVoicemailSettingsActionListener); 474ab90a18e2f05c7ae4158b770a9fbe9cbe4544597Andrew Lee promoCardViewHolder.getPrimaryActionView().setOnClickListener(mOkActionListener); 475bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 476bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 477bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 478bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Binds the view holder for the call log list item view. 479bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * 480bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param viewHolder The call log list item view holder. 481bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param position The position of the list item. 482bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 483bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 484bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private void bindCallLogListViewHolder(ViewHolder viewHolder, int position) { 485492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee Cursor c = (Cursor) getItem(position); 486492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee if (c == null) { 487492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee return; 488492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee } 489bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 490492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee int count = getGroupSize(position); 491492cd7371c6d8fddc4de85887a4ed9a89d602767Andrew Lee 49294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String number = c.getString(CallLogQuery.NUMBER); 493a46ed83a7ccba16bbfd791a3a6588d5f0add9526Brad Ebinger final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO); 49417df9323e45ae5984b6df25b788a9cbffb51e8abBrandon Maxwell final String postDialDigits = CompatUtils.isNCompatible() 4956b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi && mActivityType != ACTIVITY_TYPE_ARCHIVE ? 4966b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi c.getString(CallLogQuery.POST_DIAL_DIGITS) : ""; 497a46ed83a7ccba16bbfd791a3a6588d5f0add9526Brad Ebinger final String viaNumber = CompatUtils.isNCompatible() 498a46ed83a7ccba16bbfd791a3a6588d5f0add9526Brad Ebinger && mActivityType != ACTIVITY_TYPE_ARCHIVE ? 499a46ed83a7ccba16bbfd791a3a6588d5f0add9526Brad Ebinger c.getString(CallLogQuery.VIA_NUMBER) : ""; 500719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final int numberPresentation = c.getInt(CallLogQuery.NUMBER_PRESENTATION); 501b2eebafbc1f1e26b5178b2858ca335467b4bc341Nancy Chen final PhoneAccountHandle accountHandle = PhoneAccountUtils.getAccount( 502b2eebafbc1f1e26b5178b2858ca335467b4bc341Nancy Chen c.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME), 503b2eebafbc1f1e26b5178b2858ca335467b4bc341Nancy Chen c.getString(CallLogQuery.ACCOUNT_ID)); 504a482522fb8fe4e9959c749f4ec616ae59cf06b28Brandon Maxwell final ContactInfo cachedContactInfo = ContactInfoHelper.getContactInfo(c); 50556cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee final boolean isVoicemailNumber = 50637aa2f3d402bdb233d3c922fcde4f9aa6a262d68Nancy Chen mCallLogCache.isVoicemailNumber(accountHandle, number); 50756cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 50814cfa66d6df53303c280194d661c0b32838aa417Andrew Lee // Note: Binding of the action buttons is done as required in configureActionViews when the 50914cfa66d6df53303c280194d661c0b32838aa417Andrew Lee // user expands the actions ViewStub. 510146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn 51174479d448bc39c3534585a627fba603aa89e93caAndrew Lee ContactInfo info = ContactInfo.EMPTY; 512d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemailNumber) { 51374479d448bc39c3534585a627fba603aa89e93caAndrew Lee // Lookup contacts with this number 51435e44d4b757427a240e8764467bdd220e2124473Hall Liu info = mContactInfoCache.getValue(number + postDialDigits, 51535e44d4b757427a240e8764467bdd220e2124473Hall Liu countryIso, cachedContactInfo); 51694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 5171e5325f43c98a92f8bfec1dbd9db3d32a91835e9Ihab Awad CharSequence formattedNumber = info.formattedNumber == null 5188104b41f9ca85c2615e9aa52cb012b5868a0314fBrandon Maxwell ? null : PhoneNumberUtilsCompat.createTtsSpannable(info.formattedNumber); 519edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee 520edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee final PhoneCallDetails details = new PhoneCallDetails( 52135e44d4b757427a240e8764467bdd220e2124473Hall Liu mContext, number, numberPresentation, formattedNumber, 52235e44d4b757427a240e8764467bdd220e2124473Hall Liu postDialDigits, isVoicemailNumber); 523a46ed83a7ccba16bbfd791a3a6588d5f0add9526Brad Ebinger details.viaNumber = viaNumber; 524edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.accountHandle = accountHandle; 525edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.countryIso = countryIso; 526edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.date = c.getLong(CallLogQuery.DATE); 527edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.duration = c.getLong(CallLogQuery.DURATION); 528edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.features = getCallFeatures(c, count); 529edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.geocode = c.getString(CallLogQuery.GEOCODED_LOCATION); 530edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.transcription = c.getString(CallLogQuery.TRANSCRIPTION); 5316b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi details.callTypes = getCallTypes(c, count); 532edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee 5338b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn if (!c.isNull(CallLogQuery.DATA_USAGE)) { 534edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.dataUsage = c.getLong(CallLogQuery.DATA_USAGE); 5358b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn } 5368b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn 53736aeec91ed927b7fe3a27bcd5e224443899117f1Brandon Maxwell if (!TextUtils.isEmpty(info.name) || !TextUtils.isEmpty(info.nameAlternative)) { 538edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.contactUri = info.lookupUri; 53936aeec91ed927b7fe3a27bcd5e224443899117f1Brandon Maxwell details.namePrimary = info.name; 54036aeec91ed927b7fe3a27bcd5e224443899117f1Brandon Maxwell details.nameAlternative = info.nameAlternative; 54136aeec91ed927b7fe3a27bcd5e224443899117f1Brandon Maxwell details.nameDisplayOrder = mContactsPreferences.getDisplayOrder(); 542edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.numberType = info.type; 543edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.numberLabel = info.label; 544edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.photoUri = info.photoUri; 545edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee details.sourceType = info.sourceType; 5462f05af35af03de67c1c474cd148719b24fac3552Andrew Lee details.objectId = info.objectId; 547240523d3e1b4502326c8d0d313dd1787aa8ff024Victor Chang details.contactUserType = info.userType; 548edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee } 549704acc087ce359295475a46695c2821c55778344Chiao Cheng 55070bb286f79696fc3a3ee8a57a038a9f56087d902Andrew Lee final CallLogListItemViewHolder views = (CallLogListItemViewHolder) viewHolder; 5515a9cd71b8ea670cd7c9aebd3dba27ea8cbe769dfAndrew Lee views.info = info; 552edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.rowId = c.getLong(CallLogQuery.ID); 553edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee // Store values used when the actions ViewStub is inflated on expansion. 554edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.number = number; 55535e44d4b757427a240e8764467bdd220e2124473Hall Liu views.postDialDigits = details.postDialDigits; 55618b4a2e3b8d60df39b3489c76bf4edffb81e15a5Tyler Gunn views.displayNumber = details.displayNumber; 557edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.numberPresentation = numberPresentation; 5586b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 559edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.accountHandle = accountHandle; 560edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee // Stash away the Ids of the calls so that we can support deleting a row in the call log. 561edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.callIds = getCallIds(c, count); 56218b4a2e3b8d60df39b3489c76bf4edffb81e15a5Tyler Gunn views.isBusiness = mContactInfoHelper.isBusiness(info.sourceType); 56318b4a2e3b8d60df39b3489c76bf4edffb81e15a5Tyler Gunn views.numberType = (String) Phone.getTypeLabel(mContext.getResources(), details.numberType, 56418b4a2e3b8d60df39b3489c76bf4edffb81e15a5Tyler Gunn details.numberLabel); 565edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee // Default case: an item in the call log. 566edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.primaryActionView.setVisibility(View.VISIBLE); 567240523d3e1b4502326c8d0d313dd1787aa8ff024Victor Chang views.workIconView.setVisibility( 568240523d3e1b4502326c8d0d313dd1787aa8ff024Victor Chang details.contactUserType == ContactsUtils.USER_TYPE_WORK ? View.VISIBLE : View.GONE); 5699686330691f1216edff0ffa779138bda43388c47Sai Cheemalapati 570edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee // Check if the day group has changed and display a header if necessary. 571edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee int currentGroup = getDayGroupForCall(views.rowId); 572edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee int previousGroup = getPreviousDayGroup(c); 573edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee if (currentGroup != previousGroup) { 574edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.dayGroupHeader.setVisibility(View.VISIBLE); 575edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.dayGroupHeader.setText(getGroupDescription(currentGroup)); 57694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 577edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee views.dayGroupHeader.setVisibility(View.GONE); 57894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 57994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 5806b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi if (mActivityType == ACTIVITY_TYPE_ARCHIVE) { 5816b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi views.callType = CallLog.Calls.VOICEMAIL_TYPE; 5826b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi views.voicemailUri = VoicemailArchiveContract.VoicemailArchive.buildWithId(c.getInt( 5836b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi c.getColumnIndex(VoicemailArchiveContract.VoicemailArchive._ID))) 5846b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi .toString(); 5856b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 5866b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi } else { 5876b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi if (details.callTypes[0] == CallLog.Calls.VOICEMAIL_TYPE || 5886b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi details.callTypes[0] == CallLog.Calls.MISSED_TYPE) { 5896b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi details.isRead = c.getInt(CallLogQuery.IS_READ) == 1; 5906b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi } 5916b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi views.callType = c.getInt(CallLogQuery.CALL_TYPE); 5926b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi views.voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI); 5936b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi } 5946b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi 595d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee mCallLogListItemHelper.setPhoneCallDetails(views, details); 596b0b57a10fbb9bec5c80d7adad8f65750a2f96e1bAndrew Lee 597edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee if (mCurrentlyExpandedRowId == views.rowId) { 598158dfa2dcb89db772f61af6f1f6775fcf5695e60Andrew Lee // In case ViewHolders were added/removed, update the expanded position if the rowIds 599158dfa2dcb89db772f61af6f1f6775fcf5695e60Andrew Lee // match so that we can restore the correct expanded state on rebind. 600158dfa2dcb89db772f61af6f1f6775fcf5695e60Andrew Lee mCurrentlyExpandedPosition = position; 601fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen views.showActions(true); 602fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen } else { 603fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen views.showActions(false); 604edb22da2b40549631a08150cbfc205e6ad243c20Andrew Lee } 6057d38100ffecf97ba740df4ea2979550189922f46Ta-wei Yen views.updatePhoto(); 60656cb0efa5eda1670077e66fc0e8c79478d0c1c67Yorke Lee 607d3f6a6c56dec7d47bae1121ed1030f67c26736feAndrew Lee mCallLogListItemHelper.setPhoneCallDetails(views, details); 608c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng } 609c5b6a693d4773214ff8d3fcfa43d0a29581bb886Chiao Cheng 6105f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell private String getPreferredDisplayName(ContactInfo contactInfo) { 6115f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell if (mContactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY || 6125f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell TextUtils.isEmpty(contactInfo.nameAlternative)) { 6135f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell return contactInfo.name; 6145f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell } 6155f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell return contactInfo.nameAlternative; 6165f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell } 6175f1c7dbf86603f534fbacdc96bab30d683913f4fBrandon Maxwell 61869705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee @Override 61969705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee public int getItemCount() { 6202d588b857347fda465a963742c4f61e4014f3441Nancy Chen return super.getItemCount() + (mShowVoicemailPromoCard ? 1 : 0) 6212d588b857347fda465a963742c4f61e4014f3441Nancy Chen - (mHiddenPosition != RecyclerView.NO_POSITION ? 1 : 0); 62269705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee } 62369705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee 62469705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee @Override 62569705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee public int getItemViewType(int position) { 626a4adb2c035690a1c9600a20c2485886d9d5991d0Andrew Lee if (position == VOICEMAIL_PROMO_CARD_POSITION && mShowVoicemailPromoCard) { 627bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen return VIEW_TYPE_VOICEMAIL_PROMO_CARD; 62869705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee } 62969705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee return super.getItemViewType(position); 63069705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee } 63169705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee 632bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 633bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Retrieves an item at the specified position, taking into account the presence of a promo 634bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * card. 635bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * 636bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param position The position to retrieve. 637bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @return The item at that position. 638bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 639bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen @Override 640bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen public Object getItem(int position) { 6412d588b857347fda465a963742c4f61e4014f3441Nancy Chen return super.getItem(position - (mShowVoicemailPromoCard ? 1 : 0) 6422d588b857347fda465a963742c4f61e4014f3441Nancy Chen + ((mHiddenPosition != RecyclerView.NO_POSITION && position >= mHiddenPosition) 6436b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi ? 1 : 0)); 644bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 645bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 6460599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee @Override 6470599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee public int getGroupSize(int position) { 6480599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee return super.getGroupSize(position - (mShowVoicemailPromoCard ? 1 : 0)); 6490599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee } 6500599e880630892becf1a1991e6712e0e6d9df3c8Andrew Lee 651a4adb2c035690a1c9600a20c2485886d9d5991d0Andrew Lee protected boolean isCallLogActivity() { 6526b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi return mActivityType == ACTIVITY_TYPE_CALL_LOG; 65369705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee } 65469705be50fc4c84b35df88c879dd9a4b4de655b3Andrew Lee 6552d588b857347fda465a963742c4f61e4014f3441Nancy Chen /** 6562d588b857347fda465a963742c4f61e4014f3441Nancy Chen * In order to implement the "undo" function, when a voicemail is "deleted" i.e. when the user 6572d588b857347fda465a963742c4f61e4014f3441Nancy Chen * clicks the delete button, the deleted item is temporarily hidden from the list. If a user 6582d588b857347fda465a963742c4f61e4014f3441Nancy Chen * clicks delete on a second item before the first item's undo option has expired, the first 6592d588b857347fda465a963742c4f61e4014f3441Nancy Chen * item is immediately deleted so that only one item can be "undoed" at a time. 6602d588b857347fda465a963742c4f61e4014f3441Nancy Chen */ 6610bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee @Override 6620bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee public void onVoicemailDeleted(Uri uri) { 6632d588b857347fda465a963742c4f61e4014f3441Nancy Chen if (mHiddenItemUri == null) { 6642d588b857347fda465a963742c4f61e4014f3441Nancy Chen // Immediately hide the currently expanded card. 6652d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenPosition = mCurrentlyExpandedPosition; 6662d588b857347fda465a963742c4f61e4014f3441Nancy Chen notifyDataSetChanged(); 6672d588b857347fda465a963742c4f61e4014f3441Nancy Chen } else { 6682d588b857347fda465a963742c4f61e4014f3441Nancy Chen // This means that there was a previous item that was hidden in the UI but not 6692d588b857347fda465a963742c4f61e4014f3441Nancy Chen // yet deleted from the database (call it a "pending delete"). Delete this previous item 6702d588b857347fda465a963742c4f61e4014f3441Nancy Chen // now since it is only possible to do one "undo" at a time. 6712d588b857347fda465a963742c4f61e4014f3441Nancy Chen CallLogAsyncTaskUtil.deleteVoicemail(mContext, mHiddenItemUri, null); 6722d588b857347fda465a963742c4f61e4014f3441Nancy Chen 6732d588b857347fda465a963742c4f61e4014f3441Nancy Chen // Set pending hide action so that the current item is hidden only after the previous 6742d588b857347fda465a963742c4f61e4014f3441Nancy Chen // item is permanently deleted. 6752d588b857347fda465a963742c4f61e4014f3441Nancy Chen mPendingHide = true; 6762d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 6772d588b857347fda465a963742c4f61e4014f3441Nancy Chen 6782d588b857347fda465a963742c4f61e4014f3441Nancy Chen collapseExpandedCard(); 6792d588b857347fda465a963742c4f61e4014f3441Nancy Chen 6802d588b857347fda465a963742c4f61e4014f3441Nancy Chen // Save the new hidden item uri in case it needs to be deleted from the database when 6812d588b857347fda465a963742c4f61e4014f3441Nancy Chen // a user attempts to delete another item. 6822d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenItemUri = uri; 6832d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 6842d588b857347fda465a963742c4f61e4014f3441Nancy Chen 6852d588b857347fda465a963742c4f61e4014f3441Nancy Chen private void collapseExpandedCard() { 6860bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee mCurrentlyExpandedRowId = NO_EXPANDED_LIST_ITEM; 6870bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee mCurrentlyExpandedPosition = RecyclerView.NO_POSITION; 6880bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee } 6890bb059d61f1e6648dee6f0a4cf8f02a6a7c26ce7Yorke Lee 690146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn /** 691fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen * When the list is changing all stored position is no longer valid. 692fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen */ 693fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen public void invalidatePositions() { 694fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen mCurrentlyExpandedPosition = RecyclerView.NO_POSITION; 695fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen mHiddenPosition = RecyclerView.NO_POSITION; 696fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen } 697fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen 698fa15094f656599b24e1c2a5d59ca1d8c0e515d10Ta-wei Yen /** 6992d588b857347fda465a963742c4f61e4014f3441Nancy Chen * When the user clicks "undo", the hidden item is unhidden. 7002d588b857347fda465a963742c4f61e4014f3441Nancy Chen */ 7012d588b857347fda465a963742c4f61e4014f3441Nancy Chen @Override 7022d588b857347fda465a963742c4f61e4014f3441Nancy Chen public void onVoicemailDeleteUndo() { 7032d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenPosition = RecyclerView.NO_POSITION; 7042d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenItemUri = null; 7052d588b857347fda465a963742c4f61e4014f3441Nancy Chen 7062d588b857347fda465a963742c4f61e4014f3441Nancy Chen mPendingHide = false; 7072d588b857347fda465a963742c4f61e4014f3441Nancy Chen notifyDataSetChanged(); 7082d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 7092d588b857347fda465a963742c4f61e4014f3441Nancy Chen 7102d588b857347fda465a963742c4f61e4014f3441Nancy Chen /** 7112d588b857347fda465a963742c4f61e4014f3441Nancy Chen * This callback signifies that a database deletion has completed. This means that if there is 7122d588b857347fda465a963742c4f61e4014f3441Nancy Chen * an item pending deletion, it will be hidden because the previous item that was in "undo" mode 7132d588b857347fda465a963742c4f61e4014f3441Nancy Chen * has been removed from the database. Otherwise it simply resets the hidden state because there 7142d588b857347fda465a963742c4f61e4014f3441Nancy Chen * are no pending deletes and thus no hidden items. 7152d588b857347fda465a963742c4f61e4014f3441Nancy Chen */ 7162d588b857347fda465a963742c4f61e4014f3441Nancy Chen @Override 7172d588b857347fda465a963742c4f61e4014f3441Nancy Chen public void onVoicemailDeletedInDatabase() { 7182d588b857347fda465a963742c4f61e4014f3441Nancy Chen if (mPendingHide) { 7192d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenPosition = mCurrentlyExpandedPosition; 7202d588b857347fda465a963742c4f61e4014f3441Nancy Chen mPendingHide = false; 7212d588b857347fda465a963742c4f61e4014f3441Nancy Chen } else { 7222d588b857347fda465a963742c4f61e4014f3441Nancy Chen // There should no longer be any hidden item because it has been deleted from the 7232d588b857347fda465a963742c4f61e4014f3441Nancy Chen // database. 7242d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenPosition = RecyclerView.NO_POSITION; 7252d588b857347fda465a963742c4f61e4014f3441Nancy Chen mHiddenItemUri = null; 7262d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 7272d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 7282d588b857347fda465a963742c4f61e4014f3441Nancy Chen 7292d588b857347fda465a963742c4f61e4014f3441Nancy Chen /** 7304dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Retrieves the day group of the previous call in the call log. Used to determine if the day 7314dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * group has changed and to trigger display of the day group text. 7324dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 7334dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param cursor The call log cursor. 7344dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @return The previous day group, or DAY_GROUP_NONE if this is the first call. 7354dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 7364dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn private int getPreviousDayGroup(Cursor cursor) { 7374dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // We want to restore the position in the cursor at the end. 7384dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn int startingPosition = cursor.getPosition(); 7394dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn int dayGroup = CallLogGroupBuilder.DAY_GROUP_NONE; 7404dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn if (cursor.moveToPrevious()) { 7412d588b857347fda465a963742c4f61e4014f3441Nancy Chen // If the previous entry is hidden (deleted in the UI but not in the database), skip it 7422d588b857347fda465a963742c4f61e4014f3441Nancy Chen // and check the card above it. A list with the voicemail promo card at the top will be 7432d588b857347fda465a963742c4f61e4014f3441Nancy Chen // 1-indexed because the 0th index is the promo card iteself. 7442d588b857347fda465a963742c4f61e4014f3441Nancy Chen int previousViewPosition = mShowVoicemailPromoCard ? startingPosition : 7452d588b857347fda465a963742c4f61e4014f3441Nancy Chen startingPosition - 1; 7462d588b857347fda465a963742c4f61e4014f3441Nancy Chen if (previousViewPosition != mHiddenPosition || 7472d588b857347fda465a963742c4f61e4014f3441Nancy Chen (previousViewPosition == mHiddenPosition && cursor.moveToPrevious())) { 7482d588b857347fda465a963742c4f61e4014f3441Nancy Chen long previousRowId = cursor.getLong(CallLogQuery.ID); 7492d588b857347fda465a963742c4f61e4014f3441Nancy Chen dayGroup = getDayGroupForCall(previousRowId); 7502d588b857347fda465a963742c4f61e4014f3441Nancy Chen } 7514dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 7524dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn cursor.moveToPosition(startingPosition); 7534dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return dayGroup; 7544dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 7554dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 7564dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 7574dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Given a call Id, look up the day group that the call belongs to. The day group data is 7584dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * populated in {@link com.android.dialer.calllog.CallLogGroupBuilder}. 7594dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 7604dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param callId The call to retrieve the day group for. 7614dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @return The day group for the call. 7624dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 7634dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn private int getDayGroupForCall(long callId) { 7644dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn if (mDayGroups.containsKey(callId)) { 7654dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return mDayGroups.get(callId); 7664dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 7674dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return CallLogGroupBuilder.DAY_GROUP_NONE; 7684dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 76981c3829f8a9377cb2e93c1fa6d223d223b78f371Andrew Lee 7704dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 77194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Returns the call types for the given number of items in the cursor. 77294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 77394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It uses the next {@code count} rows in the cursor to extract the types. 77494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 77594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It position in the cursor is unchanged by this function. 77694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 77794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private int[] getCallTypes(Cursor cursor, int count) { 7786b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi if (mActivityType == ACTIVITY_TYPE_ARCHIVE) { 7796b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi return new int[] {CallLog.Calls.VOICEMAIL_TYPE}; 7806b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi } 78194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int position = cursor.getPosition(); 78294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int[] callTypes = new int[count]; 78394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng for (int index = 0; index < count; ++index) { 78494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callTypes[index] = cursor.getInt(CallLogQuery.CALL_TYPE); 78594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng cursor.moveToNext(); 78694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 78794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng cursor.moveToPosition(position); 78894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return callTypes; 78994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 79094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 7918b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn /** 7928b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * Determine the features which were enabled for any of the calls that make up a call log 7938b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * entry. 7948b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * 7958b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @param cursor The cursor. 7968b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @param count The number of calls for the current call log entry. 7978b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn * @return The features. 7988b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn */ 7998b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn private int getCallFeatures(Cursor cursor, int count) { 80003610993bf2adf12a6962c32851095551ffd0043Yorke Lee int features = 0; 8018b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn int position = cursor.getPosition(); 8028b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn for (int index = 0; index < count; ++index) { 8038b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn features |= cursor.getInt(CallLogQuery.FEATURES); 8048b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn cursor.moveToNext(); 8058b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn } 8068b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn cursor.moveToPosition(position); 8078b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn return features; 8088b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn } 8098b0e858d5b4c50813dbe2b5c244e7013814b23ecTyler Gunn 810d0715acdfc1aee0c20950741dc15d30abd18d2f2Tyler Gunn /** 81194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Sets whether processing of requests for contact details should be enabled. 81274479d448bc39c3534585a627fba603aa89e93caAndrew Lee * 81394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * This method should be called in tests to disable such processing of requests when not 81494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * needed. 81594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 81694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @VisibleForTesting 81794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng void disableRequestProcessingForTest() { 81874479d448bc39c3534585a627fba603aa89e93caAndrew Lee // TODO: Remove this and test the cache directly. 819c16ea5ad67bf454158b364dec2f26c95a879c350Yorke Lee mContactInfoCache.disableRequestProcessing(); 82094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 82194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 82294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @VisibleForTesting 82394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng void injectContactInfoForTest(String number, String countryIso, ContactInfo contactInfo) { 82474479d448bc39c3534585a627fba603aa89e93caAndrew Lee // TODO: Remove this and test the cache directly. 82574479d448bc39c3534585a627fba603aa89e93caAndrew Lee mContactInfoCache.injectContactInfoForTest(number, countryIso, contactInfo); 82694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 82794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 8284dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 8294dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Stores the day group associated with a call in the call log. 8304dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 8314dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param rowId The row Id of the current call. 8324dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param dayGroup The day group the call belongs in. 8334dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 8344dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn @Override 8354dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public void setDayGroup(long rowId, int dayGroup) { 8364dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn if (!mDayGroups.containsKey(rowId)) { 8374dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn mDayGroups.put(rowId, dayGroup); 8384dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 8394dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 8404dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 8414dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 8424dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Clears the day group associations on re-bind of the call log. 8434dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 8444dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn @Override 8454dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public void clearDayGroups() { 8464dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn mDayGroups.clear(); 8474dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 8484dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 849146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn /** 850146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn * Retrieves the call Ids represented by the current call log row. 851146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn * 852146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn * @param cursor Call log cursor to retrieve call Ids from. 853146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn * @param groupSize Number of calls associated with the current call log row. 854146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn * @return Array of call Ids. 855146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn */ 856cf5e001120916deb770ea65ae55730e456f92137Tyler Gunn private long[] getCallIds(final Cursor cursor, final int groupSize) { 857146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn // We want to restore the position in the cursor at the end. 858146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn int startingPosition = cursor.getPosition(); 859146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn long[] ids = new long[groupSize]; 860146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn // Copy the ids of the rows in the group. 861146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn for (int index = 0; index < groupSize; ++index) { 862146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn ids[index] = cursor.getLong(CallLogQuery.ID); 863146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn cursor.moveToNext(); 864146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn } 865146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn cursor.moveToPosition(startingPosition); 866146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn return ids; 867146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn } 868146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn 869146a4cdf57f0d4d0cd85e808f1df2bdea639b24cTyler Gunn /** 8704dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Determines the description for a day group. 8714dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 8724dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param group The day group to retrieve the description for. 8734dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @return The day group description. 8744dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 8754dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn private CharSequence getGroupDescription(int group) { 8764dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn if (group == CallLogGroupBuilder.DAY_GROUP_TODAY) { 8771e273313ff938ba0c7294dade433736d3fc5876bTyler Gunn return mContext.getResources().getString(R.string.call_log_header_today); 8784dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } else if (group == CallLogGroupBuilder.DAY_GROUP_YESTERDAY) { 8791e273313ff938ba0c7294dade433736d3fc5876bTyler Gunn return mContext.getResources().getString(R.string.call_log_header_yesterday); 8804dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } else { 8814dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return mContext.getResources().getString(R.string.call_log_header_other); 8824dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 8834dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 884bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 885bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 886bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Determines if the voicemail promo card should be shown or not. The voicemail promo card will 887bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * be shown as the first item in the voicemail tab. 888bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 889bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private void maybeShowVoicemailPromoCard() { 890bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen boolean showPromoCard = mPrefs.getBoolean(SHOW_VOICEMAIL_PROMO_CARD, 891bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen SHOW_VOICEMAIL_PROMO_CARD_DEFAULT); 8926b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi mShowVoicemailPromoCard = mActivityType != ACTIVITY_TYPE_ARCHIVE && 8936b0056f348e1f9ecf0f91b53b51d240961bc8313Sarmad Hashmi (mVoicemailPlaybackPresenter != null) && showPromoCard; 894bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 895bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 896bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 897bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Dismisses the voicemail promo card and refreshes the call log. 898bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 899bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen private void dismissVoicemailPromoCard() { 900bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen mPrefs.edit().putBoolean(SHOW_VOICEMAIL_PROMO_CARD, false).apply(); 901a4adb2c035690a1c9600a20c2485886d9d5991d0Andrew Lee mShowVoicemailPromoCard = false; 902bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen notifyItemRemoved(VOICEMAIL_PROMO_CARD_POSITION); 903bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 904bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 905bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen /** 906bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * Creates the view holder for the voicemail promo card. 907bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * 908bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @param parent The parent view. 909bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen * @return The {@link ViewHolder}. 910bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen */ 911bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen protected ViewHolder createVoicemailPromoCardViewHolder(ViewGroup parent) { 912bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen LayoutInflater inflater = LayoutInflater.from(mContext); 913bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen View view = inflater.inflate(R.layout.voicemail_promo_card, parent, false); 914bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen 915bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen PromoCardViewHolder viewHolder = PromoCardViewHolder.create(view); 916bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen return viewHolder; 917bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875Nancy Chen } 91894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng} 919