Use geocoded location from call log content provider.

When showing the geocoded location in the call log, use the value from
the provider instead of querying the geocoder each time: that would be
too slow and cause a strict mode violation.

Bug: 5129581
Change-Id: Ia0eb5bdd33c5bcebcf6267ce01f7d36c53396c30
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 43e6fc7..80219d9 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -116,6 +116,7 @@
         CallLog.Calls.NUMBER,
         CallLog.Calls.TYPE,
         CallLog.Calls.COUNTRY_ISO,
+        CallLog.Calls.GEOCODED_LOCATION,
     };
 
     static final int DATE_COLUMN_INDEX = 0;
@@ -123,6 +124,7 @@
     static final int NUMBER_COLUMN_INDEX = 2;
     static final int CALL_TYPE_COLUMN_INDEX = 3;
     static final int COUNTRY_ISO_COLUMN_INDEX = 4;
+    static final int GEOCODED_LOCATION_COLUMN_INDEX = 5;
 
     static final String[] PHONES_PROJECTION = new String[] {
         PhoneLookup._ID,
@@ -403,6 +405,8 @@
             long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
             int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
             String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX);
+            final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX);
+
             if (TextUtils.isEmpty(countryIso)) {
                 countryIso = mDefaultCountryIso;
             }
@@ -448,7 +452,7 @@
                     numberText = candidateNumberText;
                 }
             }
-            return new PhoneCallDetails(number, numberText, countryIso,
+            return new PhoneCallDetails(number, numberText, countryIso, geocode,
                     new int[]{ callType }, date, duration,
                     nameText, numberType, numberLabel, personId, photoUri);
         } finally {
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
index 347a303..5718091 100644
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ b/src/com/android/contacts/PhoneCallDetails.java
@@ -30,6 +30,8 @@
     public final CharSequence formattedNumber;
     /** The country corresponding with the phone number. */
     public final String countryIso;
+    /** The geocoded location for the phone number. */
+    public final String geocode;
     /**
      * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}.
      * <p>
@@ -56,18 +58,20 @@
 
     /** Create the details for a call with a number not associated with a contact. */
     public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, int[] callTypes, long date, long duration) {
-        this(number, formattedNumber, countryIso, callTypes, date, duration, "", 0, "", -1L, null);
+            String countryIso, String geocode, int[] callTypes, long date, long duration) {
+        this(number, formattedNumber, countryIso, geocode, callTypes, date, duration, "", 0, "",
+                -1L, null);
     }
 
     /** Create the details for a call with a number associated with a contact. */
     public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, int[] callTypes, long date, long duration,
