summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2015-11-11 01:11:10 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-11-11 01:11:10 +0000
commit32f7b406d7ba204649c9c73b3466d725ba9e91f5 (patch)
tree64256efd9c7a009daf0012cfa75e2a31744815fe
parentf6713820178edee978d12b5b1949ede790ba8762 (diff)
parent73b8168ac6988f231bfea1774e72352032384125 (diff)
Merge "Account for multiple open times for business contacts." into ub-contactsdialer-a-dev
am: c3e0717a4b * commit 'c3e0717a4b107f65f1ec9cff54ae4991052a8d37': Account for multiple open times for business contacts.
-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;
+ }
}