Only show recent items in the new section.

This commit limits the set of items in the new section to items that
have been receiving within the last 7 days.

In order to make the unread items more visible even when they are not in
the new section, use highlighting on them, both in the text and the play
icon.

Bug: 5403047
Change-Id: I577c58bfcb9ef2031839092d50f41c357c7decba
diff --git a/res/drawable-hdpi/ic_play_active_holo_dark.png b/res/drawable-hdpi/ic_play_active_holo_dark.png
new file mode 100644
index 0000000..179b5a1
--- /dev/null
+++ b/res/drawable-hdpi/ic_play_active_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_play_active_holo_dark.png b/res/drawable-mdpi/ic_play_active_holo_dark.png
new file mode 100644
index 0000000..042d8c1
--- /dev/null
+++ b/res/drawable-mdpi/ic_play_active_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_play_active_holo_dark.png b/res/drawable-xhdpi/ic_play_active_holo_dark.png
new file mode 100644
index 0000000..20d0583
--- /dev/null
+++ b/res/drawable-xhdpi/ic_play_active_holo_dark.png
Binary files differ
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
index 4f274a9..7e6770b 100644
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ b/src/com/android/contacts/calllog/CallLogAdapter.java
@@ -534,7 +534,7 @@
                     callTypes, date, duration, name, ntype, label, lookupUri, null);
         }
 
-        final boolean isNew = CallLogQuery.isNewSection(c);
+        final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
         // New items also use the highlighted version of the text.
         final boolean isHighlighted = isNew;
         mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted);
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index 6378c5e..bfedba5 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -65,7 +65,7 @@
 
         if (canPlay) {
             // Playback action takes preference.
-            configurePlaySecondaryAction(views);
+            configurePlaySecondaryAction(views, isHighlighted);
             views.dividerView.setVisibility(View.VISIBLE);
         } else if (canCall) {
             // Call is the secondary action.
@@ -99,9 +99,10 @@
     }
 
     /** Sets the secondary action to correspond to the play button. */
-    private void configurePlaySecondaryAction(CallLogListItemViews views) {
+    private void configurePlaySecondaryAction(CallLogListItemViews views, boolean isHighlighted) {
         views.secondaryActionView.setVisibility(View.VISIBLE);
-        views.secondaryActionView.setImageResource(R.drawable.ic_play);
+        views.secondaryActionView.setImageResource(
+                isHighlighted ? R.drawable.ic_play_active_holo_dark : R.drawable.ic_play_holo_dark);
         views.secondaryActionView.setContentDescription(
                 mResources.getString(R.string.description_call_log_play_button));
     }
diff --git a/src/com/android/contacts/calllog/CallLogQuery.java b/src/com/android/contacts/calllog/CallLogQuery.java
index e622b3d..90017b7 100644
--- a/src/com/android/contacts/calllog/CallLogQuery.java
+++ b/src/com/android/contacts/calllog/CallLogQuery.java
@@ -42,6 +42,7 @@
             Calls.CACHED_NORMALIZED_NUMBER,  // 13
             Calls.CACHED_PHOTO_ID,           // 14
             Calls.CACHED_FORMATTED_NUMBER,   // 15
+            Calls.IS_READ,                   // 16
     };
 
     public static final int ID = 0;
@@ -60,8 +61,9 @@
     public static final int CACHED_NORMALIZED_NUMBER = 13;
     public static final int CACHED_PHOTO_ID = 14;
     public static final int CACHED_FORMATTED_NUMBER = 15;
+    public static final int IS_READ = 16;
     /** The index of the synthetic "section" column in the extended projection. */
