summaryrefslogtreecommitdiff
path: root/InCallUI
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2015-11-09 13:05:05 -0800
committerNancy Chen <nancychen@google.com>2015-11-10 10:21:57 -0800
commit47249fc61a2cd39b44c157a1f8ba481d25e99577 (patch)
tree6f6ccaf0d48943c57e93d63345f3132a7d9efa09 /InCallUI
parente2cc0b2a9472bb88049f29be6b7515920807c51b (diff)
Account for multiple open times for business contacts.
Sometimes businesses will close in the middle of the day and reopen. We want to correctly represent the "open now"/"closed now" text for these breaks. Update tests accordingly. Bug: 25488385 Change-Id: I7ea96b1c037770261389297cb405a5e93d8171e4
Diffstat (limited to 'InCallUI')
-rw-r--r--InCallUI/res/values/strings.xml10
-rw-r--r--InCallUI/src/com/android/incallui/ContactInfoCache.java7
-rw-r--r--InCallUI/src/com/android/incallui/ContactUtils.java6
-rw-r--r--InCallUI/src/com/android/incallui/InCallContactInteractions.java94
-rw-r--r--InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java181
5 files changed, 189 insertions, 109 deletions
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index 2f8ef8a41..54d68c9d2 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -479,8 +479,14 @@
<string name="distance_metric_away"><xliff:g id="distance">%.1f</xliff:g> km away</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>
+ <!-- Used to indicate hours of operation for a location as a time span. e.g. "11 am - 9 pm" [CHAR LIMIT=NONE] -->
+ <string name="open_time_span"><xliff:g id="open_time">%1$s</xliff:g> - <xliff:g id="close_time">%2$s</xliff:g></string>
+ <!-- Used to indicate a series of opening hours for a location.
+ This first argument may be one or more time spans. e.g. "11 am - 9 pm, 9 pm - 11 pm"
+ The second argument is an additional time span. e.g. "11 pm - 1 am"
+ The string is used to build a list of opening hours.
+ [CHAR LIMIT=NONE] -->
+ <string name="opening_hours"><xliff:g id="earlier_times">%1$s</xliff:g>, <xliff:g id="later_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/ContactInfoCache.java b/InCallUI/src/com/android/incallui/ContactInfoCache.java
index 098f82b81..c5176b1a1 100644
--- a/InCallUI/src/com/android/incallui/ContactInfoCache.java
+++ b/InCallUI/src/com/android/incallui/ContactInfoCache.java
@@ -49,7 +49,9 @@ import com.android.incalluibind.ObjectFactory;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.Calendar;
import java.util.HashMap;
+import java.util.List;
import java.util.Set;
/**
@@ -324,7 +326,8 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete
}
@Override
- public void onContactInteractionsFound(Address address, Pair<String, String> openingHours) {
+ public void onContactInteractionsFound(Address address,
+ List<Pair<Calendar, Calendar>> openingHours) {
final ContactCacheEntry entry = mInfoMap.get(mCallId);
entry.locationAddress = address;
entry.openingHours = openingHours;
@@ -621,7 +624,7 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete
public Uri lookupUri; // Sent to NotificationMananger
public String lookupKey;
public Address locationAddress;
- public Pair<String, String> openingHours;
+ public List<Pair<Calendar, Calendar>> openingHours;
public int contactLookupResult = LogState.LOOKUP_NOT_FOUND;
@Override
diff --git a/InCallUI/src/com/android/incallui/ContactUtils.java b/InCallUI/src/com/android/incallui/ContactUtils.java
index dfacade8a..0750af731 100644
--- a/InCallUI/src/com/android/incallui/ContactUtils.java
+++ b/InCallUI/src/com/android/incallui/ContactUtils.java
@@ -21,6 +21,9 @@ import android.util.Pair;
import com.android.incalluibind.ObjectFactory;
+import java.util.Calendar;
+import java.util.List;
+
/**
* Utility functions to help manipulate contact data.
*/
@@ -36,7 +39,8 @@ public abstract class ContactUtils {
}
public interface Listener {
- public void onContactInteractionsFound(Address address, Pair<String, String> openingHours);
+ public void onContactInteractionsFound(Address address,
+ List<Pair<Calendar, Calendar>> openingHours);
}
public abstract boolean retrieveContactInteractionsFromLookupKey(String lookupKey,
diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
index 21660cbce..275243e4d 100644
--- a/InCallUI/src/com/android/incallui/InCallContactInteractions.java
+++ b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
@@ -49,7 +49,6 @@ import java.util.Locale;
* is a business contact or not and logic for the manipulation of data for the call context.
*/
public class InCallContactInteractions {
- private static final String TAG = InCallContactInteractions.class.getSimpleName();
private Context mContext;
private InCallContactInteractionsListAdapter mListAdapter;
private boolean mIsBusiness;
@@ -95,7 +94,7 @@ public class InCallContactInteractions {
}
public void setBusinessInfo(Address address, float distance,
- Pair<String, String> openingHours) {
+ List<Pair<Calendar, Calendar>> openingHours) {
mListAdapter.clear();
List<ContactContextInfo> info = new ArrayList<ContactContextInfo>();
@@ -126,7 +125,7 @@ public class InCallContactInteractions {
* @return BusinessContextInfo object with the schedule icon, the heading set to whether the
* business is open or not and the details set to the hours of operation.
*/
- private BusinessContextInfo constructHoursInfo(Pair<String, String> openingHours) {
+ private BusinessContextInfo constructHoursInfo(List<Pair<Calendar, Calendar>> openingHours) {
return constructHoursInfo(Calendar.getInstance(), openingHours);
}
@@ -135,26 +134,38 @@ public class InCallContactInteractions {
*/
@VisibleForTesting
BusinessContextInfo constructHoursInfo(Calendar currentTime,
- Pair<String, String> openingHours) {
+ List<Pair<Calendar, Calendar>> openingHours) {
+ if (currentTime == null || openingHours == null || openingHours.size() == 0) {
+ return null;
+ }
+
BusinessContextInfo hoursInfo = new BusinessContextInfo();
hoursInfo.iconId = R.drawable.ic_schedule_white_24dp;
- // Note: the date of these {@link Date}s are set to January 1, 1970. The object is just
- // used as a storage for the time.
- Date openingDateTime = getSimpleDateTime(openingHours.first);
- Date closingDateTime = getSimpleDateTime(openingHours.second);
+ boolean isOpen = false;
+ for (Pair<Calendar, Calendar> hours : openingHours) {
+ if (hours.first.compareTo(currentTime) <= 0
+ && currentTime.compareTo(hours.second) < 0) {
+ // If the current time is on or after the opening time and strictly before the
+ // closing time, then this business is open.
+ isOpen = true;
+ }
- if (openingDateTime == null || closingDateTime == null) {
- return null;
+ String openTimeSpan = mContext.getString(R.string.open_time_span,
+ DateFormat.getTimeFormat(mContext).format(hours.first.getTime()),
+ DateFormat.getTimeFormat(mContext).format(hours.second.getTime()));
+
+ if (TextUtils.isEmpty(hoursInfo.detail)) {
+ hoursInfo.detail = openTimeSpan;
+ } else {
+ hoursInfo.detail = mContext.getString(R.string.opening_hours, hoursInfo.detail,
+ openTimeSpan);
+ }
}
- hoursInfo.heading = isOpen(openingDateTime, closingDateTime, currentTime)
- ? mContext.getString(R.string.open_now) : mContext.getString(R.string.closed_now);
+ hoursInfo.heading = isOpen ? mContext.getString(R.string.open_now)
+ : mContext.getString(R.string.closed_now);
- hoursInfo.detail = mContext.getString(
- R.string.opening_hours,
- DateFormat.getTimeFormat(mContext).format(openingDateTime),
- DateFormat.getTimeFormat(mContext).format(closingDateTime));
return hoursInfo;
}
@@ -204,57 +215,6 @@ public class InCallContactInteractions {
}
/**
- * Get a {@link Date} object corresponding to a particular time.
- *
- * @param time A string containing a time in the format "hhmm".
- * @return A {@link Date} object with the time set to the parsed value of the "time" parameter
- * and the date set to January 1, 1970. Or {@code null} if the input string is not able to be
- * parsed.
- */
- private Date getSimpleDateTime(String time) {
- try {
- return new SimpleDateFormat("hhmm").parse(time);
- } catch (ParseException e) {
- Log.w(TAG, "Could not parse time string " + time);
- }
- return null;
- }
-
- /**
- * Check whether the current time falls between the opening time and the closing time.
- *
- * @param openingTime A {@link Date} object with the time set to the opening time and the date
- * set to January 1, 1970.
- * @param closingTime A {@link Date} object with the time set to the closing time and the date
- * set to January 1, 1970.
- * @param currentDateTime A {@link Calendar} object with the current date and time.
- * @return {@code true} if the current time falls within the opening and closing time bounds and
- * {@code false} otherwise.
- */
- private boolean isOpen(Date openingTime, Date closingTime, Calendar currentDateTime) {
- Calendar openTimeCalendar = Calendar.getInstance();
- openTimeCalendar.setTime(openingTime);
-
- Calendar closeTimeCalendar = Calendar.getInstance();
- closeTimeCalendar.setTime(closingTime);
-
- if (openTimeCalendar.compareTo(closeTimeCalendar) >= 0) {
- // If the open time is the same or after the close time, add a day to the close time
- // calendar.
- closeTimeCalendar.add(Calendar.DATE, 1);
- }
-
- // Since the date doesn't actually matter, it's easier to set the current date to the
- // opening date rather than change both the calendars for the open time and the close time.
- currentDateTime.set(
- openTimeCalendar.get(Calendar.YEAR),
- openTimeCalendar.get(Calendar.MONTH),
- openTimeCalendar.get(Calendar.DATE));
-
- return currentDateTime.after(openTimeCalendar) && currentDateTime.before(closeTimeCalendar);
- }
-
- /**
* Get the appropriate title for the context.
* @return The "Business info" title for a business contact and the "Recent messages" title for
* personal contacts.
diff --git a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java b/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
index 50d0aaf6c..0d03848b6 100644
--- a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
+++ b/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java
@@ -22,9 +22,18 @@ import android.util.Pair;
import com.android.incallui.InCallContactInteractions.BusinessContextInfo;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
+/**
+ * Tests for InCallContactInteractions class methods for formatting info for display.
+ *
+ * NOTE: tests assume system settings are set to 12hr time format and US locale. This means that
+ * the output of InCallContactInteractions methods are compared against strings in 12hr time format
+ * and US locale address formatting unless otherwise specified.
+ */
public class InCallContactInteractionsTest extends AndroidTestCase {
private InCallContactInteractions mInCallContactInteractions;
private static final float TEST_DISTANCE = (float) 1234.56;
@@ -34,64 +43,147 @@ public class InCallContactInteractionsTest extends AndroidTestCase {
mInCallContactInteractions = new InCallContactInteractions(mContext, true /* isBusiness */);
}
- public void testIsOpenNow() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 10);
- BusinessContextInfo info =
+ public void testIsOpenNow_NowMatchesOpenTime() {
+ assertEquals(mContext.getString(R.string.open_now),
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("0800", "2000"));
- assertEquals(mContext.getString(R.string.open_now), info.heading);
+ getTestCalendarWithHour(8),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(20))))
+ .heading);
}
public void testIsOpenNow_ClosingAfterMidnight() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 10);
- BusinessContextInfo info =
+ assertEquals(mContext.getString(R.string.open_now),
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("0800", "0100"));
- assertEquals(mContext.getString(R.string.open_now), info.heading);
+ getTestCalendarWithHour(10),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHourAndDaysFromToday(1, 1))))
+ .heading);
}
public void testIsOpenNow_Open24Hours() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 10);
- BusinessContextInfo info =
+ assertEquals(mContext.getString(R.string.open_now),
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(10),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHourAndDaysFromToday(8, 1))))
+ .heading);
+ }
+
+ public void testIsOpenNow_AfterMiddayBreak() {
+ assertEquals(mContext.getString(R.string.open_now),
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("0800", "0800"));
- assertEquals(mContext.getString(R.string.open_now), info.heading);
+ getTestCalendarWithHour(13),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(10)),
+ Pair.create(
+ getTestCalendarWithHour(12),
+ getTestCalendarWithHour(15))))
+ .heading);
+ }
+
+ public void testIsClosedNow_DuringMiddayBreak() {
+ assertEquals(mContext.getString(R.string.closed_now),
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(11),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(10)),
+ Pair.create(
+ getTestCalendarWithHour(12),
+ getTestCalendarWithHour(15))))
+ .heading);
}
public void testIsClosedNow_BeforeOpen() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 6);
- BusinessContextInfo info =
+ assertEquals(mContext.getString(R.string.closed_now),
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("0800", "2000"));
- assertEquals(mContext.getString(R.string.closed_now), info.heading);
+ getTestCalendarWithHour(6),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(20))))
+ .heading);
+ }
+
+ public void testIsClosedNow_NowMatchesClosedTime() {
+ assertEquals(mContext.getString(R.string.closed_now),
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(20),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(20))))
+ .heading);
}
public void testIsClosedNow_AfterClosed() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 21);
- BusinessContextInfo info =
+ assertEquals(mContext.getString(R.string.closed_now),
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("0800", "2000"));
- assertEquals(mContext.getString(R.string.closed_now), info.heading);
+ getTestCalendarWithHour(21),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(20))))
+ .heading);
+ }
+
+ public void testOpeningHours_SingleOpenRange() {
+ assertEquals("8:00 AM - 8:00 PM",
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(21),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(20))))
+ .detail);
+ }
+
+ public void testOpeningHours_TwoOpenRanges() {
+ assertEquals("8:00 AM - 10:00 AM, 12:00 PM - 3:00 PM",
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(13),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(10)),
+ Pair.create(
+ getTestCalendarWithHour(12),
+ getTestCalendarWithHour(15))))
+ .detail);
+ }
+
+ public void testOpeningHours_MultipleOpenRanges() {
+ assertEquals("8:00 AM - 10:00 AM, 12:00 PM - 3:00 PM, 5:00 PM - 9:00 PM",
+ mInCallContactInteractions.constructHoursInfo(
+ getTestCalendarWithHour(13),
+ Arrays.asList(
+ Pair.create(
+ getTestCalendarWithHour(8),
+ getTestCalendarWithHour(10)),
+ Pair.create(
+ getTestCalendarWithHour(12),
+ getTestCalendarWithHour(15)),
+ Pair.create(
+ getTestCalendarWithHour(17),
+ getTestCalendarWithHour(21))))
+ .detail);
}
public void testInvalidOpeningHours() {
- Calendar currentTimeForTest = Calendar.getInstance();
- currentTimeForTest.set(Calendar.HOUR_OF_DAY, 21);
- BusinessContextInfo info =
+ assertEquals(null,
mInCallContactInteractions.constructHoursInfo(
- currentTimeForTest,
- Pair.create("", "2000"));
- assertEquals(null, info);
+ getTestCalendarWithHour(21),
+ new ArrayList<Pair<Calendar, Calendar>>()));
}
public void testLocationInfo_ForUS() {
@@ -150,4 +242,19 @@ public class InCallContactInteractionsTest extends AndroidTestCase {
address.setLocality("Test locality");
return address;
}
+
+ private Calendar getTestCalendarWithHour(int hour) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY, hour);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar;
+ }
+
+ private Calendar getTestCalendarWithHourAndDaysFromToday(int hour, int daysFromToday) {
+ Calendar calendar = getTestCalendarWithHour(hour);
+ calendar.add(Calendar.DATE, daysFromToday);
+ return calendar;
+ }
}