Merge "DO NOT MERGE - Merge ab/7272582" am: 7999f23e0d am: 44da8e6ce8

Original change: https://android-review.googlesource.com/c/platform/packages/providers/CalendarProvider/+/1736081

Change-Id: Ib119fc5acca810df66cd965430adcf02f84f0571
diff --git a/Android.bp b/Android.bp
index 0c29652..f971e51 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,6 +35,7 @@
 
 android_app {
     name: "CalendarProvider",
+    defaults: ["platform_app_defaults"],
     static_libs: [
         "guava",
         "android-common",
@@ -44,6 +45,7 @@
         "src/**/*.java",
         "src/com/android/providers/calendar/EventLogTags.logtags",
     ],
+    libs: ["app-compat-annotations"],
     platform_apis: true,
     privileged: true,
 
@@ -56,3 +58,8 @@
         include_filter: ["com.android.providers.calendar.*"],
     },
 }
+
+platform_compat_config {
+    name: "calendar-provider-compat-config",
+    src: ":CalendarProvider",
+}
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 84011cd..3f52171 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,6 +40,8 @@
     <uses-permission android:name="android.permission.USE_RESERVED_DISK" />
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
 
     <application android:label="@string/calendar_storage"
                  android:allowBackup="false"
@@ -107,5 +109,9 @@
             </intent-filter>
         </receiver>
 
+        <service android:name="CalendarProviderJobService"
+                 android:exported="false"
+                 android:permission="android.permission.BIND_JOB_SERVICE" />
+
     </application>
 </manifest>
diff --git a/OWNERS b/OWNERS
index 3ca2b75..dc2d0b3 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,2 @@
 omakoto@google.com
 yamasani@google.com
-fkupolov@google.com
diff --git a/src/com/android/providers/calendar/CalendarAlarmManager.java b/src/com/android/providers/calendar/CalendarAlarmManager.java
index 1c39be6..c8daec2 100644
--- a/src/com/android/providers/calendar/CalendarAlarmManager.java
+++ b/src/com/android/providers/calendar/CalendarAlarmManager.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.calendar;
 
+import com.android.calendarcommon2.Time;
 import com.android.providers.calendar.CalendarDatabaseHelper.Tables;
 import com.android.providers.calendar.CalendarDatabaseHelper.Views;
 import com.google.common.annotations.VisibleForTesting;
@@ -38,7 +39,6 @@
 import android.provider.CalendarContract.Instances;
 import android.provider.CalendarContract.Reminders;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.Log;
 
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -170,13 +170,13 @@
             }
             Intent intent = getCheckNextAlarmIntent(mContext, removeAlarms);
             PendingIntent pending = PendingIntent.getBroadcast(mContext, 0 /* ignored */, intent,
-                    PendingIntent.FLAG_NO_CREATE);
+                    PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);
             if (pending != null) {
                 // Cancel any previous Alarm check requests
                 cancel(pending);
             }
             pending = PendingIntent.getBroadcast(mContext, 0 /* ignored */, intent,
-                    PendingIntent.FLAG_CANCEL_CURRENT);
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
 
             // Trigger the check in 5s from now, so that we can have batch processing.
             long triggerAtTime = SystemClock.elapsedRealtime() + ALARM_CHECK_DELAY_MILLIS;
