Add the city/locality to the displayed business information.

To disambiguate, include the city/locality with the address in the form
"[street address], [city/locality]" in the contact interactions. Also
add tests to ensure the construction of the location info is correct.

Bug: 23351559
Change-Id: Ib0b2ce8a80a8494d5b006a6a74ad94447befc0ef
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index 20a724c..2f8ef8a 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -477,8 +477,10 @@
     <string name="distance_imperial_away"><xliff:g id="distance">%.1f</xliff:g> mi away</string>
     <!-- Used to inform the user how far away a location is in kilometers. [CHAR LIMIT=NONE] -->
     <string name="distance_metric_away"><xliff:g id="distance">%.1f</xliff:g> km away</string>
-    <!-- Used to indicate the opening hours for a location as a time span. [CHAR LIMIT=NONE] -->
-    <string name="opening_hours"><xliff:g id="open_time">%s</xliff:g> - <xliff:g id="close_time">%s</xliff:g></string>
+    <!-- A shortened way to display a business address. Formatted [street address], [city/locality]. -->
+    <string name="display_address"><xliff:g id="street_address">%1$s</xliff:g>, <xliff:g id="locality">%2$s</xliff:g></string>
+    <!-- Used to indicate the opening hours for a location as a time span. e.g. "11 am - 9 pm" [CHAR LIMIT=NONE] -->
+    <string name="opening_hours"><xliff:g id="open_time">%1$s</xliff:g> - <xliff:g id="close_time">%2$s</xliff:g></string>
     <!-- Displayed when a place is open. -->
     <string name="open_now">Open now</string>
     <!-- Displayed when a place is closed. -->
diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
index 6d1c9fc..918d39b 100644
--- a/InCallUI/src/com/android/incallui/InCallContactInteractions.java
+++ b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
@@ -127,15 +127,15 @@
      * business is open or not and the details set to the hours of operation.
      */
     private BusinessContextInfo constructHoursInfo(Pair<String, String> openingHours) {
-        return constructHoursInfoByTime(Calendar.getInstance(), openingHours);
+        return constructHoursInfo(Calendar.getInstance(), openingHours);
     }
 
     /**
      * Pass in arbitrary current calendar time.
      */
     @VisibleForTesting
