New API to clear usage stats

resolver.delete(DataUsageFeedback.FEEDBACK_URI, null, null);

Bug 5475575

Change-Id: I20adaea0350e95a8f8526507ddc1b2bdc8e8fe13
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 13ec9b3..a14c5c7 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -354,6 +354,7 @@
     private static final int PROFILE_PHOTO = 19011;
     private static final int PROFILE_DISPLAY_PHOTO = 19012;
 
+    private static final int DATA_USAGE_FEEDBACK = 20000;
     private static final int DATA_USAGE_FEEDBACK_ID = 20001;
 
     private static final int STREAM_ITEMS = 21000;
@@ -1133,6 +1134,7 @@
         matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER);
         matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS);
         matcher.addURI(ContactsContract.AUTHORITY, "data/postals/#", POSTALS_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "data/usagefeedback", DATA_USAGE_FEEDBACK);
         /** "*" is in CSV form with data ids ("123,456,789") */
         matcher.addURI(ContactsContract.AUTHORITY, "data/usagefeedback/*", DATA_USAGE_FEEDBACK_ID);
         matcher.addURI(ContactsContract.AUTHORITY, "data/callables/", CALLABLES);
@@ -3467,6 +3469,10 @@
                         new String[]{streamItemPhotoId, streamItemId});
             }
 
+            case DATA_USAGE_FEEDBACK: {
+                return deleteDataUsageFeedback();
+            }
+
             default: {
                 mSyncToNetwork = true;
                 return mLegacyApiSupport.delete(uri, selection, selectionArgs);
@@ -3624,6 +3630,21 @@
         return updateRawContact(rawContactId, mValues, callerIsSyncAdapter);
     }
 
+    private int deleteDataUsageFeedback() {
+        final SQLiteDatabase db = mActiveDb.get();
+        db.execSQL("UPDATE " + Tables.RAW_CONTACTS + " SET " +
+                Contacts.TIMES_CONTACTED + "=0," +
+                Contacts.LAST_TIME_CONTACTED + "=NULL"
+                );
+        db.execSQL("UPDATE " + Tables.CONTACTS + " SET " +
+                Contacts.TIMES_CONTACTED + "=0," +
+                Contacts.LAST_TIME_CONTACTED + "=NULL"
+                );
+        db.delete(Tables.DATA_USAGE_STAT, null, null);
+
+        return 1;
+    }
+
     @Override
     protected int updateInTransaction(Uri uri, ContentValues values, String selection,
             String[] selectionArgs) {
diff --git a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
index 45c360e..fd22f35 100644
--- a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
@@ -1194,6 +1194,14 @@
         cursor.close();
     }
 
+    protected void assertRowCount(int expectedCount, Uri uri, String selection, String[] args) {
+        Cursor cursor = mResolver.query(uri, null, selection, args, null);
+        int count = cursor.getCount();
+        cursor.close();
+
+        assertEquals(expectedCount, count);
+    }
+
     /**
      * A contact in the database, and the attributes used to create it.  Construct using
      * {@link GoldenContactBuilder#build()}.
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 5539815..6471a3f 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -6497,6 +6497,39 @@
         }
     }
 
+    public void testDeleteDataUsageFeedback() {
+        // First, there's no frequent.  (We use strequent here only because frequent is hidden
+        // and may be removed someday.)
+        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
+
+        ContentValues values = new ContentValues();
+        createContact(values, "First", "Contact", "5551112222", "email1@email.com",
+                StatusUpdates.OFFLINE, 0, 0, 0, 0);
+
+        sendFeedback("email1@email.com", DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values);
+
+        // Now there should be one frequent.
+        assertRowCount(1, Contacts.CONTENT_STREQUENT_URI, null, null);
+
+        assertRowCount(1, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
+        assertRowCount(1, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
+
+        // Purge all stats.
+        assertTrue(mResolver.delete(DataUsageFeedback.FEEDBACK_URI, null, null) > 0);
+
+        // Now there's no frequent.
+        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
+
+        // The following values should all be 0 or null.
+        assertRowCount(0, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
+        assertRowCount(0, Contacts.CONTENT_URI, Contacts.LAST_TIME_CONTACTED + ">0", null);
+        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
+        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.LAST_TIME_CONTACTED + ">0", null);
+
+        // Calling it when there's no usage stats will still return a positive value.
+        assertTrue(mResolver.delete(DataUsageFeedback.FEEDBACK_URI, null, null) > 0);
+    }
+
     private Cursor queryGroupMemberships(Account account) {
         Cursor c = mResolver.query(maybeAddAccountQueryParameters(Data.CONTENT_URI, account),
                 new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},