@@ -249,7 +249,7 @@
      * @param cp2 TODO
      */
     private void scheduleNextAlarmLocked(SQLiteDatabase db, CalendarProvider2 cp2) {
-        cp2.mSanityChecker.updateLastCheckTime();
+        cp2.mConfidenceChecker.updateLastCheckTime();
 
         Time time = new Time();
 
@@ -261,7 +261,7 @@
 
         if (Log.isLoggable(CalendarProvider2.TAG, Log.DEBUG)) {
             time.set(start);
-            String startTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+            String startTimeStr = time.format();
             Log.d(CalendarProvider2.TAG, "runScheduleNextAlarm() start search: " + startTimeStr);
         }
 
@@ -306,9 +306,9 @@
         // string query parameter to an int in myAlarmtime>=?, so the comparison
         // will fail. This could be simplified if bug 2464440 is resolved.
 
-        time.setToNow();
-        time.normalize(false);
-        long localOffset = time.gmtoff * 1000;
+        time.set(System.currentTimeMillis());
+        time.normalize();
+        long localOffset = time.getGmtOffset() * 1000;
 
         String allDayOffset = " -(" + localOffset + ") ";
         String subQueryPrefix = "SELECT " + Instances.BEGIN;
@@ -373,7 +373,7 @@
 
             if (Log.isLoggable(CalendarProvider2.TAG, Log.DEBUG)) {
                 time.set(nextAlarmTime);
-                String alarmTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                String alarmTimeStr = time.format();
                 Log.d(CalendarProvider2.TAG,
                         "cursor results: " + cursor.getCount() + " nextAlarmTime: " + alarmTimeStr);
             }
@@ -394,9 +394,9 @@
 
                 if (Log.isLoggable(CalendarProvider2.TAG, Log.DEBUG)) {
                     time.set(alarmTime);
-                    String schedTime = time.format(" %a, %b %d, %Y %I:%M%P");
+                    String schedTime = time.format();
                     time.set(startTime);
-                    String startTimeStr = time.format(" %a, %b %d, %Y %I:%M%P");
+                    String startTimeStr = time.format();
 
                     Log.d(CalendarProvider2.TAG,
                             "  looking at id: " + eventId + " " + startTime + startTimeStr
diff --git a/src/com/android/providers/calendar/CalendarSanityChecker.java b/src/com/android/providers/calendar/CalendarConfidenceChecker.java
similarity index 96%
rename from src/com/android/providers/calendar/CalendarSanityChecker.java
rename to src/com/android/providers/calendar/CalendarConfidenceChecker.java
index ce7b62a..ae340b3 100644
--- a/src/com/android/providers/calendar/CalendarSanityChecker.java
+++ b/src/com/android/providers/calendar/CalendarConfidenceChecker.java
@@ -33,10 +33,10 @@
  * We call {@link #checkLastCheckTime} at the provider public entry points to make sure
  * {@link CalendarAlarmManager#scheduleNextAlarmLocked} has been called recently enough.
  *
- * atest tests/src/com/android/providers/calendar/CalendarSanityCheckerTest.java
+ * atest tests/src/com/android/providers/calendar/CalendarConfidenceCheckerTest.java
  */
-public class CalendarSanityChecker {
-    private static final String TAG = "CalendarSanityChecker";
+public class CalendarConfidenceChecker {
+    private static final String TAG = "CalendarConfidenceChecker";
 
     private static final boolean DEBUG = false;
 
@@ -68,7 +68,7 @@
     @VisibleForTesting
     final SharedPreferences mPrefs;
 
-    public CalendarSanityChecker(Context context) {
+    public CalendarConfidenceChecker(Context context) {
         mContext = context;
         mPrefs = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
     }
diff --git a/src/com/android/providers/calendar/CalendarDatabaseHelper.java b/src/com/android/providers/calendar/CalendarDatabaseHelper.java
index 1e2b986..b96dada 100644
--- a/src/com/android/providers/calendar/CalendarDatabaseHelper.java
+++ b/src/com/android/providers/calendar/CalendarDatabaseHelper.java
@@ -36,9 +36,9 @@
 import android.provider.CalendarContract.Reminders;
 import android.provider.SyncStateContract;
 import android.text.TextUtils;
-import android.text.format.Time;
 import android.util.Log;
 
+import com.android.calendarcommon2.Time;
 import com.android.common.content.SyncStateContentProviderHelper;
 import com.google.common.annotations.VisibleForTesting;
 
@@ -1476,10 +1476,10 @@
 
     private static boolean fixAllDayTime(Time time, String timezone, Long timeInMillis) {
         time.set(timeInMillis);
-        if(time.hour != 0 || time.minute != 0 || time.second != 0) {
-            time.hour = 0;
-            time.minute = 0;
-            time.second = 0;
+        if(time.getHour() != 0 || time.getMinute() != 0 || time.getSecond() != 0) {
+            time.setHour(0);
+            time.setMinute(0);
+            time.setSecond(0);
             return true;
         }
         return false;
@@ -2576,22 +2576,22 @@
 
                         time.clear(timezone);
                         update |= fixAllDayTime(time, timezone, dtstart);
-                        dtstart = time.normalize(false);
+                        dtstart = time.normalize();
 
                         time.clear(timezone);
                         update |= fixAllDayTime(time, timezone, dtend);
-                        dtend = time.normalize(false);
+                        dtend = time.normalize();
 
                         if (dtstart2 != null) {
                             time.clear(timezone2);
                             update |= fixAllDayTime(time, timezone2, dtstart2);
-                            dtstart2 = time.normalize(false);
+                            dtstart2 = time.normalize();
                         }
 
                         if (dtend2 != null) {
                             time.clear(timezone2);
                             update |= fixAllDayTime(time, timezone2, dtend2);
-                            dtend2 = time.normalize(false);
+                            dtend2 = time.normalize();
                         }
 
                         if (!TextUtils.isEmpty(duration)) {
@@ -2637,12 +2637,12 @@
 
                         time.clear(timezone);
                         update |= fixAllDayTime(time, timezone, dtstart);
-                        dtstart = time.normalize(false);
+                        dtstart = time.normalize();
 
                         if (dtstart2 != null) {
                             time.clear(timezone2);
                             update |= fixAllDayTime(time, timezone2, dtstart2);
-                            dtstart2 = time.normalize(false);
+                            dtstart2 = time.normalize();
                         }
 
                         if (TextUtils.isEmpty(duration)) {
@@ -2756,17 +2756,17 @@
                     oldTime.clear(eTz);
                     oldTime.set(dtstart);
                     newTime.clear(tz);
-                    newTime.set(oldTime.monthDay, oldTime.month, oldTime.year);
-                    newTime.normalize(false);
-                    dtstart = newTime.toMillis(false /*ignoreDst*/);
+                    newTime.set(oldTime.getDay(), oldTime.getMonth(), oldTime.getYear());
+                    newTime.normalize();
+                    dtstart = newTime.toMillis();
 
                     // Convert end time for all day events into the timezone of their calendar
                     oldTime.clear(eTz);
                     oldTime.set(dtend);
                     newTime.clear(tz);
-                    newTime.set(oldTime.monthDay, oldTime.month, oldTime.year);
-                    newTime.normalize(false);
-                    dtend = newTime.toMillis(false /*ignoreDst*/);
+                    newTime.set(oldTime.getDay(), oldTime.getMonth(), oldTime.getYear());
+                    newTime.normalize();
+                    dtend = newTime.toMillis();
 
                     newData[0] = String.valueOf(dtstart);
                     newData[1] = String.valueOf(dtend);
diff --git a/src/com/android/providers/calendar/CalendarInstancesHelper.java b/src/com/android/providers/calendar/CalendarInstancesHelper.java
index 1ab5a01..8e2fdc7 100644
--- a/src/com/android/providers/calendar/CalendarInstancesHelper.java
+++ b/src/com/android/providers/calendar/CalendarInstancesHelper.java
@@ -21,6 +21,7 @@
 import com.android.calendarcommon2.EventRecurrence;
 import com.android.calendarcommon2.RecurrenceProcessor;
 import com.android.calendarcommon2.RecurrenceSet;
+import com.android.calendarcommon2.Time;
 import com.android.providers.calendar.CalendarDatabaseHelper.Tables;
 
 import android.content.ContentValues;
@@ -33,7 +34,6 @@
 import android.provider.CalendarContract.Events;
 import android.provider.CalendarContract.Instances;
 import android.text.TextUtils;
-import android.text.format.Time;
 import android.util.Log;
 import android.util.TimeFormatException;
 
@@ -288,9 +288,9 @@
                     }
 
                     // need to parse the event into a local calendar.
-                    eventTime.timezone = eventTimezone;
+                    eventTime.setTimezone(eventTimezone);
                     eventTime.set(dtstartMillis);
-                    eventTime.allDay = allDay;
+                    eventTime.setAllDay(allDay);
 
                     if (durationStr == null) {
                         // should not happen.
@@ -332,9 +332,9 @@
                     // Initialize the "eventTime" timezone outside the loop.
                     // This is used in computeTimezoneDependentFields().
                     if (allDay) {
-                        eventTime.timezone = Time.TIMEZONE_UTC;
+                        eventTime.setTimezone(Time.TIMEZONE_UTC);
                     } else {
-                        eventTime.timezone = localTimezone;
+                        eventTime.setTimezone(localTimezone);
                     }
 
                     long durationMillis = duration.getMillis();
@@ -404,9 +404,9 @@
                     initialValues.put(Events.DELETED, deleted);
 
                     if (allDay) {
-                        eventTime.timezone = Time.TIMEZONE_UTC;
+                        eventTime.setTimezone(Time.TIMEZONE_UTC);
                     } else {
-                        eventTime.timezone = localTimezone;
+                        eventTime.setTimezone(localTimezone);
                     }
                     CalendarInstancesHelper.computeTimezoneDependentFields(dtstartMillis,
                             dtendMillis, eventTime, initialValues);
@@ -703,9 +703,9 @@
             // Update the timezone-dependent fields.
             Time local = new Time();
             if (allDay) {
-                local.timezone = Time.TIMEZONE_UTC;
+                local.setTimezone(Time.TIMEZONE_UTC);
             } else {
-                local.timezone = fields.timezone;
+                local.setTimezone(fields.timezone);
             }
 
             CalendarInstancesHelper.computeTimezoneDependentFields(dtstartMillis, dtendMillis,
@@ -889,12 +889,12 @@
     static void computeTimezoneDependentFields(long begin, long end,
             Time local, ContentValues values) {
         local.set(begin);
-        int startDay = Time.getJulianDay(begin, local.gmtoff);
-        int startMinute = local.hour * 60 + local.minute;
+        int startDay = Time.getJulianDay(begin, local.getGmtOffset());
+        int startMinute = local.getHour() * 60 + local.getMinute();
 
         local.set(end);
-        int endDay = Time.getJulianDay(end, local.gmtoff);
-        int endMinute = local.hour * 60 + local.minute;
+        int endDay = Time.getJulianDay(end, local.getGmtOffset());
+        int endMinute = local.getHour() * 60 + local.getMinute();
 
         // Special case for midnight, which has endMinute == 0.  Change
         // that to +24 hours on the previous day to make everything simpler.
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index e439f3a..389b5b9 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -23,6 +23,9 @@
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
 import android.content.BroadcastReceiver;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
@@ -44,6 +47,7 @@
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -60,9 +64,7 @@
 import android.provider.CalendarContract.SyncState;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.Log;
-import android.util.TimeFormatException;
 import android.util.TimeUtils;
 
 import com.android.calendarcommon2.DateException;
@@ -70,6 +72,7 @@
 import com.android.calendarcommon2.EventRecurrence;
 import com.android.calendarcommon2.RecurrenceProcessor;
 import com.android.calendarcommon2.RecurrenceSet;
+import com.android.calendarcommon2.Time;
 import com.android.internal.util.ProviderAccessStats;
 import com.android.providers.calendar.CalendarDatabaseHelper.Tables;
 import com.android.providers.calendar.CalendarDatabaseHelper.Views;
@@ -189,7 +192,7 @@
      */
     MetaData mMetaData;
     CalendarCache mCalendarCache;
-    CalendarSanityChecker mSanityChecker;
+    CalendarConfidenceChecker mConfidenceChecker;
 
     private CalendarDatabaseHelper mDbHelper;
     private CalendarInstancesHelper mInstancesHelper;
@@ -451,11 +454,19 @@
 
     /** set to 'true' to enable debug logging for recurrence exception code */
     private static final boolean DEBUG_EXCEPTION = false;
-    
+
     private static final String SELECTION_PRIMARY_CALENDAR =
             Calendars.IS_PRIMARY + "= 1"
                     + " OR " + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT;
 
+    /**
+     * The SQLiteQueryBuilder will now verify all CalendarProvider2 query selections against
+     * malicious arguments.
+     */
+    @ChangeId
+    @Disabled
+    private static final long ENFORCE_STRICT_QUERY_BUILDER = 143231523L;
+
     private final ThreadLocal<Boolean> mCallingPackageErrorLogged = new ThreadLocal<Boolean>();
 
     private Context mContext;
@@ -530,7 +541,7 @@
 
         mMetaData = new MetaData(mDbHelper);
         mInstancesHelper = new CalendarInstancesHelper(mDbHelper, mMetaData);
-        mSanityChecker = new CalendarSanityChecker(mContext);
+        mConfidenceChecker = new CalendarConfidenceChecker(mContext);
 
         // Register for Intent broadcasts
         IntentFilter filter = new IntentFilter();
@@ -720,13 +731,13 @@
         Time time = (timezone != null) ? new Time(timezone) : new Time();
         try {
             time.parse(dt2445);
-        } catch (TimeFormatException e) {
+        } catch (IllegalArgumentException e) {
             if (Log.isLoggable(TAG, Log.ERROR)) {
                 Log.e(TAG, "Cannot parse RFC2445 date " + dt2445);
             }
             return 0;
         }
-        return time.toMillis(true /* ignore DST */);
+        return time.toMillis();
     }
 
     private void updateEventsStartEndLocked(long eventId,
@@ -791,17 +802,21 @@
         String instancesTimezone = mCalendarCache.readTimezoneInstances();
         Time time = new Time(instancesTimezone);
         time.set(now);
-        time.monthDay = 1;
-        time.hour = 0;
-        time.minute = 0;
-        time.second = 0;
+        time.setDay(1);
+        time.setHour(0);
+        time.setMinute(0);
+        time.setSecond(0);
 
-        long begin = time.normalize(true);
+        long begin = time.normalize();
         long end = begin + MINIMUM_EXPANSION_SPAN;
 
         Cursor cursor = null;
         try {
-            cursor = handleInstanceQuery(new SQLiteQueryBuilder(),
+            final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setStrict(true);
+            qb.setStrictColumns(true);
+            qb.setStrictGrammar(true);
+            cursor = handleInstanceQuery(qb,
                     begin, end,
                     new String[] { Instances._ID },
                     null /* selection */, null,
@@ -853,7 +868,7 @@
     @Override
     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
             String sortOrder) {
-        mSanityChecker.checkLastCheckTime();
+        mConfidenceChecker.checkLastCheckTime();
 
         // Note don't use mCallingUid here. That's only used by mutation functions.
         final int callingUid = Binder.getCallingUid();
@@ -861,7 +876,7 @@
         mStats.incrementQueryStats(callingUid);
         final long identity = clearCallingIdentityInternal();
         try {
-            return queryInternal(uri, projection, selection, selectionArgs, sortOrder);
+            return queryInternal(uri, projection, selection, selectionArgs, sortOrder, callingUid);
         } finally {
             restoreCallingIdentityInternal(identity);
             mStats.finishOperation(callingUid);
@@ -966,7 +981,7 @@
     }
 
     private Cursor queryInternal(Uri uri, String[] projection, String selection,
-            String[] selectionArgs, String sortOrder) {
+            String[] selectionArgs, String sortOrder, int callingUid) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "query uri - " + uri);
         }
@@ -974,6 +989,9 @@
         final SQLiteDatabase db = mDbHelper.getReadableDatabase();
 
         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        if (CompatChanges.isChangeEnabled(ENFORCE_STRICT_QUERY_BUILDER, callingUid)) {
+            qb.setStrict(true);
+        }
         String groupBy = null;
         String limit = null; // Not currently implemented
         String instancesTimezone;
@@ -1706,11 +1724,11 @@
         // Change dtstart so h,m,s are 0 if necessary.
         time.clear(Time.TIMEZONE_UTC);
         time.set(dtstart.longValue());
-        if (time.hour != 0 || time.minute != 0 || time.second != 0) {
-            time.hour = 0;
-            time.minute = 0;
-            time.second = 0;
-            modValues.put(Events.DTSTART, time.toMillis(true));
+        if (time.getHour() != 0 || time.getMinute() != 0 || time.getSecond() != 0) {
+            time.setHour(0);
+            time.setMinute(0);
+            time.setSecond(0);
+            modValues.put(Events.DTSTART, time.toMillis());
             neededCorrection = true;
         }
 
@@ -1718,11 +1736,11 @@
         if (dtend != null) {
             time.clear(Time.TIMEZONE_UTC);
             time.set(dtend.longValue());
-            if (time.hour != 0 || time.minute != 0 || time.second != 0) {
-                time.hour = 0;
-                time.minute = 0;
-                time.second = 0;
-                dtend = time.toMillis(true);
+            if (time.getHour() != 0 || time.getMinute() != 0 || time.getSecond() != 0) {
+                time.setHour(0);
+                time.setMinute(0);
+                time.setSecond(0);
+                dtend = time.toMillis();
                 modValues.put(Events.DTEND, dtend);
                 neededCorrection = true;
             }
@@ -1795,7 +1813,7 @@
         // Get the start time of the first instance in the original recurrence.
         long startTimeMillis = values.getAsLong(Events.DTSTART);
         Time dtstart = new Time();
-        dtstart.timezone = values.getAsString(Events.EVENT_TIMEZONE);
+        dtstart.setTimezone(values.getAsString(Events.EVENT_TIMEZONE));
         dtstart.set(startTimeMillis);
 
         ContentValues updateValues = new ContentValues();
@@ -1834,26 +1852,30 @@
             // to display it properly. For all-day events, the "until" time string
             // must include just the date field, and not the time field. The
             // repeating events repeat up to and including the "until" time.
-            untilTime.timezone = Time.TIMEZONE_UTC;
+            untilTime.setTimezone(Time.TIMEZONE_UTC);
 
             // Subtract one second from the exception begin time to get the "until" time.
             untilTime.set(endTimeMillis - 1000); // subtract one second (1000 millis)
             if (origAllDay) {
-                untilTime.hour = untilTime.minute = untilTime.second = 0;
-                untilTime.allDay = true;
-                untilTime.normalize(false);
+                untilTime.setHour(0);
+                untilTime.setMinute(0);
+                untilTime.setSecond(0);
+                untilTime.setAllDay(true);
+                untilTime.normalize();
 
                 // This should no longer be necessary -- DTSTART should already be in the correct
                 // format for an all-day event.
-                dtstart.hour = dtstart.minute = dtstart.second = 0;
-                dtstart.allDay = true;
-                dtstart.timezone = Time.TIMEZONE_UTC;
+                dtstart.setHour(0);
+                dtstart.setMinute(0);
+                dtstart.setSecond(0);
+                dtstart.setAllDay(true);
+                dtstart.setTimezone(Time.TIMEZONE_UTC);
             }
             origRecurrence.until = untilTime.format2445();
         }
 
         updateValues.put(Events.RRULE, origRecurrence.toString());
-        updateValues.put(Events.DTSTART, dtstart.normalize(true));
+        updateValues.put(Events.DTSTART, dtstart.normalize());
         return updateValues;
     }
 
@@ -2327,7 +2349,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "insertInTransaction: " + uri);
         }
-        mSanityChecker.checkLastCheckTime();
+        mConfidenceChecker.checkLastCheckTime();
 
         validateUriParameters(uri.getQueryParameterNames());
         final int match = sUriMatcher.match(uri);
@@ -3263,7 +3285,7 @@
         }
 
         Time time = new Time(timezone);
-        time.allDay = allDay;
+        time.setAllDay(allDay);
         Long dtstartMillis = values.getAsLong(Events.DTSTART);
         if (dtstartMillis != null) {
             time.set(dtstartMillis);
@@ -3283,7 +3305,7 @@
             // date correctly.
             allDayInteger = values.getAsInteger(Events.ORIGINAL_ALL_DAY);
             if (allDayInteger != null) {
-                time.allDay = allDayInteger != 0;
+                time.setAllDay(allDayInteger != 0);
             }
             time.set(originalInstanceMillis);
             rawValues.put(CalendarContract.EventsRawTimes.ORIGINAL_INSTANCE_TIME_2445,
@@ -3292,7 +3314,7 @@
 
         Long lastDateMillis = values.getAsLong(Events.LAST_DATE);
         if (lastDateMillis != null) {
-            time.allDay = allDay;
+            time.setAllDay(allDay);
             time.set(lastDateMillis);
             rawValues.put(CalendarContract.EventsRawTimes.LAST_DATE_2445, time.format2445());
         }
@@ -3317,7 +3339,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "deleteInTransaction: " + uri);
         }
-        mSanityChecker.checkLastCheckTime();
+        mConfidenceChecker.checkLastCheckTime();
 
         validateUriParameters(uri.getQueryParameterNames());
         final int match = sUriMatcher.match(uri);
@@ -4196,7 +4218,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "updateInTransaction: " + uri);
         }
-        mSanityChecker.checkLastCheckTime();
+        mConfidenceChecker.checkLastCheckTime();
 
         validateUriParameters(uri.getQueryParameterNames());
         final int match = sUriMatcher.match(uri);
@@ -4567,7 +4589,7 @@
             // TODO review this list, document in contract.
             if (!TextUtils.isEmpty(selection)) {
                 // Only allow selections for the URIs that can reasonably use them.
-                // Whitelist of URIs allowed selections
+                // Allowed list of URIs allowed selections
                 switch (uriMatch) {
                     case SYNCSTATE:
                     case CALENDARS:
@@ -4584,7 +4606,7 @@
                 }
             } else {
                 // Disallow empty selections for some URIs.
-                // Blacklist of URIs _not_ allowed empty selections
+                // Disallowed list of URIs _not_ allowed empty selections
                 switch (uriMatch) {
                     case EVENTS:
                     case ATTENDEES:
@@ -4815,7 +4837,7 @@
         mCalendarAlarm.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                 SystemClock.elapsedRealtime() + delay,
                 PendingIntent.getBroadcast(mContext, 0, createProviderChangedBroadcast(),
-                        PendingIntent.FLAG_UPDATE_CURRENT));
+                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
     }
 
     private Intent createProviderChangedBroadcast() {
diff --git a/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java b/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
index 10c76c0..c27044f 100644
--- a/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
+++ b/src/com/android/providers/calendar/CalendarProviderBroadcastReceiver.java
@@ -17,10 +17,12 @@
 package com.android.providers.calendar;
 
 import android.app.Activity;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobWorkItem;
 import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
+import android.content.ComponentName;
 import android.content.Context;
-import android.content.IContentProvider;
 import android.content.Intent;
 import android.provider.CalendarContract;
 import android.util.Log;
@@ -41,33 +43,17 @@
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "Received intent: " + intent);
         }
-        final IContentProvider iprovider =
-                context.getContentResolver().acquireProvider(CalendarContract.AUTHORITY);
-        final ContentProvider cprovider = ContentProvider.coerceToLocalContentProvider(iprovider);
 
-        if (!(cprovider instanceof CalendarProvider2)) {
-            Slog.wtf(TAG, "CalendarProvider2 not found in CalendarProviderBroadcastReceiver.");
-            return;
+        JobWorkItem jwi = new JobWorkItem(intent);
+        JobInfo alarmJob = new JobInfo.Builder(CalendarProviderJobService.JOB_ID,
+                new ComponentName(context, CalendarProviderJobService.class))
+                .setExpedited(true)
+                .build();
+        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+        if (jobScheduler.enqueue(alarmJob, jwi) == JobScheduler.RESULT_SUCCESS) {
+            setResultCode(Activity.RESULT_OK);
+        } else {
+            Slog.wtf(TAG, "Failed to schedule expedited job");
         }
-
-        final CalendarProvider2 provider = (CalendarProvider2) cprovider;
-
-        final PendingResult result = goAsync();
-
-        new Thread(() -> {
-            // Schedule the next alarm. Please be noted that for ACTION_EVENT_REMINDER broadcast,
-            // we never remove scheduled alarms.
-            final boolean removeAlarms = intent
-                    .getBooleanExtra(CalendarAlarmManager.KEY_REMOVE_ALARMS, false);
-            provider.getOrCreateCalendarAlarmManager().runScheduleNextAlarm(removeAlarms, provider);
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Next alarm set.");
-            }
-
-            result.setResultCode(Activity.RESULT_OK);
-            result.finish();
-        }).start();
-
     }
 }
diff --git a/src/com/android/providers/calendar/CalendarProviderJobService.java b/src/com/android/providers/calendar/CalendarProviderJobService.java
new file mode 100644
index 0000000..bfec48a
--- /dev/null
+++ b/src/com/android/providers/calendar/CalendarProviderJobService.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.providers.calendar;
+
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.app.job.JobWorkItem;
+import android.content.ContentProvider;
+import android.content.IContentProvider;
+import android.provider.CalendarContract;
+import android.util.Log;
+import android.util.Slog;
+
+public class CalendarProviderJobService extends JobService {
+    private static final String TAG = CalendarProvider2.TAG;
+    static final int JOB_ID = CalendarProviderJobService.class.hashCode();
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        if (!params.isExpeditedJob()) {
+            Slog.w(TAG, "job not running as expedited");
+        }
+
+        final IContentProvider iprovider =
+                getContentResolver().acquireProvider(CalendarContract.AUTHORITY);
+        final ContentProvider cprovider = ContentProvider.coerceToLocalContentProvider(iprovider);
+
+        if (!(cprovider instanceof CalendarProvider2)) {
+            Slog.wtf(TAG, "CalendarProvider2 not found in CalendarProviderJobService.");
+            return false;
+        }
+
+        final CalendarProvider2 provider = (CalendarProvider2) cprovider;
+
+        new Thread(() -> {
+            for (JobWorkItem jwi = params.dequeueWork(); jwi != null; jwi = params.dequeueWork()) {
+                // Schedule the next alarm. Please be noted that for ACTION_EVENT_REMINDER
+                // broadcast, we never remove scheduled alarms.
+                final boolean removeAlarms = jwi.getIntent()
+                        .getBooleanExtra(CalendarAlarmManager.KEY_REMOVE_ALARMS, false);
+                provider.getOrCreateCalendarAlarmManager()
+                        .runScheduleNextAlarm(removeAlarms, provider);
+
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Next alarm set.");
+                }
+                params.completeWork(jwi);
+            }
+        }).start();
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        // The work should be very quick, so it'll be surprising if JS has to stop us.
+        Slog.wtf(TAG, "CalendarProviderJobService was stopped due to "
+                + JobParameters.getInternalReasonCodeDescription(params.getInternalStopReasonCode())
+                + "(" + params.getStopReason() + ")");
+        return true;
+    }
+}
diff --git a/src/com/android/providers/calendar/CalendarReceiver.java b/src/com/android/providers/calendar/CalendarReceiver.java
index 55b75e0..f59968b 100644
--- a/src/com/android/providers/calendar/CalendarReceiver.java
+++ b/src/com/android/providers/calendar/CalendarReceiver.java
@@ -94,7 +94,7 @@
         final PendingIntent checkIntent = PendingIntent.getBroadcast(context,
                 NEXT_EVENT_CHECK_PENDING_CODE,
                 CalendarAlarmManager.getCheckNextAlarmIntentForBroadcast(context),
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
 
         final AlarmManager am = context.getSystemService(AlarmManager.class);
 
diff --git a/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelper.java b/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelper.java
index 57aa5b3..8c5ace7 100644
--- a/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelper.java
+++ b/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelper.java
@@ -37,58 +37,58 @@
 
     final private Context mContext;
 
-    public static final Set<String> EVENTS_TABLE_WHITELIST;
-    public static final Set<String> CALENDARS_TABLE_WHITELIST;
-    public static final Set<String> INSTANCES_TABLE_WHITELIST;
+    public static final Set<String> EVENTS_TABLE_ALLOWED_LIST;
+    public static final Set<String> CALENDARS_TABLE_ALLOWED_LIST;
+    public static final Set<String> INSTANCES_TABLE_ALLOWED_LIST;
 
     static {
-        EVENTS_TABLE_WHITELIST = new ArraySet<>();
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events._ID);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.CALENDAR_ID);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.TITLE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EVENT_LOCATION);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EVENT_COLOR);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.STATUS);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.DTSTART);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.DTEND);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EVENT_TIMEZONE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EVENT_END_TIMEZONE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.DURATION);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.ALL_DAY);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.AVAILABILITY);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.RRULE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.RDATE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EXRULE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.EXDATE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.LAST_DATE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.SELF_ATTENDEE_STATUS);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Events.DISPLAY_COLOR);
+        EVENTS_TABLE_ALLOWED_LIST = new ArraySet<>();
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events._ID);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.CALENDAR_ID);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.TITLE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EVENT_LOCATION);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EVENT_COLOR);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.STATUS);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.DTSTART);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.DTEND);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EVENT_TIMEZONE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EVENT_END_TIMEZONE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.DURATION);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.ALL_DAY);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.AVAILABILITY);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.RRULE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.RDATE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EXRULE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.EXDATE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.LAST_DATE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.SELF_ATTENDEE_STATUS);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Events.DISPLAY_COLOR);
 
