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 1994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.database.Cursor; 2094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.CallLog.Calls; 2194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.PhoneNumberUtils; 224dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunnimport android.text.format.Time; 2394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 244dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunnimport com.android.contacts.common.util.DateUtils; 2537d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Leeimport com.android.contacts.common.util.PhoneNumberHelper; 2637d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee 2794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.google.common.annotations.VisibleForTesting; 2894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 2987ba489564b25d4a64c9faaeafea46e2f72d8933Nancy Chenimport java.util.Objects; 3087ba489564b25d4a64c9faaeafea46e2f72d8933Nancy Chen 3194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/** 324dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Groups together calls in the call log. The primary grouping attempts to group together calls 334dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * to and from the same number into a single row on the call log. 344dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * A secondary grouping assigns calls, grouped via the primary grouping, to "day groups". The day 354dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * groups provide a means of identifying the calls which occurred "Today", "Yesterday", "Last week", 364dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * or "Other". 3794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 3894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * This class is meant to be used in conjunction with {@link GroupingListAdapter}. 3994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpublic class CallLogGroupBuilder { 4194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public interface GroupCreator { 424dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 434dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 444dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Defines the interface for adding a group to the call log. 454dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * The primary group for a call log groups the calls together based on the number which was 464dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * dialed. 474dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param cursorPosition The starting position of the group in the cursor. 484dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param size The size of the group. 494dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param expanded Whether the group is expanded; always false for the call log. 504dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void addGroup(int cursorPosition, int size, boolean expanded); 524dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 534dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 544dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Defines the interface for tracking the day group each call belongs to. Calls in a call 554dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * group are assigned the same day group as the first call in the group. The day group 564dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * assigns calls to the buckets: Today, Yesterday, Last week, and Other 574dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 584dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param rowId The row Id of the current call. 594dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param dayGroup The day group the call belongs in. 604dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 614dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public void setDayGroup(long rowId, int dayGroup); 624dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 634dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 644dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Defines the interface for clearing the day groupings information on rebind/regroup. 654dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 664dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public void clearDayGroups(); 6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 694dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 704dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Day grouping for call log entries used to represent no associated day group. Used primarily 714dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * when retrieving the previous day group, but there is no previous day group (i.e. we are at 724dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * the start of the list). 734dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 744dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public static final int DAY_GROUP_NONE = -1; 754dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 764dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** Day grouping for calls which occurred today. */ 774dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public static final int DAY_GROUP_TODAY = 0; 784dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 794dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** Day grouping for calls which occurred yesterday. */ 804dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn public static final int DAY_GROUP_YESTERDAY = 1; 814dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 824dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** Day grouping for calls which occurred before last week. */ 834a5a1bd99ef5e7c3571f299a6c979000bc6a0f74Nancy Chen public static final int DAY_GROUP_OTHER = 2; 844dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 854dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** Instance of the time object used for time calculations. */ 864dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn private static final Time TIME = new Time(); 874dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 8894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The object on which the groups are created. */ 8994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final GroupCreator mGroupCreator; 9094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public CallLogGroupBuilder(GroupCreator groupCreator) { 9294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mGroupCreator = groupCreator; 9394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 9494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 9694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Finds all groups of adjacent entries in the call log which should be grouped together and 9794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * calls {@link GroupCreator#addGroup(int, int, boolean)} on {@link #mGroupCreator} for each of 9894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * them. 9994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 10094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * For entries that are not grouped with others, we do not need to create a group of size one. 10194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 10294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * It assumes that the cursor will not change during its execution. 10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 10494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @see GroupingListAdapter#addGroups(Cursor) 10594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 10694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void addGroups(Cursor cursor) { 10794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final int count = cursor.getCount(); 10894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (count == 0) { 10994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 11094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 11194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1124dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // Clear any previous day grouping information. 1134dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn mGroupCreator.clearDayGroups(); 1144dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 1154dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // Get current system time, used for calculating which day group calls belong to. 1164dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn long currentTime = System.currentTimeMillis(); 1174dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 11894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int currentGroupSize = 1; 11994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng cursor.moveToFirst(); 12094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The number of the first entry in the group. 12194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng String firstNumber = cursor.getString(CallLogQuery.NUMBER); 12294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This is the type of the first call in the group. 12394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int firstCallType = cursor.getInt(CallLogQuery.CALL_TYPE); 1244dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 1251d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad // The account information of the first entry in the group. 1261d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad String firstAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME); 1271d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad String firstAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID); 12887ba489564b25d4a64c9faaeafea46e2f72d8933Nancy Chen 1294dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // Determine the day group for the first call in the cursor. 1304dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn final long firstDate = cursor.getLong(CallLogQuery.DATE); 1314dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn final long firstRowId = cursor.getLong(CallLogQuery.ID); 1324dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn int currentGroupDayGroup = getDayGroup(firstDate, currentTime); 1334dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn mGroupCreator.setDayGroup(firstRowId, currentGroupDayGroup); 1344dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 13594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng while (cursor.moveToNext()) { 13694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The number of the current row in the cursor. 13794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String currentNumber = cursor.getString(CallLogQuery.NUMBER); 13894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final int callType = cursor.getInt(CallLogQuery.CALL_TYPE); 1391d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad final String currentAccountComponentName = cursor.getString( 1401d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad CallLogQuery.ACCOUNT_COMPONENT_NAME); 1411d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad final String currentAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID); 14287ba489564b25d4a64c9faaeafea46e2f72d8933Nancy Chen 14394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final boolean sameNumber = equalNumbers(firstNumber, currentNumber); 1441d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad final boolean sameAccountComponentName = Objects.equals( 1451d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad firstAccountComponentName, 1461d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad currentAccountComponentName); 1471d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad final boolean sameAccountId = Objects.equals( 1481d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad firstAccountId, 1491d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad currentAccountId); 1501d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad final boolean sameAccount = sameAccountComponentName && sameAccountId; 15187ba489564b25d4a64c9faaeafea46e2f72d8933Nancy Chen 15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final boolean shouldGroup; 1534dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn final long currentCallId = cursor.getLong(CallLogQuery.ID); 1544dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn final long date = cursor.getLong(CallLogQuery.DATE); 15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1561d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad if (!sameNumber || !sameAccount) { 15794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Should only group with calls from the same number. 15894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng shouldGroup = false; 15994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else if (firstCallType == Calls.VOICEMAIL_TYPE) { 16094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // never group voicemail. 16194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng shouldGroup = false; 16294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 16394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Incoming, outgoing, and missed calls group together. 16466b60af960e3bf2e3b425966026e4b8ed8d01a03Yorke Lee shouldGroup = callType != Calls.VOICEMAIL_TYPE; 16594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 16694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 16794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (shouldGroup) { 16894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Increment the size of the group to include the current call, but do not create 16994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // the group until we find a call that does not match. 17094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng currentGroupSize++; 17194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 1724dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // The call group has changed, so determine the day group for the new call group. 1734dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // This ensures all calls grouped together in the call log are assigned the same 1744dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // day group. 1754dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn currentGroupDayGroup = getDayGroup(date, currentTime); 1764dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 17794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Create a group for the previous set of calls, excluding the current one, but do 17894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // not create a group for a single call. 17994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (currentGroupSize > 1) { 18094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng addGroup(cursor.getPosition() - currentGroupSize, currentGroupSize); 18194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Start a new group; it will include at least the current call. 18394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng currentGroupSize = 1; 18494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The current entry is now the first in the group. 18594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng firstNumber = currentNumber; 18694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng firstCallType = callType; 1871d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad firstAccountComponentName = currentAccountComponentName; 1881d1bd0da0b32a5b8cb1c7c5585acccb180b19849Ihab Awad firstAccountId = currentAccountId; 18994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 1904dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 1914dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn // Save the day group associated with the current call. 1924dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn mGroupCreator.setDayGroup(currentCallId, currentGroupDayGroup); 19394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If the last set of calls at the end of the call log was itself a group, create it now. 19594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (currentGroupSize > 1) { 19694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng addGroup(count - currentGroupSize, currentGroupSize); 19794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 20094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 20194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Creates a group of items in the cursor. 20294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 20394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * The group is always unexpanded. 20494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 20594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @see CallLogAdapter#addGroup(int, int, boolean) 20694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 20794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void addGroup(int cursorPosition, int size) { 20894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mGroupCreator.addGroup(cursorPosition, size, false); 20994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 21094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 21194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @VisibleForTesting 21294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng boolean equalNumbers(String number1, String number2) { 21337d29854313ca0a7807ac4fd5d10d154b79ee2ebYorke Lee if (PhoneNumberHelper.isUriNumber(number1) || PhoneNumberHelper.isUriNumber(number2)) { 21494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return compareSipAddresses(number1, number2); 21594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 21694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return PhoneNumberUtils.compare(number1, number2); 21794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 21894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 21994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 22094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @VisibleForTesting 22194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng boolean compareSipAddresses(String number1, String number2) { 22294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (number1 == null || number2 == null) return number1 == number2; 22394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 22494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int index1 = number1.indexOf('@'); 22594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String userinfo1; 22694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String rest1; 22794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (index1 != -1) { 22894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng userinfo1 = number1.substring(0, index1); 22994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng rest1 = number1.substring(index1); 23094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 23194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng userinfo1 = number1; 23294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng rest1 = ""; 23394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 23494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 23594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng int index2 = number2.indexOf('@'); 23694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String userinfo2; 23794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String rest2; 23894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (index2 != -1) { 23994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng userinfo2 = number2.substring(0, index2); 24094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng rest2 = number2.substring(index2); 24194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 24294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng userinfo2 = number2; 24394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng rest2 = ""; 24494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 24594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 24694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return userinfo1.equals(userinfo2) && rest1.equalsIgnoreCase(rest2); 24794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 2484dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 2494dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn /** 2504dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * Given a call date and the current date, determine which date group the call belongs in. 2514dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * 2524dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param date The call date. 2534dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @param now The current date. 2544dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn * @return The date group the call belongs in. 2554dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn */ 2564dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn private int getDayGroup(long date, long now) { 2574dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn int days = DateUtils.getDayDifference(TIME, date, now); 2584dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn 2594dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn if (days == 0) { 2604dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return DAY_GROUP_TODAY; 2614dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } else if (days == 1) { 2624dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return DAY_GROUP_YESTERDAY; 2634dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } else { 2644dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn return DAY_GROUP_OTHER; 2654dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 2664dfd7129ab04853504fe0c050e982db7b178b643Tyler Gunn } 26794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng} 268