-    public static final int SECTION = 16;
+    public static final int SECTION = 17;
 
     /**
      * The name of the synthetic "section" column.
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
index 2a11cc3..affdd1d 100644
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ b/src/com/android/contacts/calllog/CallLogQueryHandler.java
@@ -18,6 +18,7 @@
 
 import com.android.common.io.MoreCloseables;
 import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
+import com.google.android.collect.Lists;
 
 import android.content.AsyncQueryHandler;
 import android.content.ContentResolver;
@@ -37,11 +38,15 @@
 import android.util.Log;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import javax.annotation.concurrent.GuardedBy;
 
 /** Handles asynchronous queries to the call log. */
 /*package*/ class CallLogQueryHandler extends AsyncQueryHandler {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
     private static final String TAG = "CallLogQueryHandler";
 
     /** The token for the query to fetch the new entries from the call log. */
@@ -58,6 +63,12 @@
     /** The token for the query to fetch voicemail status messages. */
     private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 58;
 
+    /**
+     * The time window from the current time within which an unread entry will be added to the new
+     * section.
+     */
+    private static final long NEW_SECTION_TIME_WINDOW = TimeUnit.DAYS.toMillis(7);
+
     private final WeakReference<Listener> mListener;
 
     /** The cursor containing the new calls, or null if they have not yet been fetched. */
@@ -107,7 +118,8 @@
         // The values in this row correspond to default values for _PROJECTION from CallLogQuery
         // plus the section value.
         matrixCursor.addRow(new Object[]{
-                0L, "", 0L, 0L, 0, "", "", "", null, 0, null, null, null, null, 0L, null, section
+                0L, "", 0L, 0L, 0, "", "", "", null, 0, null, null, null, null, 0L, null, 0,
+                section
         });
         return matrixCursor;
     }
@@ -157,8 +169,10 @@
         // We need to check for NULL explicitly otherwise entries with where READ is NULL
         // may not match either the query or its negation.
         // We consider the calls that are not yet consumed (i.e. IS_READ = 0) as "new".
-        String selection = String.format("%s IS NOT NULL AND %s = 0", Calls.IS_READ, Calls.IS_READ);
-        String[] selectionArgs = null;
+        String selection = String.format("%s IS NOT NULL AND %s = 0 AND %s > ?",
+                Calls.IS_READ, Calls.IS_READ, Calls.DATE);
+        List<String> selectionArgs = Lists.newArrayList(
+                Long.toString(System.currentTimeMillis() - NEW_SECTION_TIME_WINDOW));
         if (!isNew) {
             // Negate the query.
             selection = String.format("NOT (%s)", selection);
@@ -166,12 +180,11 @@
         if (voicemailOnly) {
             // Add a clause to fetch only items of type voicemail.
             selection = String.format("(%s) AND (%s = ?)", selection, Calls.TYPE);
-            selectionArgs = new String[]{
-                    Integer.toString(Calls.VOICEMAIL_TYPE),
-            };
+            selectionArgs.add(Integer.toString(Calls.VOICEMAIL_TYPE));
         }
         startQuery(token, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
-                CallLogQuery._PROJECTION, selection, selectionArgs, Calls.DEFAULT_SORT_ORDER);
+                CallLogQuery._PROJECTION, selection, selectionArgs.toArray(EMPTY_STRING_ARRAY),
+                Calls.DEFAULT_SORT_ORDER);
     }
 
     /** Cancel any pending fetch request. */
diff --git a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java b/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
index 331d388..a88bf4f 100644
--- a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
+++ b/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
@@ -29,7 +29,7 @@
     public static Object[] createTestValues() {
         Object[] values = new Object[]{
                 0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null
+                0L, null, 0,
         };
         assertEquals(CallLogQuery._PROJECTION.length, values.length);
         return values;
@@ -38,7 +38,7 @@
     public static Object[] createTestExtendedValues() {
         Object[] values = new Object[]{
                 0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null, CallLogQuery.SECTION_OLD_ITEM
+                0L, null, 1, CallLogQuery.SECTION_OLD_ITEM
         };
         Assert.assertEquals(CallLogQuery.EXTENDED_PROJECTION.length, values.length);
         return values;