-        CALENDARS_TABLE_WHITELIST = new ArraySet<>();
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars._ID);
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars.CALENDAR_COLOR);
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars.VISIBLE);
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars.CALENDAR_LOCATION);
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars.CALENDAR_TIME_ZONE);
-        CALENDARS_TABLE_WHITELIST.add(CalendarContract.Calendars.IS_PRIMARY);
+        CALENDARS_TABLE_ALLOWED_LIST = new ArraySet<>();
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars._ID);
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.CALENDAR_COLOR);
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.VISIBLE);
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.CALENDAR_LOCATION);
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.CALENDAR_TIME_ZONE);
+        CALENDARS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.IS_PRIMARY);
 
-        INSTANCES_TABLE_WHITELIST = new ArraySet<>();
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances._ID);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.EVENT_ID);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.BEGIN);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.END);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.START_DAY);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.END_DAY);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.START_MINUTE);
-        INSTANCES_TABLE_WHITELIST.add(CalendarContract.Instances.END_MINUTE);
+        INSTANCES_TABLE_ALLOWED_LIST = new ArraySet<>();
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances._ID);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.EVENT_ID);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.BEGIN);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.END);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.START_DAY);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.END_DAY);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.START_MINUTE);
+        INSTANCES_TABLE_ALLOWED_LIST.add(CalendarContract.Instances.END_MINUTE);
 
         // Add calendar columns.
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Calendars.CALENDAR_COLOR);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Calendars.VISIBLE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Calendars.CALENDAR_TIME_ZONE);
-        EVENTS_TABLE_WHITELIST.add(CalendarContract.Calendars.IS_PRIMARY);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.CALENDAR_COLOR);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.VISIBLE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.CALENDAR_TIME_ZONE);
+        EVENTS_TABLE_ALLOWED_LIST.add(CalendarContract.Calendars.IS_PRIMARY);
 
