Fixed the problem where updating event colors would cause exceptions

Bug: 6742712
Change-Id: Ie097e05c74995513b5b6fc04efd8e0d35876b698
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index dd8741f..0bc80c5 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -203,8 +203,9 @@
     private static final String SQL_WHERE_CALENDAR_COLOR = Calendars.ACCOUNT_NAME + "=? AND "
             + Calendars.ACCOUNT_TYPE + "=? AND " + Calendars.CALENDAR_COLOR_KEY + "=?";
 
-    private static final String SQL_WHERE_EVENT_COLOR = Events.ACCOUNT_NAME + "=? AND "
-            + Events.ACCOUNT_TYPE + "=? AND " + Events.EVENT_COLOR_KEY + "=?";
+    private static final String SQL_WHERE_EVENT_COLOR = Calendars._ID + " in (SELECT _id from "
+            + Tables.CALENDARS + " WHERE " + Events.ACCOUNT_NAME + "=? AND " + Events.ACCOUNT_TYPE
+            + "=?) AND " + Events.EVENT_COLOR_KEY + "=?";
 
     protected static final String SQL_WHERE_ID = GENERIC_ID + "=?";
     private static final String SQL_WHERE_EVENT_ID = GENERIC_EVENT_ID + "=?";
@@ -3875,10 +3876,17 @@
             }
 
             case COLORS:
-                Integer color = values.getAsInteger(Colors.COLOR);
-                if (values.size() > 1 || (values.size() == 1 && color == null)) {
-                    throw new UnsupportedOperationException("You may only change the COLOR "
-                            + "for an existing Colors entry.");
+                int validValues = 0;
+                if (values.getAsInteger(Colors.COLOR) != null) {
+                    validValues++;
+                }
+                if (values.getAsString(Colors.DATA) != null) {
+                    validValues++;
+                }
+
+                if (values.size() != validValues) {
+                    throw new UnsupportedOperationException("You may only change the COLOR and"
+                            + " DATA columns for an existing Colors entry.");
                 }
                 return handleUpdateColors(values, appendAccountToSelection(uri, selection,
                         Calendars.ACCOUNT_NAME, Calendars.ACCOUNT_TYPE),
diff --git a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
index ab5f0ac..597bf29 100644
--- a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
+++ b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
@@ -1072,7 +1072,7 @@
         return bob.toString();
     }
 
-    private long insertColor(long colorType, String colorKey, long color) {
+    private Uri insertColor(long colorType, String colorKey, long color) {
         ContentValues m = new ContentValues();
         m.put(Colors.ACCOUNT_NAME, DEFAULT_ACCOUNT);
         m.put(Colors.ACCOUNT_TYPE, DEFAULT_ACCOUNT_TYPE);
@@ -1083,9 +1083,31 @@
 
         Uri uri = CalendarContract.Colors.CONTENT_URI;
 
-        uri = mResolver.insert(addSyncQueryParams(uri, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), m);
-        String id = uri.getLastPathSegment();
-        return Long.parseLong(id);
+        return mResolver.insert(addSyncQueryParams(uri, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), m);
+    }
+
+    private void updateAndCheckColor(long colorId, long colorType, String colorKey, long color) {
+
+        Uri uri = CalendarContract.Colors.CONTENT_URI;
+
+        final String where = Colors.ACCOUNT_NAME + "=? AND " + Colors.ACCOUNT_TYPE + "=? AND "
+                + Colors.COLOR_TYPE + "=? AND " + Colors.COLOR_KEY + "=?";
+
+        String[] selectionArgs = new String[] {
+                DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE, Long.toString(colorType), colorKey
+        };
+
+        ContentValues cv = new ContentValues();
+        cv.put(Colors.COLOR, color);
+        cv.put(Colors.DATA, obsToString(colorType, colorKey, color));
+
+        int count = mResolver.update(
+                addSyncQueryParams(uri, DEFAULT_ACCOUNT, DEFAULT_ACCOUNT_TYPE), cv, where,
+                selectionArgs);
+
+        checkColor(colorId, colorType, colorKey, color);
+
+        assertEquals(1, count);
     }
 
     /**
@@ -1293,19 +1315,42 @@
         mMetaData.clearInstanceRange();
     }
 
-    public void testInsertColor() throws Exception {
-        checkColor(Colors.TYPE_EVENT, "1" /* color key */, 11 /* color */);
+    public void testInsertAndUpdateColor() throws Exception {
+        // Calendar Color
+        long colorType = Colors.TYPE_CALENDAR;
+        String colorKey = "123";
+        long colorValue = 11;
+        long colorId = insertAndCheckColor(colorType, colorKey, colorValue);
+
         try {
-            checkColor(Colors.TYPE_EVENT, "1" /* color key */, 11 /* color */);
+            insertAndCheckColor(colorType, colorKey, colorValue);
             fail("Expected to fail with duplicate insertion");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
-        checkColor(Colors.TYPE_CALENDAR, "1" /* color key */, 22 /* color */);
+        // Test Update
+        colorValue += 11;
+        updateAndCheckColor(colorId, colorType, colorKey, colorValue);
+
+        // Event Color
+        colorType = Colors.TYPE_EVENT;
+        colorValue += 11;
+
+        colorId = insertAndCheckColor(colorType, colorKey, colorValue);
+        try {
+            insertAndCheckColor(colorType, colorKey, colorValue);
+            fail("Expected to fail with duplicate insertion");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        // Test Update
+        colorValue += 11;
+        updateAndCheckColor(colorId, colorType, colorKey, colorValue);
     }
 
-    private void checkColor(long colorType, String colorKey, long color) {
+    private void checkColor(long colorId, long colorType, String colorKey, long color) {
         String[] projection = new String[] {
                 Colors.ACCOUNT_NAME, // 0
                 Colors.ACCOUNT_TYPE, // 1
@@ -1316,8 +1361,6 @@
                 Colors.DATA,         // 6
         };
 
-        long color1Id = insertColor(colorType, colorKey, color);
-
         Cursor cursor = mResolver.query(Colors.CONTENT_URI, projection, Colors.COLOR_KEY
                 + "=? AND " + Colors.COLOR_TYPE + "=?", new String[] {
                 colorKey, Long.toString(colorType)
@@ -1331,11 +1374,19 @@
         assertEquals(colorType, cursor.getLong(2));
         assertEquals(colorKey, cursor.getString(3));
         assertEquals(color, cursor.getLong(4));
-        assertEquals(color1Id, cursor.getLong(5));
+        assertEquals(colorId, cursor.getLong(5));
         assertEquals(obsToString(colorType, colorKey, color), cursor.getString(6));
         cursor.close();
     }
 
+    private long insertAndCheckColor(long colorType, String colorKey, long color) {
+        Uri uri = insertColor(colorType, colorKey, color);
+        long id = Long.parseLong(uri.getLastPathSegment());
+
+        checkColor(id, colorType, colorKey, color);
+        return id;
+    }
+
     public void testInsertNormalEvents() throws Exception {
         final int calId = insertCal("Calendar0", DEFAULT_TIMEZONE);
         Cursor cursor = mResolver.query(mEventsUri, null, null, null, null);