+            String countryIso, String geocode, int[] callTypes, long date, long duration,
             CharSequence name, int numberType, CharSequence numberLabel, long personId,
             Uri photoUri) {
         this.number = number;
         this.formattedNumber = formattedNumber;
         this.countryIso = countryIso;
+        this.geocode = geocode;
         this.callTypes = callTypes;
         this.date = date;
         this.duration = duration;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 3101aee..e970fcc 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -107,12 +107,10 @@
             mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
         if (TextUtils.isEmpty(details.name)) {
             nameText = displayNumber;
-            String geocode = mPhoneNumberHelper.getGeocodeForNumber(
-                    details.number.toString(), details.countryIso);
-            if (TextUtils.isEmpty(geocode)) {
+            if (TextUtils.isEmpty(details.geocode)) {
                 numberText = mResources.getString(R.string.call_log_empty_gecode);
             } else {
-                numberText = geocode;
+                numberText = details.geocode;
             }
         } else {
             nameText = details.name;
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 58dcc8b..212a0e6 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -89,6 +89,7 @@
                 Calls.TYPE,
                 Calls.COUNTRY_ISO,
                 Calls.VOICEMAIL_URI,
+                Calls.GEOCODED_LOCATION,
         };
 
         public static final int ID = 0;
@@ -98,6 +99,7 @@
         public static final int CALL_TYPE = 4;
         public static final int COUNTRY_ISO = 5;
         public static final int VOICEMAIL_URI = 6;
+        public static final int GEOCODED_LOCATION = 7;
 
         /**
          * The name of the synthetic "section" column.
@@ -107,7 +109,7 @@
          */
         public static final String SECTION_NAME = "section";
         /** The index of the "section" column in the projection. */
-        public static final int SECTION = 7;
+        public static final int SECTION = 8;
         /** The value of the "section" column for the header of the new section. */
         public static final int SECTION_NEW_HEADER = 0;
         /** The value of the "section" column for the items of the new section. */
@@ -756,12 +758,13 @@
             final Uri thumbnailUri = info.thumbnailUri;
             final String lookupKey = info.lookupKey;
             final int[] callTypes = getCallTypes(c, count);
+            final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
             final PhoneCallDetails details;
             if (TextUtils.isEmpty(name)) {
-                details = new PhoneCallDetails(number, formattedNumber, countryIso,
+                details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
                         callTypes, date, duration);
             } else {
-                details = new PhoneCallDetails(number, formattedNumber, countryIso,
+                details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
                         callTypes, date, duration, name, ntype, label, personId, thumbnailUri);
             }
 
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
index 394599f..68ac63a 100644
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ b/src/com/android/contacts/calllog/CallLogQueryHandler.java
@@ -103,7 +103,7 @@
                 new MatrixCursor(CallLogFragment.CallLogQuery.EXTENDED_PROJECTION);
         // The values in this row correspond to default values for _PROJECTION from CallLogQuery
         // plus the section value.
-        matrixCursor.addRow(new Object[]{ -1L, "", 0L, 0L, 0, "", "", section });
+        matrixCursor.addRow(new Object[]{ -1L, "", 0L, 0L, 0, "", "", "", section });
         return matrixCursor;
     }
 
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
index bf493f5..4d96f4f 100644
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ b/src/com/android/contacts/calllog/PhoneNumberHelper.java
@@ -18,10 +18,6 @@
 
 import com.android.contacts.R;
 import com.android.internal.telephony.CallerInfo;
-import com.google.i18n.phonenumbers.NumberParseException;
-import com.google.i18n.phonenumbers.PhoneNumberUtil;
-import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
-import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 
 import android.content.res.Resources;
 import android.net.Uri;
@@ -34,14 +30,10 @@
 public class PhoneNumberHelper {
     private final Resources mResources;
     private final String mVoicemailNumber;
-    private final PhoneNumberUtil mPhoneNumberUtil;
-    private final PhoneNumberOfflineGeocoder mPhoneNumberOfflineGeocoder;
 
     public PhoneNumberHelper(Resources resources, String voicemailNumber) {
         mResources = resources;
         mVoicemailNumber = voicemailNumber;
-        mPhoneNumberUtil = PhoneNumberUtil.getInstance();
-        mPhoneNumberOfflineGeocoder = PhoneNumberOfflineGeocoder.getInstance();
     }
 
     /** Returns true if it is possible to place a call to the given number. */
@@ -106,35 +98,4 @@
     public boolean isSipNumber(CharSequence number) {
         return PhoneNumberUtils.isUriNumber(number.toString());
     }
-
-    /**
-     * Returns a structured phone number from the given text representation, or null if the number
-     * cannot be parsed.
-     */
-    private PhoneNumber parsePhoneNumber(String number, String countryIso) {
-        try {
-            return mPhoneNumberUtil.parse(number, countryIso);
-        } catch (NumberParseException e) {
-            return null;
-        }
-    }
-
-    /** Returns the geocode associated with a phone number or the empty string if not available. */
-    public String getGeocodeForNumber(String number, String countryIso) {
-        if (!canGeocode(number)) {
-            return "";
-        }
-        PhoneNumber structuredPhoneNumber = parsePhoneNumber(number, countryIso);
-        if (structuredPhoneNumber != null) {
-            return mPhoneNumberOfflineGeocoder.getDescriptionForNumber(
-                    structuredPhoneNumber, mResources.getConfiguration().locale);
-        } else {
-            return "";
-        }
-    }
-
-    /** Returns true if it is possible to compute a geocode for the given number. */
-    private boolean canGeocode(CharSequence number) {
-        return canPlaceCallsTo(number) && !isVoicemailNumber(number);
-    }
 }