-        ((ArraySet<String>) INSTANCES_TABLE_WHITELIST).addAll(EVENTS_TABLE_WHITELIST);
+        ((ArraySet<String>) INSTANCES_TABLE_ALLOWED_LIST).addAll(EVENTS_TABLE_ALLOWED_LIST);
     }
 
     public CrossProfileCalendarHelper(Context context) {
@@ -140,29 +140,29 @@
     /**
      * Returns the calibrated version of projection for a given table.
      *
-     * If the input projection is empty, return an array of all the whitelisted columns for a
+     * If the input projection is empty, return an array of all the allowed list of columns for a
      * given table. Table is determined by the input uri.
      *
      * @param projection the original projection
      * @param localUri the local uri for the query of the projection
      * @return the original value of the input projection if it's not empty, otherwise an array of
-     * all the whitelisted columns.
+     * all the allowed list of columns.
      * @throws IllegalArgumentException if the input projection contains a column that is not
-     * whitelisted for a given table.
+     * in the allowed list for a given table.
      */
     public String[] getCalibratedProjection(String[] projection, Uri localUri) {
         // If projection is not empty, check if it's valid. Otherwise fill it with all
         // allowed columns.
         Set<String> validColumnsSet = new ArraySet<String>();
         if (CalendarContract.Events.CONTENT_URI.equals(localUri)) {
-            validColumnsSet = EVENTS_TABLE_WHITELIST;
+            validColumnsSet = EVENTS_TABLE_ALLOWED_LIST;
         } else if (CalendarContract.Calendars.CONTENT_URI.equals(localUri)) {
-            validColumnsSet = CALENDARS_TABLE_WHITELIST;
+            validColumnsSet = CALENDARS_TABLE_ALLOWED_LIST;
         } else if (CalendarContract.Instances.CONTENT_URI.equals(localUri)
                 || CalendarContract.Instances.CONTENT_BY_DAY_URI.equals(localUri)
                 || CalendarContract.Instances.CONTENT_SEARCH_URI.equals(localUri)
                 || CalendarContract.Instances.CONTENT_SEARCH_BY_DAY_URI.equals(localUri)) {
-            validColumnsSet = INSTANCES_TABLE_WHITELIST;
+            validColumnsSet = INSTANCES_TABLE_ALLOWED_LIST;
         } else {
             throw new IllegalArgumentException(String.format("Cross profile version of %d is not "
                     + "supported", localUri.toSafeString()));
diff --git a/tests/src/com/android/providers/calendar/CalendarSanityCheckerTest.java b/tests/src/com/android/providers/calendar/CalendarConfidenceCheckerTest.java
similarity index 68%
rename from tests/src/com/android/providers/calendar/CalendarSanityCheckerTest.java
rename to tests/src/com/android/providers/calendar/CalendarConfidenceCheckerTest.java
index 4cd00c8..cadaae0 100644
--- a/tests/src/com/android/providers/calendar/CalendarSanityCheckerTest.java
+++ b/tests/src/com/android/providers/calendar/CalendarConfidenceCheckerTest.java
@@ -31,9 +31,9 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class CalendarSanityCheckerTest {
-    private class CalendarSanityCheckerTestable extends CalendarSanityChecker {
-        protected CalendarSanityCheckerTestable(Context context) {
+public class CalendarConfidenceCheckerTest {
+    private class CalendarConfidenceCheckerTestable extends CalendarConfidenceChecker {
+        protected CalendarConfidenceCheckerTestable(Context context) {
             super(context);
         }
 
@@ -54,7 +54,7 @@
     }
 
     private Context mContext;
-    private CalendarSanityCheckerTestable mSanityChecker;
+    private CalendarConfidenceCheckerTestable mConfidenceChecker;
 
     private long mInjectedRealtimeMillis = 1000000L;
     private long mInjectedBootCount = 1000;
@@ -63,69 +63,69 @@
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getContext();
-        mSanityChecker = new CalendarSanityCheckerTestable(mContext);
-        mSanityChecker.mPrefs.edit().clear().commit();
+        mConfidenceChecker = new CalendarConfidenceCheckerTestable(mContext);
+        mConfidenceChecker.mPrefs.edit().clear().commit();
     }
 
     @Test
     public void testWithoutLastCheckTime() {
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         // Unlock.
         mInjectedUnlockTime = mInjectedRealtimeMillis;
 
         mInjectedRealtimeMillis += 15 * 60 * 1000;
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedRealtimeMillis += 1;
-        assertFalse(mSanityChecker.checkLastCheckTime());
+        assertFalse(mConfidenceChecker.checkLastCheckTime());
     }
 
     @Test
     public void testWithLastCheckTime() {
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedUnlockTime = mInjectedRealtimeMillis;
 
         // Update the last check time.
         mInjectedRealtimeMillis += 1 * 60 * 1000;
-        mSanityChecker.updateLastCheckTime();
+        mConfidenceChecker.updateLastCheckTime();
 
         // Right after, okay.
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         // Still okay.
         mInjectedRealtimeMillis += DateUtils.DAY_IN_MILLIS - (15 * DateUtils.MINUTE_IN_MILLIS);
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedRealtimeMillis += 1;
-        assertFalse(mSanityChecker.checkLastCheckTime());
+        assertFalse(mConfidenceChecker.checkLastCheckTime());
 
         // Repeat the same thing.
         mInjectedRealtimeMillis += 1 * 60 * 1000;
-        mSanityChecker.updateLastCheckTime();
+        mConfidenceChecker.updateLastCheckTime();
 
         // Right after, okay.
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         // Still okay.
         mInjectedRealtimeMillis += DateUtils.DAY_IN_MILLIS - (15 * DateUtils.MINUTE_IN_MILLIS);
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedRealtimeMillis += 1;
-        assertFalse(mSanityChecker.checkLastCheckTime());
+        assertFalse(mConfidenceChecker.checkLastCheckTime());
 
         // Check again right after. This should pass because of WTF_INTERVAL_MS.
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedRealtimeMillis += 60 * 60 * 1000;
 
         // Still okay.
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         // Now WTF again.
         mInjectedRealtimeMillis += 1;
-        assertFalse(mSanityChecker.checkLastCheckTime());
+        assertFalse(mConfidenceChecker.checkLastCheckTime());
 
         // Reboot.
         mInjectedRealtimeMillis = 1000000L;
@@ -135,12 +135,12 @@
         mInjectedUnlockTime = mInjectedRealtimeMillis;
 
         mInjectedRealtimeMillis += 15 * 60 * 1000;
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
 
         mInjectedRealtimeMillis += 1;
-        assertFalse(mSanityChecker.checkLastCheckTime());
+        assertFalse(mConfidenceChecker.checkLastCheckTime());
 
         // Check again right after. This should pass because of WTF_INTERVAL_MS.
-        assertTrue(mSanityChecker.checkLastCheckTime());
+        assertTrue(mConfidenceChecker.checkLastCheckTime());
     }
 }
diff --git a/tests/src/com/android/providers/calendar/CalendarDatabaseHelperTest.java b/tests/src/com/android/providers/calendar/CalendarDatabaseHelperTest.java
index a2925d4..873ec63 100644
--- a/tests/src/com/android/providers/calendar/CalendarDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/calendar/CalendarDatabaseHelperTest.java
@@ -427,7 +427,6 @@
     }
 
     @Test
-    @Ignore("b/140236227")
     public void testUpgradeToCurrentVersion() {
         // Create event tables
         bootstrapDbVersion50(mBadDb);
@@ -464,7 +463,6 @@
     private static final String[] PROJECTION = {"tbl_name", "sql"};
 
     @Test
-    @Ignore("b/140236227")
     public void testSchemasEqualForAllTables() {
 
         CalendarDatabaseHelper cDbHelper = new CalendarDatabaseHelper(new MockContext());
diff --git a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
index 466497c..11bccd4 100644
--- a/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
+++ b/tests/src/com/android/providers/calendar/CalendarProvider2Test.java
@@ -49,9 +49,9 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.Log;
 
+import com.android.calendarcommon2.Time;
 import com.android.providers.calendar.enterprise.CrossProfileCalendarHelper;
 
 import java.io.File;
@@ -132,7 +132,7 @@
     private static long parseTimeStringToMillis(String timeStr, String timeZone) {
         Time time = new Time(timeZone);
         time.parse3339(timeStr);
-        return time.toMillis(false /* use isDst */);
+        return time.toMillis();
     }
 
     private static String WORK_DEFAULT_TIMEZONE = TIME_ZONE_AMERICA_LOS_ANGELES;
@@ -343,9 +343,9 @@
         public DumpInstances(String startDate, String endDate) {
             Time time = new Time(DEFAULT_TIMEZONE);
             time.parse3339(startDate);
-            begin = time.toMillis(false /* use isDst */);
+            begin = time.toMillis();
             time.parse3339(endDate);
-            end = time.toMillis(false /* use isDst */);
+            end = time.toMillis();
         }
 
         public void execute() {
@@ -367,9 +367,9 @@
         public QueryNumInstances(String startDate, String endDate, int expected) {
             Time time = new Time(DEFAULT_TIMEZONE);
             time.parse3339(startDate);
-            begin = time.toMillis(false /* use isDst */);
+            begin = time.toMillis();
             time.parse3339(endDate);
-            end = time.toMillis(false /* use isDst */);
+            end = time.toMillis();
             this.expected = expected;
         }
 
@@ -395,9 +395,9 @@
         public VerifyAllInstances(String startDate, String endDate, String[] dates) {
             Time time = new Time(DEFAULT_TIMEZONE);
             time.parse3339(startDate);
-            begin = time.toMillis(false /* use isDst */);
+            begin = time.toMillis();
             time.parse3339(endDate);
-            end = time.toMillis(false /* use isDst */);
+            end = time.toMillis();
 
             if (dates == null) {
                 return;
@@ -409,7 +409,7 @@
             int index = 0;
             for (String instance : dates) {
                 time.parse3339(instance);
-                this.instances[index++] = time.toMillis(false /* use isDst */);
+                this.instances[index++] = time.toMillis();
             }
         }
 
@@ -490,14 +490,14 @@
         public VerifyInstance(String startDate, String endDate, String date) {
             Time time = new Time(DEFAULT_TIMEZONE);
             time.parse3339(startDate);
-            begin = time.toMillis(false /* use isDst */);
+            begin = time.toMillis();
             time.parse3339(endDate);
-            end = time.toMillis(false /* use isDst */);
+            end = time.toMillis();
 
             // Convert the instance date string to UTC milliseconds
             time.parse3339(date);
-            allDay = time.allDay;
-            instance = time.toMillis(false /* use isDst */);
+            allDay = time.isAllDay();
+            instance = time.toMillis();
         }
 
         public void execute() {
@@ -566,15 +566,15 @@
             mTitle = title;
             Time time = new Time();
             if (allDay) {
-                time.timezone = Time.TIMEZONE_UTC;
+                time.setTimezone(Time.TIMEZONE_UTC);
             } else if (timezone != null) {
-                time.timezone = timezone;
+                time.setTimezone(timezone);
             }
-            mTimezone = time.timezone;
+            mTimezone = time.getTimezone();
             time.parse3339(startDate);
-            mDtstart = time.toMillis(false /* use isDst */);
+            mDtstart = time.toMillis();
             time.parse3339(endDate);
-            mDtend = time.toMillis(false /* use isDst */);
+            mDtend = time.toMillis();
             mDuration = null;
             mRrule = null;
             mAllDay = allDay;
@@ -601,16 +601,16 @@
             mDescription = description;
             Time time = new Time();
             if (allDay) {
-                time.timezone = Time.TIMEZONE_UTC;
+                time.setTimezone(Time.TIMEZONE_UTC);
             } else if (timezone != null) {
-                time.timezone = timezone;
+                time.setTimezone(timezone);
             }
-            mTimezone = time.timezone;
+            mTimezone = time.getTimezone();
             time.parse3339(startDate);
-            mDtstart = time.toMillis(false /* use isDst */);
+            mDtstart = time.toMillis();
             if (endDate != null) {
                 time.parse3339(endDate);
-                mDtend = time.toMillis(false /* use isDst */);
+                mDtend = time.toMillis();
             }
             if (allDay) {
                 long days = 1;
@@ -642,7 +642,7 @@
             mOriginalTitle = originalTitle;
             Time time = new Time(timezone);
             time.parse3339(originalInstance);
-            mOriginalInstance = time.toMillis(false /* use isDst */);
+            mOriginalInstance = time.toMillis();
             mCustomAppPackage = customPackageName;
             mCustomAppUri = customPackageUri;
             mUid2445 = uid2445;
@@ -661,9 +661,9 @@
             mEvent = findEvent(eventName);
             Time time = new Time(mEvent.mTimezone);
             time.parse3339(startDate);
-            mBegin = time.toMillis(false /* use isDst */);
+            mBegin = time.toMillis();
             time.parse3339(endDate);
-            mEnd = time.toMillis(false /* use isDst */);
+            mEnd = time.toMillis();
             mExpectedOccurrences = expected;
         }
     }
@@ -1953,7 +1953,7 @@
 
         Time time = new Time(DEFAULT_TIMEZONE);
         time.parse3339(START);
-        long startMs = time.toMillis(true /* ignoreDst */);
+        long startMs = time.toMillis();
         // Query starting from way in the past to one hour into the event.
         // Query is more than 2 months so the range won't get extended by the provider.
         Cursor cursor = null;
@@ -2763,7 +2763,7 @@
 
         Time time = new Time(DEFAULT_TIMEZONE);
         time.parse3339(START);
-        long startMs = time.toMillis(true /* ignoreDst */);
+        long startMs = time.toMillis();
         // Query starting from way in the past to one hour into the event.
         // Query is more than 2 months so the range won't get extended by the provider.
         Cursor cursor = queryInstances(mResolver, PROJECTION,
@@ -3466,7 +3466,7 @@
         // Assume cross profile uri access is allowed by policy and settings.
         MockCrossProfileCalendarHelper.setPackageAllowedToAccessCalendar(true);
 
-        // Test all whitelisted columns are returned when projection is empty.
+        // Test all allowed list of columns are returned when projection is empty.
         String selection = "(" + Events.TITLE + " = ? )";
         String[] selectionArgs = new String[]{
                 WORK_EVENT_TITLE
@@ -3478,7 +3478,7 @@
         assertNotNull(cursor);
         assertEquals(1, cursor.getCount());
         cursor.moveToFirst();
-        for (String column : CrossProfileCalendarHelper.EVENTS_TABLE_WHITELIST) {
+        for (String column : CrossProfileCalendarHelper.EVENTS_TABLE_ALLOWED_LIST) {
             final int index = cursor.getColumnIndex(column);
             assertTrue(index != -1);
         }
@@ -3576,7 +3576,7 @@
         // Assume cross profile uri access is allowed by policy and settings.
         MockCrossProfileCalendarHelper.setPackageAllowedToAccessCalendar(true);
 
-        // Test all whitelisted columns are returned when projection is empty.
+        // Test all allowed list of columns are returned when projection is empty.
         final Cursor cursor = mResolver.query(
                 Calendars.ENTERPRISE_CONTENT_URI,
                 new String[] {}, null, null, null);
@@ -3584,7 +3584,7 @@
         assertNotNull(cursor);
         assertEquals(1, cursor.getCount());
         cursor.moveToFirst();
-        for (String column : CrossProfileCalendarHelper.CALENDARS_TABLE_WHITELIST) {
+        for (String column : CrossProfileCalendarHelper.CALENDARS_TABLE_ALLOWED_LIST) {
             final int index = cursor.getColumnIndex(column);
             assertTrue(index != -1);
         }
@@ -3597,8 +3597,8 @@
         cleanupEnterpriseTestForCalendars(1);
     }
 
-    public void testEnterpriseCalendarsNonWhitelistedProjection() {
-        // Test SecurityException is thrown there is non-whitelisted column in the projection.
+    public void testEnterpriseCalendarsNonAllowedListProjection() {
+        // Test SecurityException is thrown there is non-allowed list column in the projection.
         try {
             String[] projection = new String[] {
                     Calendars._ID,
@@ -3609,7 +3609,7 @@
             mResolver.query(
                     Calendars.ENTERPRISE_CONTENT_URI,
                     projection, null, null, null);
-            fail("IllegalArgumentException is not thrown when querying non-whitelisted columns");
+            fail("IllegalArgumentException is not thrown when querying non-allowed list of columns");
         } catch (IllegalArgumentException e) {
         }
     }
@@ -3651,4 +3651,3 @@
         return Long.parseLong(uri.getLastPathSegment());
     }
 }
-
diff --git a/tests/src/com/android/providers/calendar/ICalendarTest.java b/tests/src/com/android/providers/calendar/ICalendarTest.java
index 28bc73b..bbc4bb3 100644
--- a/tests/src/com/android/providers/calendar/ICalendarTest.java
+++ b/tests/src/com/android/providers/calendar/ICalendarTest.java
@@ -30,13 +30,13 @@
 
     @SmallTest
     public void testAddProperty() throws Exception {
-        String text = "BEGIN:DUMMY\n" +
+        String text = "BEGIN:STUB\n" +
                 "prop2:value3\n" +
                 "prop1:value1\n" +
                 "prop1:value2\n" +
-                "END:DUMMY\n";
+                "END:STUB\n";
 
-        ICalendar.Component component = new ICalendar.Component("DUMMY", null);
+        ICalendar.Component component = new ICalendar.Component("STUB", null);
         // properties should be listed in insertion order, by property name.
         component.addProperty(new ICalendar.Property("prop2", "value3"));
         component.addProperty(new ICalendar.Property("prop1", "value1"));
@@ -46,17 +46,17 @@
 
     @SmallTest
     public void testAddComponent() throws Exception {
-        String text = "BEGIN:DUMMY\n" +
+        String text = "BEGIN:STUB\n" +
                 "prop1:value1\n" +
                 "prop1:value12\n" +
-                "BEGIN:DUMMY2\n" +
+                "BEGIN:STUB2\n" +
                 "prop2:value2\n" +
-                "END:DUMMY2\n" +
-                "END:DUMMY\n";
+                "END:STUB2\n" +
+                "END:STUB\n";
 
-        ICalendar.Component parent = new ICalendar.Component("DUMMY", null);
+        ICalendar.Component parent = new ICalendar.Component("STUB", null);
         // properties should precede components
-        ICalendar.Component child = new ICalendar.Component("DUMMY2", parent);
+        ICalendar.Component child = new ICalendar.Component("STUB2", parent);
         child.addProperty(new ICalendar.Property("prop2", "value2"));
         parent.addChild(child);
         parent.addProperty(new ICalendar.Property("prop1", "value1"));
@@ -66,15 +66,15 @@
 
     @SmallTest
     public void testParseBasicComponent() throws Exception {
-        String text = "BEGIN:DUMMY\n" +
+        String text = "BEGIN:STUB\n" +
                 "PROP1;PARAM1=foo;PARAM2=bar:VALUE1\n" +
                 "PROP1;PARAM1=baaz;PARAM1=quux:VALUE2\n" +
                 "PROP2:VALUE3\n" +
-                "END:DUMMY\n";
+                "END:STUB\n";
 
         ICalendar.Component component = ICalendar.parseComponent(text);
-        
-        assertEquals("DUMMY", component.getName());
+
+        assertEquals("STUB", component.getName());
         assertNull(component.getComponents());
         assertEquals(2, component.getPropertyNames().size());
         ICalendar.Property prop1 = component.getFirstProperty("PROP1");
@@ -91,7 +91,7 @@
     @SmallTest
     public void testParseQuotedParam() throws Exception {
         ICalendar.Component component
-                = new ICalendar.Component("DUMMY", null /* parent */);
+                = new ICalendar.Component("STUB", null /* parent */);
         ICalendar.parseComponent(
                 component,
                 "DTSTART;TZID=\"GMT+03:00\";TEST=test1;TEST=\"test2\":20101221T090000");
@@ -108,7 +108,7 @@
     @SmallTest
     public void testParseBadQuotedParam() throws Exception {
         ICalendar.Component component
-                = new ICalendar.Component("DUMMY", null /* parent */);
+                = new ICalendar.Component("STUB", null /* parent */);
 
         ICalendar.parseComponent(
                 component,
@@ -139,13 +139,13 @@
                 "PROP2:VALUE3\n" +
                 "END:CHILD\n";
 
-        String completeText = "BEGIN:DUMMY\n" +
+        String completeText = "BEGIN:STUB\n" +
                 childText +
-                "END:DUMMY\n";
+                "END:STUB\n";
 
-        ICalendar.Component component = new ICalendar.Component("DUMMY", null);
+        ICalendar.Component component = new ICalendar.Component("STUB", null);
         component = ICalendar.parseComponent(component, childText);
-        assertEquals("DUMMY", component.getName());
+        assertEquals("STUB", component.getName());
         assertEquals(1, component.getComponents().size());
         assertEquals(completeText, component.toString());
     }
@@ -218,8 +218,8 @@
 
     @SmallTest
     public void testParseEventDoesNotStartWithBegin() throws Exception {
-        String text = "NOTBEGIN:DUMMY\n" +
-                "END:DUMMY\n";
+        String text = "NOTBEGIN:STUB\n" +
+                "END:STUB\n";
 
         try {
             ICalendar.parseEvent(text);
@@ -231,8 +231,8 @@
 
     @SmallTest
     public void testParseCalendarDoesNotStartWithBegin() throws Exception {
-        String text = "NOTBEGIN:DUMMY\n" +
-                "END:DUMMY\n";
+        String text = "NOTBEGIN:STUB\n" +
+                "END:STUB\n";
 
         try {
             ICalendar.parseCalendar(text);
@@ -244,13 +244,13 @@
 
     @SmallTest
     public void testParseComponentDoesNotStartWithBegin() throws Exception {
-        String text = "NOTBEGIN:DUMMY\n" +
-                "END:DUMMY\n";
+        String text = "NOTBEGIN:STUB\n" +
+                "END:STUB\n";
 
         ICalendar.Component component = ICalendar.parseComponent(text);
         assertNull(component);
     }
-    
+
     @SmallTest
     public void testParseUnexpectedEndComponent() throws Exception {
         String text = "BEGIN:PARENT\n" +
@@ -262,7 +262,7 @@
 
     @SmallTest
     public void testParseNoEndComponent() throws Exception {
-        String text = "BEGIN:DUMMY\n" +
+        String text = "BEGIN:STUB\n" +
                 "END:\n";
 
         ICalendar.Component component = ICalendar.parseComponent(text);
diff --git a/tests/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelperTest.java b/tests/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelperTest.java
index 4b28476..410c218 100644
--- a/tests/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelperTest.java
+++ b/tests/src/com/android/providers/calendar/enterprise/CrossProfileCalendarHelperTest.java
@@ -35,7 +35,7 @@
         mHelper = new CrossProfileCalendarHelper(mContext);
     }
 
-    public void testProjectionNotWhitelisted_throwErrorForCalendars() {
+    public void testProjectionNotInAllowedList_throwErrorForCalendars() {
         final String[] projection = new String[]{
                 Calendars._ID,
                 Calendars.OWNER_ACCOUNT
@@ -48,7 +48,7 @@
         }
     }
 
-    public void testProjectionNotWhitelisted_throwErrorForEvents() {
+    public void testProjectionNotInAllowedList_throwErrorForEvents() {
         final String[] projection = new String[] {
                 Events._ID,
                 Events.DESCRIPTION
@@ -61,7 +61,7 @@
         }
     }
 
-    public void testProjectionNotWhitelisted_throwErrorForInstances() {
+    public void testProjectionNotInAllowedList_throwErrorForInstances() {
         final String[] projection = new String[] {
                 Instances._ID,
                 Events.DESCRIPTION
@@ -74,22 +74,22 @@
         }
     }
 
-    public void testNoProjection_getFullWhitelistedProjectionForCalendars() {
+    public void testNoProjection_getFullAllowedListProjectionForCalendars() {
         final String[] projection = mHelper.getCalibratedProjection(null, Calendars.CONTENT_URI);
         final Set<String> projectionSet = new ArraySet<String>(Arrays.asList(projection));
-        assertTrue(Objects.deepEquals(CrossProfileCalendarHelper.CALENDARS_TABLE_WHITELIST,
+        assertTrue(Objects.deepEquals(CrossProfileCalendarHelper.CALENDARS_TABLE_ALLOWED_LIST,
                 projectionSet));
     }
 
-    public void testNoProjection_getFullWhitelistedProjectionForEvents() {
+    public void testNoProjection_getFullAllowedListProjectionForEvents() {
         final String[] projection = mHelper.getCalibratedProjection(null, Events.CONTENT_URI);
         final Set<String> projectionSet = new ArraySet<String>(Arrays.asList(projection));
-        assertTrue(CrossProfileCalendarHelper.EVENTS_TABLE_WHITELIST.equals(projectionSet));
+        assertTrue(CrossProfileCalendarHelper.EVENTS_TABLE_ALLOWED_LIST.equals(projectionSet));
     }
 
-    public void testNoProjection_getFullWhitelistedProjectionForInstances() {
+    public void testNoProjection_getFullAllowedListProjectionForInstances() {
         final String[] projection = mHelper.getCalibratedProjection(null, Instances.CONTENT_URI);
         final Set<String> projectionSet = new ArraySet<String>(Arrays.asList(projection));
-        assertTrue(CrossProfileCalendarHelper.INSTANCES_TABLE_WHITELIST.equals(projectionSet));
+        assertTrue(CrossProfileCalendarHelper.INSTANCES_TABLE_ALLOWED_LIST.equals(projectionSet));
     }
 }