summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/calllogutils
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/calllogutils')
-rw-r--r--java/com/android/dialer/calllogutils/CallLogDates.java165
-rw-r--r--java/com/android/dialer/calllogutils/CallLogDurations.java (renamed from java/com/android/dialer/calllogutils/CallEntryFormatter.java)55
-rw-r--r--java/com/android/dialer/calllogutils/res/values/strings.xml3
3 files changed, 170 insertions, 53 deletions
diff --git a/java/com/android/dialer/calllogutils/CallLogDates.java b/java/com/android/dialer/calllogutils/CallLogDates.java
new file mode 100644
index 000000000..2d4bd8bf5
--- /dev/null
+++ b/java/com/android/dialer/calllogutils/CallLogDates.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dialer.calllogutils;
+
+import android.content.Context;
+import android.icu.lang.UCharacter;
+import android.icu.text.BreakIterator;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.text.format.DateUtils;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+/** Static methods for formatting dates in the call log. */
+public final class CallLogDates {
+
+ /**
+ * Uses the new date formatting rules to format dates in the new call log.
+ *
+ * <p>Rules:
+ *
+ * <pre>
+ * if < 1 minute ago: "Now";
+ * else if today: "12:15 PM"
+ * else if < 3 days ago: "Wednesday";
+ * else: "Jan 15"
+ * </pre>
+ */
+ public static CharSequence newCallLogTimestampLabel(
+ Context context, long nowMillis, long timestampMillis) {
+ if (nowMillis - timestampMillis < TimeUnit.MINUTES.toMillis(1)) {
+ return context.getString(R.string.now);
+ }
+ if (isSameDay(nowMillis, timestampMillis)) {
+ return DateUtils.formatDateTime(
+ context, timestampMillis, DateUtils.FORMAT_SHOW_TIME); // e.g. 12:15 PM
+ }
+ if (isWithin3Days(nowMillis, timestampMillis)) {
+ return formatDayOfWeek(context, timestampMillis); // e.g. "Wednesday"
+ }
+ return formatAbbreviatedMonthAndDay(context, timestampMillis); // e.g. "Jan 15"
+ }
+
+ /**
+ * Formats the provided date into a value suitable for display in the current locale.
+ *
+ * <p>For example, returns a string like "Wednesday, May 25, 2016, 8:02PM" or "Chorshanba, 2016
+ * may 25,20:02".
+ *
+ * <p>For pre-N devices, the returned value may not start with a capital if the local convention
+ * is to not capitalize day names. On N+ devices, the returned value is always capitalized.
+ */
+ public static CharSequence formatDate(Context context, long callDateMillis) {
+ return toTitleCase(
+ DateUtils.formatDateTime(
+ context,
+ callDateMillis,
+ DateUtils.FORMAT_SHOW_TIME
+ | DateUtils.FORMAT_SHOW_DATE
+ | DateUtils.FORMAT_SHOW_WEEKDAY
+ | DateUtils.FORMAT_SHOW_YEAR));
+ }
+
+ /**
+ * Formats the provided date into the day of week.
+ *
+ * <p>For example, returns a string like "Wednesday" or "Chorshanba".
+ *
+ * <p>For pre-N devices, the returned value may not start with a capital if the local convention
+ * is to not capitalize day names. On N+ devices, the returned value is always capitalized.
+ */
+ private static CharSequence formatDayOfWeek(Context context, long callDateMillis) {
+ return toTitleCase(
+ DateUtils.formatDateTime(context, callDateMillis, DateUtils.FORMAT_SHOW_WEEKDAY));
+ }
+
+ /**
+ * Formats the provided date into the month abbreviation and day.
+ *
+ * <p>For example, returns a string like "Jan 15".
+ *
+ * <p>For pre-N devices, the returned value may not start with a capital if the local convention
+ * is to not capitalize day names. On N+ devices, the returned value is always capitalized.
+ */
+ private static CharSequence formatAbbreviatedMonthAndDay(Context context, long callDateMillis) {
+ return toTitleCase(
+ DateUtils.formatDateTime(
+ context, callDateMillis, DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_NO_YEAR));
+ }
+
+ private static CharSequence toTitleCase(CharSequence value) {
+ // We want the beginning of the date string to be capitalized, even if the word at the beginning
+ // of the string is not usually capitalized. For example, "Wednesdsay" in Uzbek is "chorshanba”
+ // (not capitalized). To handle this issue we apply title casing to the start of the sentence so
+ // that "chorshanba, 2016 may 25,20:02" becomes "Chorshanba, 2016 may 25,20:02".
+ //
+ // The ICU library was not available in Android until N, so we can only do this in N+ devices.
+ // Pre-N devices will still see incorrect capitalization in some languages.
+ if (VERSION.SDK_INT < VERSION_CODES.N) {
+ return value;
+ }
+
+ // Using the ICU library is safer than just applying toUpperCase() on the first letter of the
+ // word because in some languages, there can be multiple starting characters which should be
+ // upper-cased together. For example in Dutch "ij" is a digraph in which both letters should be
+ // capitalized together.
+
+ // TITLECASE_NO_LOWERCASE is necessary so that things that are already capitalized are not
+ // lower-cased as part of the conversion.
+ return UCharacter.toTitleCase(
+ Locale.getDefault(),
+ value.toString(),
+ BreakIterator.getSentenceInstance(),
+ UCharacter.TITLECASE_NO_LOWERCASE);
+ }
+
+ private static boolean isWithin3Days(long nowMillis, long timestampMillis) {
+ Calendar threeDaysAgoStartOfDay = Calendar.getInstance();
+ threeDaysAgoStartOfDay.setTimeInMillis(nowMillis);
+
+ // This is attempting to find the start of the current day, but it's not quite right due to
+ // daylight savings. Unfortunately there doesn't seem to be a way to get the correct start of
+ // the day without using Joda or Java8, both of which are disallowed. This means that the wrong
+ // formatting may be applied on days with time changes (though the displayed values will be
+ // correct).
+ threeDaysAgoStartOfDay.add(
+ Calendar.HOUR_OF_DAY, -threeDaysAgoStartOfDay.get(Calendar.HOUR_OF_DAY));
+ threeDaysAgoStartOfDay.add(Calendar.MINUTE, -threeDaysAgoStartOfDay.get(Calendar.MINUTE));
+ threeDaysAgoStartOfDay.add(Calendar.SECOND, -threeDaysAgoStartOfDay.get(Calendar.SECOND));
+
+ threeDaysAgoStartOfDay.add(Calendar.DATE, -2);
+
+ Calendar then = Calendar.getInstance();
+ then.setTimeInMillis(timestampMillis);
+
+ return then.equals(threeDaysAgoStartOfDay) || then.after(threeDaysAgoStartOfDay);
+ }
+
+ private static boolean isSameDay(long firstMillis, long secondMillis) {
+ Calendar first = Calendar.getInstance();
+ first.setTimeInMillis(firstMillis);
+
+ Calendar second = Calendar.getInstance();
+ second.setTimeInMillis(secondMillis);
+
+ return first.get(Calendar.YEAR) == second.get(Calendar.YEAR)
+ && first.get(Calendar.MONTH) == second.get(Calendar.MONTH)
+ && first.get(Calendar.DAY_OF_MONTH) == second.get(Calendar.DAY_OF_MONTH);
+ }
+}
diff --git a/java/com/android/dialer/calllogutils/CallEntryFormatter.java b/java/com/android/dialer/calllogutils/CallLogDurations.java
index c5ec15748..20998deb4 100644
--- a/java/com/android/dialer/calllogutils/CallEntryFormatter.java
+++ b/java/com/android/dialer/calllogutils/CallLogDurations.java
@@ -18,67 +18,16 @@ package com.android.dialer.calllogutils;
import android.content.Context;
import android.content.res.Resources;
-import android.icu.lang.UCharacter;
-import android.icu.text.BreakIterator;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.text.format.DateUtils;
import android.text.format.Formatter;
import com.android.dialer.util.DialerUtils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import java.util.Locale;
import java.util.concurrent.TimeUnit;
-/** Utility class for formatting data and data usage in call log entries. */
-public class CallEntryFormatter {
-
- /**
- * Formats the provided date into a value suitable for display in the current locale.
- *
- * <p>For example, returns a string like "Wednesday, May 25, 2016, 8:02PM" or "Chorshanba, 2016
- * may 25,20:02".
- *
- * <p>For pre-N devices, the returned value may not start with a capital if the local convention
- * is to not capitalize day names. On N+ devices, the returned value is always capitalized.
- */
- public static CharSequence formatDate(Context context, long callDateMillis) {
- CharSequence dateValue =
- DateUtils.formatDateRange(
- context,
- callDateMillis /* startDate */,
- callDateMillis /* endDate */,
- DateUtils.FORMAT_SHOW_TIME
- | DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_SHOW_WEEKDAY
- | DateUtils.FORMAT_SHOW_YEAR);
-
- // We want the beginning of the date string to be capitalized, even if the word at the beginning
- // of the string is not usually capitalized. For example, "Wednesdsay" in Uzbek is "chorshanba”
- // (not capitalized). To handle this issue we apply title casing to the start of the sentence so
- // that "chorshanba, 2016 may 25,20:02" becomes "Chorshanba, 2016 may 25,20:02".
- //
- // The ICU library was not available in Android until N, so we can only do this in N+ devices.
- // Pre-N devices will still see incorrect capitalization in some languages.
- if (VERSION.SDK_INT < VERSION_CODES.N) {
- return dateValue;
- }
-
- // Using the ICU library is safer than just applying toUpperCase() on the first letter of the
- // word because in some languages, there can be multiple starting characters which should be
- // upper-cased together. For example in Dutch "ij" is a digraph in which both letters should be
- // capitalized together.
-
- // TITLECASE_NO_LOWERCASE is necessary so that things that are already capitalized like the
- // month ("May") are not lower-cased as part of the conversion.
- return UCharacter.toTitleCase(
- Locale.getDefault(),
- dateValue.toString(),
- BreakIterator.getSentenceInstance(),
- UCharacter.TITLECASE_NO_LOWERCASE);
- }
+/** Utility class for formatting duration and data usage in call log entries. */
+public class CallLogDurations {
private static CharSequence formatDuration(Context context, long elapsedSeconds) {
Resources res = context.getResources();
diff --git a/java/com/android/dialer/calllogutils/res/values/strings.xml b/java/com/android/dialer/calllogutils/res/values/strings.xml
index 255990399..56cd94a9e 100644
--- a/java/com/android/dialer/calllogutils/res/values/strings.xml
+++ b/java/com/android/dialer/calllogutils/res/values/strings.xml
@@ -127,4 +127,7 @@
<!-- String used for displaying calls to the voicemail number in the call log -->
<string name="voicemail_string">Voicemail</string>
+
+ <!-- String to be displayed to indicate in the call log that a call just now occurred. -->
+ <string name="now">Now</string>
</resources> \ No newline at end of file