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

Commit b0e36dec authored by Hall Liu's avatar Hall Liu Committed by android-build-merger
Browse files

Merge "Query geo description in worker thread to prevent ANR" am: eb7c287c

am: 53d24141

Change-Id: If224f142cf1bb77ecf8ed515250ad5c813682eb0
parents bd2cf664 53d24141
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -576,7 +576,7 @@ public class CallerInfo {
     * @return a geographical description string for the specified number.
     * @see com.android.i18n.phonenumbers.PhoneNumberOfflineGeocoder
     */
    private static String getGeoDescription(Context context, String number) {
    public static String getGeoDescription(Context context, String number) {
        if (VDBG) Rlog.v(TAG, "getGeoDescription('" + number + "')...");

        if (TextUtils.isEmpty(number)) {
+66 −25
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract.PhoneLookup;
@@ -35,6 +36,9 @@ import android.text.TextUtils;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;

import java.util.ArrayList;
import java.util.List;

/**
 * Helper class to make it easier to run asynchronous caller-id lookup queries.
 * @see CallerInfo
@@ -50,6 +54,7 @@ public class CallerInfoAsyncQuery {
    private static final int EVENT_END_OF_QUEUE = 3;
    private static final int EVENT_EMERGENCY_NUMBER = 4;
    private static final int EVENT_VOICEMAIL_NUMBER = 5;
    private static final int EVENT_GET_GEO_DESCRIPTION = 6;

    private CallerInfoAsyncQueryHandler mHandler;

@@ -79,6 +84,7 @@ public class CallerInfoAsyncQuery {
        public Object cookie;
        public int event;
        public String number;
        public String geoDescription;

        public int subId;
    }
@@ -142,6 +148,7 @@ public class CallerInfoAsyncQuery {
        private Context mContext;
        private Uri mQueryUri;
        private CallerInfo mCallerInfo;
        private List<Runnable> mPendingListenerCallbacks = new ArrayList<>();

        /**
         * Our own query worker thread.
@@ -206,11 +213,32 @@ public class CallerInfoAsyncQuery {

                            reply.sendToTarget();

                            break;
                        case EVENT_GET_GEO_DESCRIPTION:
                            handleGeoDescription(msg);
                            break;
                        default:
                    }
                }
            }

            private void handleGeoDescription(Message msg) {
                WorkerArgs args = (WorkerArgs) msg.obj;
                CookieWrapper cw = (CookieWrapper) args.cookie;
                if (!TextUtils.isEmpty(cw.number) && cw.cookie != null && mContext != null) {
                    final long startTimeMillis = SystemClock.elapsedRealtime();
                    cw.geoDescription = CallerInfo.getGeoDescription(mContext, cw.number);
                    final long duration = SystemClock.elapsedRealtime() - startTimeMillis;
                    if (duration > 500) {
                        if (DBG) Rlog.d(LOG_TAG, "[handleGeoDescription]" +
                                "Spends long time to retrieve Geo description: " + duration);
                    }
                }
                Message reply = args.handler.obtainMessage(msg.what);
                reply.obj = args;
                reply.arg1 = msg.arg1;
                reply.sendToTarget();
            }
        }


@@ -256,6 +284,11 @@ public class CallerInfoAsyncQuery {
            }

            if (cw.event == EVENT_END_OF_QUEUE) {
                for (Runnable r : mPendingListenerCallbacks) {
                    r.run();
                }
                mPendingListenerCallbacks.clear();

                release();
                if (cursor != null) {
                    cursor.close();
@@ -263,6 +296,18 @@ public class CallerInfoAsyncQuery {
                return;
            }

            // If the cw.event == EVENT_GET_GEO_DESCRIPTION, means it would not be the 1st
            // time entering the onQueryComplete(), mCallerInfo should not be null.
            if (cw.event == EVENT_GET_GEO_DESCRIPTION) {
                if (mCallerInfo != null) {
                    mCallerInfo.geoDescription = cw.geoDescription;
                }
                // notify that we can clean up the queue after this.
                CookieWrapper endMarker = new CookieWrapper();
                endMarker.event = EVENT_END_OF_QUEUE;
                startQuery(token, endMarker, null, null, null, null, null);
            }

            // check the token and if needed, create the callerinfo object.
            if (mCallerInfo == null) {
                if ((mContext == null) || (mQueryUri == null)) {
@@ -293,34 +338,24 @@ public class CallerInfoAsyncQuery {
                                + mCallerInfo);
                    }

                    // Final step: look up the geocoded description.
                    if (ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION) {
                        // Note we do this only if we *don't* have a valid name (i.e. if
                        // no contacts matched the phone number of the incoming call),
                        // since that's the only case where the incoming-call UI cares
                        // about this field.
                        //
                        // (TODO: But if we ever want the UI to show the geoDescription
                        // even when we *do* match a contact, we'll need to either call
                        // updateGeoDescription() unconditionally here, or possibly add a
                        // new parameter to CallerInfoAsyncQuery.startQuery() to force
                        // the geoDescription field to be populated.)

                        if (TextUtils.isEmpty(mCallerInfo.name)) {
                            // Actually when no contacts match the incoming phone number,
                            // the CallerInfo object is totally blank here (i.e. no name
                            // *or* phoneNumber).  So we need to pass in cw.number as
                            // a fallback number.
                            mCallerInfo.updateGeoDescription(mContext, cw.number);
                        }
                    }

                    // Use the number entered by the user for display.
                    if (!TextUtils.isEmpty(cw.number)) {
                        mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number,
                                mCallerInfo.normalizedNumber,
                                CallerInfo.getCurrentCountryIso(mContext));
                    }

                    // This condition refer to the google default code for geo.
                    // If the number exists in Contacts, the CallCard would never show
                    // the geo description, so it would be unnecessary to query it.
                    if (ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION) {
                        if (TextUtils.isEmpty(mCallerInfo.name)) {
                            if (DBG) Rlog.d(LOG_TAG, "start querying geo description");
                            cw.event = EVENT_GET_GEO_DESCRIPTION;
                            startQuery(token, cw, null, null, null, null, null);
                            return;
                        }
                    }
                }

                if (DBG) Rlog.d(LOG_TAG, "constructing CallerInfo object for token: " + token);
@@ -333,9 +368,15 @@ public class CallerInfoAsyncQuery {

            //notify the listener that the query is complete.
            if (cw.listener != null) {
                Rlog.d(LOG_TAG, "notifying listener: " + cw.listener.getClass().toString() +
                             " for token: " + token + mCallerInfo);
                mPendingListenerCallbacks.add(new Runnable() {
                    @Override
                    public void run() {
                        if (DBG) Rlog.d(LOG_TAG, "notifying listener: "
                                + cw.listener.getClass().toString() + " for token: " + token
                                + mCallerInfo);
                        cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
                    }
                });
            } else {
                Rlog.w(LOG_TAG, "There is no listener to notify for this query.");
            }