-    BusinessContextInfo constructHoursInfoByTime(
-            Calendar currentTime, Pair<String, String> openingHours) {
+    BusinessContextInfo constructHoursInfo(Calendar currentTime,
+            Pair<String, String> openingHours) {
         BusinessContextInfo hoursInfo = new BusinessContextInfo();
         hoursInfo.iconId = R.drawable.ic_schedule_white_24dp;
 
@@ -170,8 +170,13 @@
      * @return A BusinessContextInfo object with the location icon, the heading as the distance to
      * the business and the details containing the address.
      */
+    private BusinessContextInfo constructLocationInfo(Address address, float distance) {
+        return constructLocationInfo(Locale.getDefault(), address, distance);
+    }
+
     @VisibleForTesting
-    BusinessContextInfo constructLocationInfo(Address address, float distance) {
+    BusinessContextInfo constructLocationInfo(Locale locale, Address address,
+            float distance) {
         if (address == null) {
             return null;
         }
@@ -180,7 +185,7 @@
         locationInfo.iconId = R.drawable.ic_location_on_white_24dp;
         if (distance != DistanceHelper.DISTANCE_NOT_FOUND) {
             //TODO: add a setting to allow the user to select "KM" or "MI" as their distance units.
-            if (Locale.US.equals(Locale.getDefault())) {
+            if (Locale.US.equals(locale)) {
                 locationInfo.heading = mContext.getString(R.string.distance_imperial_away,
                         distance * DistanceHelper.MILES_PER_METER);
             } else {
@@ -188,7 +193,14 @@
                         distance * DistanceHelper.KILOMETERS_PER_METER);
             }
         }
-        locationInfo.detail = address.getAddressLine(0);
+        if (address.getLocality() != null) {
+            locationInfo.detail = mContext.getString(
+                    R.string.display_address,
+                    address.getAddressLine(0),
+                    address.getLocality());
+        } else {
+            locationInfo.detail = address.getAddressLine(0);
+        }
         return locationInfo;
     }
 
diff --git a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java b/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
index c3ec08d..b97be01 100644
--- a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
+++ b/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
@@ -16,15 +16,18 @@
 
 package com.android.incallui;
 
+import android.location.Address;
 import android.test.AndroidTestCase;
 import android.util.Pair;
 
 import com.android.incallui.InCallContactInteractions.BusinessContextInfo;
 
 import java.util.Calendar;
+import java.util.Locale;
 
 public class InCallContactInteractionsTest extends AndroidTestCase {
     private InCallContactInteractions mInCallContactInteractions;
+    private static final float TEST_DISTANCE = (float) 1234.56;
 
     @Override
     protected void setUp() {
@@ -35,7 +38,7 @@
         Calendar currentTimeForTest = Calendar.getInstance();
         currentTimeForTest.set(Calendar.HOUR_OF_DAY, 10);
         BusinessContextInfo info =
-                mInCallContactInteractions.constructHoursInfoByTime(
+                mInCallContactInteractions.constructHoursInfo(
                         currentTimeForTest,
                         Pair.create("0800", "2000"));
         assertEquals(mContext.getString(R.string.open_now), info.heading);
@@ -45,7 +48,7 @@
         Calendar currentTimeForTest = Calendar.getInstance();
         currentTimeForTest.set(Calendar.HOUR_OF_DAY, 6);
         BusinessContextInfo info =
-                mInCallContactInteractions.constructHoursInfoByTime(
+                mInCallContactInteractions.constructHoursInfo(
                         currentTimeForTest,
                         Pair.create("0800", "2000"));
         assertEquals(mContext.getString(R.string.closed_now), info.heading);
@@ -55,7 +58,7 @@
         Calendar currentTimeForTest = Calendar.getInstance();
         currentTimeForTest.set(Calendar.HOUR_OF_DAY, 21);
         BusinessContextInfo info =
-                mInCallContactInteractions.constructHoursInfoByTime(
+                mInCallContactInteractions.constructHoursInfo(
                         currentTimeForTest,
                         Pair.create("0800", "2000"));
         assertEquals(mContext.getString(R.string.closed_now), info.heading);
@@ -65,9 +68,66 @@
         Calendar currentTimeForTest = Calendar.getInstance();
         currentTimeForTest.set(Calendar.HOUR_OF_DAY, 21);
         BusinessContextInfo info =
-                mInCallContactInteractions.constructHoursInfoByTime(
+                mInCallContactInteractions.constructHoursInfo(
                         currentTimeForTest,
                         Pair.create("", "2000"));
         assertEquals(null, info);
     }
+
+    public void testLocationInfo_ForUS() {
+        BusinessContextInfo info =
+                mInCallContactInteractions.constructLocationInfo(
+                        Locale.US,
+                        getAddressForTest(),
+                        TEST_DISTANCE);
+        assertEquals("0.8 mi away", info.heading);
+        assertEquals("Test address, Test locality", info.detail);
+    }
+
+    public void testLocationInfo_ForNotUS() {
+        BusinessContextInfo info =
+                mInCallContactInteractions.constructLocationInfo(
+                        Locale.CANADA,
+                        getAddressForTest(),
+                        TEST_DISTANCE);
+        assertEquals("1.2 km away", info.heading);
+        assertEquals("Test address, Test locality", info.detail);
+    }
+
+    public void testLocationInfo_NoLocality() {
+        Address address = getAddressForTest();
+        address.setLocality(null);
+        BusinessContextInfo info =
+                mInCallContactInteractions.constructLocationInfo(
+                        Locale.CANADA,
+                        address,
+                        TEST_DISTANCE);
+        assertEquals("1.2 km away", info.heading);
+        assertEquals("Test address", info.detail);
+    }
+
+    public void testLocationInfo_NoAddress() {
+        BusinessContextInfo info =
+                mInCallContactInteractions.constructLocationInfo(
+                        Locale.CANADA,
+                        null,
+                        TEST_DISTANCE);
+        assertEquals(null, info);
+    }
+
+    public void testLocationInfo_NoDistance() {
+        BusinessContextInfo info =
+                mInCallContactInteractions.constructLocationInfo(
+                        Locale.US,
+                        getAddressForTest(),
+                        DistanceHelper.DISTANCE_NOT_FOUND);
+        assertEquals(null, info.heading);
+    }
+
+    private Address getAddressForTest() {
+        Address address = new Address(Locale.US);
+        address.setAddressLine(0, "Test address");
+        address.setLocality("Test locality");
+        return address;
+    }
 }