Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d6722e1 authored by Mengjun Leng's avatar Mengjun Leng
Browse files

Fix 4g conference call logs are merged together

If the first participant is same with other call logs, these call
logs are treated as group so that shows one call log. In order to avoid
it, compare number separately. Otherwise, avoid to query contact with
post dial string that casues showing contact name for post dial string
if user stores it as contact.

Change-Id: Ifaea5c5c3ed70e5654fcb3ff6372681ae14896ac
CRs-Fixed: 1089412
parent 5a8c5bfa
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -536,8 +536,8 @@ public class CallLogAdapter extends GroupingListAdapter
            // Lookup contacts with this number
            boolean isConfCallLog = num != null && num.length > 1
                    && DialerUtils.isConferenceURICallLog(phoneNumber, postDialDigits);
            String queryNumber = isConfCallLog ? phoneNumber : number + postDialDigits;
            info = mContactInfoCache.getValue(queryNumber,
            String queryNumber = isConfCallLog ? phoneNumber : number;
            info = mContactInfoCache.getValue(queryNumber, postDialDigits,
                    countryIso, cachedContactInfo, isConfCallLog);
        }
        CharSequence formattedNumber = info.formattedNumber == null
+10 −3
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.dialer.util.TelecomUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.regex.Pattern;

public class CallLogAsyncTaskUtil {
    private static String TAG = CallLogAsyncTaskUtil.class.getSimpleName();
@@ -209,14 +210,20 @@ public class CallLogAsyncTaskUtil {
                    PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemail;
            ContactInfo info = ContactInfo.EMPTY;

            Pattern pattern = Pattern.compile("[,;]");
            String[] num = pattern.split(number);
            boolean isConf = num != null && num.length > 1
                    && DialerUtils.isConferenceURICallLog(number, postDialDigits);
            String phoneNumber = num != null && num.length > 0 ? num[0] : "";
            String queryNumber = isConf ? number : phoneNumber;
            if (shouldLookupNumber) {
                ContactInfo lookupInfo = contactInfoHelper.lookupNumber(number, countryIso,
                    DialerUtils.isConferenceURICallLog(number, postDialDigits));
                ContactInfo lookupInfo = contactInfoHelper.lookupNumber(queryNumber, postDialDigits,
                        countryIso, isConf);
                info = lookupInfo != null ? lookupInfo : ContactInfo.EMPTY;
            }

            PhoneCallDetails details = new PhoneCallDetails(
                    context, number, numberPresentation, info.formattedNumber,
                    context, queryNumber, numberPresentation, info.formattedNumber,
                    postDialDigits, isVoicemail);

            details.viaNumber = viaNumber;
+30 −1
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ import com.android.contacts.common.compat.CompatUtils;
import com.android.contacts.common.util.DateUtils;
import com.android.contacts.common.util.PhoneNumberHelper;
import com.android.dialer.util.AppCompatConstants;
import com.android.dialer.util.DialerUtils;

import java.util.regex.Pattern;

/**
 * Groups together calls in the call log.  The primary grouping attempts to group together calls
@@ -130,6 +133,8 @@ public class CallLogGroupBuilder {
        int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
        String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
        String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
        boolean isGroupConfCallLog = DialerUtils.isConferenceURICallLog(groupNumber,
                groupPostDialDigits);
        int groupSize = 1;

        String number;
@@ -138,6 +143,7 @@ public class CallLogGroupBuilder {
        int callType;
        String accountComponentName;
        String accountId;
        boolean isNumberConfCallLog = false;

        while (cursor.moveToNext()) {
            // Obtain the values for the current call to group.
@@ -149,8 +155,10 @@ public class CallLogGroupBuilder {
            callType = cursor.getInt(CallLogQuery.CALL_TYPE);
            accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
            accountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
            isNumberConfCallLog = DialerUtils.isConferenceURICallLog(number, numberPostDialDigits);

            final boolean isSameNumber = equalNumbers(groupNumber, number);
            final boolean isSameNumber = equalNumbers(groupNumber, isGroupConfCallLog,
                    number, isNumberConfCallLog);
            final boolean isSamePostDialDigits = groupPostDialDigits.equals(numberPostDialDigits);
            final boolean isSameViaNumbers = groupViaNumbers.equals(numberViaNumbers);
            final boolean isSameAccount = isSameAccount(
@@ -184,6 +192,8 @@ public class CallLogGroupBuilder {
                groupCallType = callType;
                groupAccountComponentName = accountComponentName;
                groupAccountId = accountId;
                isGroupConfCallLog = DialerUtils.isConferenceURICallLog(groupNumber,
                        groupPostDialDigits);
            }

            // Save the day group associated with the current call.
@@ -224,8 +234,27 @@ public class CallLogGroupBuilder {

    @VisibleForTesting
    boolean equalNumbers(String number1, String number2) {
        return equalNumbers(number1, false, number2, false);
    }

    boolean equalNumbers(String number1, boolean isConf1, String number2, boolean isConf2) {
        if (PhoneNumberHelper.isUriNumber(number1) || PhoneNumberHelper.isUriNumber(number2)) {
            return compareSipAddresses(number1, number2);
        } else if (isConf1 && isConf2) {
            Pattern pattern = Pattern.compile("[,;]");
            String[] num1 = pattern.split(number1);
            String[] num2 = pattern.split(number2);
            if (num1 == null || num2 == null || num1.length != num2.length) {
                return false;
            }
            for (int i = 0; i < num1.length; i++) {
                if (!PhoneNumberUtils.compare(num1[i], num2[i])) {
                    return false;
                }
            }
            return true;
        } else if (isConf1 != isConf2) {
            return false;
        } else {
            return PhoneNumberUtils.compare(number1, number2);
        }
+15 −6
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public class ContactInfoHelper {
     */
    @Nullable
    public ContactInfo lookupNumber(String number, String countryIso) {
        return lookupNumber(number, countryIso, false);
        return lookupNumber(number, null, countryIso, false);
    }

    /**
@@ -90,11 +90,13 @@ public class ContactInfoHelper {
     * If an error occurs during the lookup, it returns null.
     *
     * @param number the number to look up
     * @param postDialString append into number if required
     * @param countryIso the country associated with this number
     * @param isConfUrlLog whether call log is for Conference URL call
     */
    @Nullable
    public ContactInfo lookupNumber(String number, String countryIso, boolean isConfUrlCallLog) {
    public ContactInfo lookupNumber(String number, String postDialString, String countryIso,
            boolean isConfUrlCallLog) {

        if (TextUtils.isEmpty(number)) {
            return null;
@@ -109,13 +111,14 @@ public class ContactInfoHelper {
                // If lookup failed, check if the "username" of the SIP address is a phone number.
                String username = PhoneNumberHelper.getUsernameFromUriNumber(number);
                if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
                    info = queryContactInfoForPhoneNumber(username, countryIso, true,
                    info = queryContactInfoForPhoneNumber(username, null, countryIso, true,
                            isConfUrlCallLog);
                }
            }
        } else {
            // Look for a contact that has the given phone number.
            info = queryContactInfoForPhoneNumber(number, countryIso, false, isConfUrlCallLog);
            info = queryContactInfoForPhoneNumber(number, postDialString, countryIso,
                    false, isConfUrlCallLog);
        }

        final ContactInfo updatedInfo;
@@ -127,6 +130,9 @@ public class ContactInfoHelper {
            if (info == ContactInfo.EMPTY) {
                // Did not find a matching contact.
                updatedInfo = new ContactInfo();
                if (!isConfUrlCallLog && !TextUtils.isEmpty(postDialString)) {
                    number += postDialString;
                }
                updatedInfo.number = number;
                updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
                updatedInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164(
@@ -265,8 +271,8 @@ public class ContactInfoHelper {
     * <p>
     * If the lookup fails for some other reason, it returns null.
     */
    private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso,
            boolean isSip, boolean isConfUrlLog) {
    private ContactInfo queryContactInfoForPhoneNumber(String number, String postDialString,
            String countryIso, boolean isSip, boolean isConfUrlLog) {
        if (TextUtils.isEmpty(number)) {
            return null;
        }
@@ -303,6 +309,9 @@ public class ContactInfoHelper {
            }
        }
        if (info != null && info != ContactInfo.EMPTY) {
            if (!isConfUrlLog && TextUtils.isEmpty(postDialString)) {
                number += postDialString;
            }
            info.formattedNumber = formatPhoneNumber(number, null, countryIso);
        } else if (mCachedNumberLookupService != null) {
            CachedContactInfo cacheInfo =
+64 −24
Original line number Diff line number Diff line
@@ -76,8 +76,8 @@ public class ContactInfoCache {

                if (req != null) {
                    // Process the request. If the lookup succeeds, schedule a redraw.
                    needRedraw |= queryContactInfo(req.number, req.countryIso, req.callLogInfo,
                            req.isConf);
                    needRedraw |= queryContactInfo(req.number, req.postDialString, req.countryIso,
                            req.callLogInfo, req.isConf);
                } else {
                    // Throttle redraw rate by only sending them when there are
                    // more requests.
@@ -131,6 +131,7 @@ public class ContactInfoCache {
    private final LinkedList<ContactInfoRequest> mRequests;

    private ExpirableCache<NumberWithCountryIso, ContactInfo> mCache;
    private ExpirableCache<NumberWithCountryIso, ContactInfo> mCacheFor4gConfCall;

    private ContactInfoHelper mContactInfoHelper;
    private QueryThread mContactInfoQueryThread;
@@ -143,37 +144,52 @@ public class ContactInfoCache {

        mRequests = new LinkedList<ContactInfoRequest>();
        mCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
        mCacheFor4gConfCall = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
    }

    public ContactInfo getValue(String number, String countryIso, ContactInfo cachedContactInfo) {
        return getValue(number, countryIso, cachedContactInfo, false);
        return getValue(number, null, countryIso, cachedContactInfo, false);
    }

    public ContactInfo getValue(String number, String countryIso, ContactInfo cachedContactInfo,
                boolean isConf) {
        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
        ExpirableCache.CachedValue<ContactInfo> cachedInfo =
                mCache.getCachedValue(numberCountryIso);
    public ContactInfo getValue(String number, String postDialString, String countryIso,
                ContactInfo cachedContactInfo, boolean isConf) {
        String phoneNumber = number;
        if (!isConf && !TextUtils.isEmpty(postDialString)) {
            phoneNumber += postDialString;
        }
        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(phoneNumber, countryIso);
        ExpirableCache.CachedValue<ContactInfo> cachedInfo = null;
        if (isConf) {
            cachedInfo = mCacheFor4gConfCall.getCachedValue(numberCountryIso);
        } else {
            cachedInfo = mCache.getCachedValue(numberCountryIso);
        }
        ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue();
        if (cachedInfo == null) {
            if (isConf) {
                mCacheFor4gConfCall.put(numberCountryIso, ContactInfo.EMPTY);
            } else {
                mCache.put(numberCountryIso, ContactInfo.EMPTY);
            }
            // Use the cached contact info from the call log.
            info = cachedContactInfo;
            // The db request should happen on a non-UI thread.
            // Request the contact details immediately since they are currently missing.
            enqueueRequest(number, countryIso, cachedContactInfo, true, isConf);
            enqueueRequest(number, postDialString, countryIso, cachedContactInfo, true, isConf);
            // We will format the phone number when we make the background request.
        } else {
            if (cachedInfo.isExpired()) {
                // The contact info is no longer up to date, we should request it. However, we
                // do not need to request them immediately.
                enqueueRequest(number, countryIso, cachedContactInfo, false, isConf);
                enqueueRequest(number, postDialString, countryIso,
                        cachedContactInfo, false, isConf);
            } else if (!callLogInfoMatches(cachedContactInfo, info)) {
                // The call log information does not match the one we have, look it up again.
                // We could simply update the call log directly, but that needs to be done in a
                // background thread, so it is easier to simply request a new lookup, which will, as
                // a side-effect, update the call log.
                enqueueRequest(number, countryIso, cachedContactInfo, false, isConf);
                enqueueRequest(number, postDialString, countryIso,
                        cachedContactInfo, false, isConf);
            }

            if (info == ContactInfo.EMPTY) {
@@ -192,12 +208,15 @@ public class ContactInfoCache {
     *
     * The number might be either a SIP address or a phone number.
     *
     * @param postDialString if required, append into number
     * @param isConf determine whether it is a 4g conf call log
     * It returns true if it updated the content of the cache and we should therefore tell the
     * view to update its content.
     */
    private boolean queryContactInfo(String number, String countryIso, ContactInfo callLogInfo,
            boolean isConf) {
        final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso, isConf);
    private boolean queryContactInfo(String number, String postDialString, String countryIso,
            ContactInfo callLogInfo, boolean isConf) {
        final ContactInfo info = mContactInfoHelper.lookupNumber(number, postDialString,
                countryIso, isConf);

        if (info == null) {
            // The lookup failed, just return without requesting to update the view.
@@ -206,8 +225,17 @@ public class ContactInfoCache {

        // Check the existing entry in the cache: only if it has changed we should update the
        // view.
        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
        ContactInfo existingInfo = mCache.getPossiblyExpired(numberCountryIso);
        String phoneNumber = number;
        if (!isConf && !TextUtils.isEmpty(postDialString)) {
            phoneNumber += postDialString;
        }
        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(phoneNumber, countryIso);
        ContactInfo existingInfo = null;
        if (isConf) {
            existingInfo = mCacheFor4gConfCall.getPossiblyExpired(numberCountryIso);
        } else {
            existingInfo = mCache.getPossiblyExpired(numberCountryIso);
        }

        final boolean isRemoteSource = info.sourceType != 0;

@@ -222,11 +250,21 @@ public class ContactInfoCache {

        // Store the data in the cache so that the UI thread can use to display it. Store it
        // even if it has not changed so that it is marked as not expired.
        if (isConf) {
            mCacheFor4gConfCall.put(numberCountryIso, info);
        } else {
            mCache.put(numberCountryIso, info);
        }

        // Update the call log even if the cache it is up-to-date: it is possible that the cache
        // contains the value from a different call log entry.
        mContactInfoHelper.updateCallLogContactInfo(number, countryIso, info, callLogInfo);
        if (isConf) {
            mContactInfoHelper.updateCallLogContactInfo(number, countryIso,
                    info, callLogInfo);
        } else {
            mContactInfoHelper.updateCallLogContactInfo(phoneNumber, countryIso,
                    info, callLogInfo);
        }
        return updated;
    }

@@ -271,6 +309,7 @@ public class ContactInfoCache {

    public void invalidate() {
        mCache.expireAll();
        mCacheFor4gConfCall.expireAll();
        stopRequestProcessing();
    }

@@ -300,7 +339,7 @@ public class ContactInfoCache {
     */
    protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
            boolean immediate) {
        enqueueRequest(number, countryIso, callLogInfo, immediate, false);
        enqueueRequest(number, null, countryIso, callLogInfo, immediate, false);
    }

    /**
@@ -311,12 +350,13 @@ public class ContactInfoCache {
     * If the {@code immediate} parameter is true, it will start immediately the thread that looks
     * up the contact information (if it has not been already started). Otherwise, it will be
     * started with a delay. See {@link #START_PROCESSING_REQUESTS_DELAY_MILLIS}.
     * @param postDialString if required, append into number
     * @param isConf indicate whether call log is for Conference Url call
     */
    protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
            boolean immediate, boolean isConf) {
        ContactInfoRequest request = new ContactInfoRequest(number, countryIso, callLogInfo,
                isConf);
    protected void enqueueRequest(String number, String postDialString, String countryIso,
            ContactInfo callLogInfo, boolean immediate, boolean isConf) {
        ContactInfoRequest request = new ContactInfoRequest(number, postDialString, countryIso,
                callLogInfo, isConf);
        synchronized (mRequests) {
            if (!mRequests.contains(request)) {
                mRequests.add(request);
Loading