diff options
17 files changed, 369 insertions, 270 deletions
@@ -35,6 +35,7 @@ license { android_app { name: "CalendarProvider", + defaults: ["platform_app_defaults"], static_libs: [ "guava", "android-common", @@ -44,6 +45,7 @@ android_app { "src/**/*.java", "src/com/android/providers/calendar/EventLogTags.logtags", ], + libs: ["app-compat-annotations"], platform_apis: true, privileged: true, @@ -56,3 +58,8 @@ android_app { 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> @@ -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.Events; 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 @@ public class CalendarAlarmManager { } 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 @@ public class CalendarAlarmManager { * @param cp2 TODO */ private void scheduleNextAlarmLocked(SQLiteDatabase db, CalendarProvider2 cp2) { - cp2.mSanityChecker.updateLastCheckTime(); + cp2.mConfidenceChecker.updateLastCheckTime(); Time time = new Time(); @@ -261,7 +261,7 @@ public class CalendarAlarmManager { 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 @@ public class CalendarAlarmManager { // 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 @@ public class CalendarAlarmManager { 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 @@ public class CalendarAlarmManager { 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 index ce7b62a..ae340b3 100644 --- a/src/com/android/providers/calendar/CalendarSanityChecker.java +++ b/src/com/android/providers/calendar/CalendarConfidenceChecker.java @@ -33,10 +33,10 @@ import com.android.internal.annotations.VisibleForTesting; * 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 @@ public class CalendarSanityChecker { @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.Events; 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 @@ import java.util.TimeZone; 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 @@ import java.util.TimeZone; 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 @@ import java.util.TimeZone; 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 @@ import java.util.TimeZone; 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.Duration; 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.Calendars; 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 @@ public class CalendarInstancesHelper { } // 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 @@ public class CalendarInstancesHelper { // 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 @@ public class CalendarInstancesHelper { 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 @@ public class CalendarInstancesHelper { // 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 @@ public class CalendarInstancesHelper { 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.accounts.OnAccountsUpdateListener; 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.SQLiteDatabase; 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.Reminders; 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.Duration; 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun */ MetaData mMetaData; CalendarCache mCalendarCache; - CalendarSanityChecker mSanityChecker; + CalendarConfidenceChecker mConfidenceChecker; private CalendarDatabaseHelper mDbHelper; private CalendarInstancesHelper mInstancesHelper; @@ -451,11 +454,19 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun /** 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun @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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun // 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } } 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 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun 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 @@ public class CalendarProviderBroadcastReceiver extends BroadcastReceiver { 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..908304d --- /dev/null +++ b/src/com/android/providers/calendar/CalendarProviderJobService.java @@ -0,0 +1,82 @@ +/* + * 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(); + + private volatile boolean canRun; + + @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; + } + + canRun = true; + 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."); + } + if (!canRun) { + break; + } + 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() + ")"); + canRun = false; + 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 @@ public class CalendarReceiver extends BroadcastReceiver { 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 @@ public class CrossProfileCalendarHelper { 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); - - 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); - - 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); + 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_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_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 @@ public class CrossProfileCalendarHelper { /** * 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 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 @@ import org.junit.runner.RunWith; @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 @@ public class CalendarSanityCheckerTest { } private Context mContext; - private CalendarSanityCheckerTestable mSanityChecker; + private CalendarConfidenceCheckerTestable mConfidenceChecker; private long mInjectedRealtimeMillis = 1000000L; private long mInjectedBootCount = 1000; @@ -63,69 +63,69 @@ public class CalendarSanityCheckerTest { @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 @@ public class CalendarSanityCheckerTest { 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 @@ public class CalendarDatabaseHelperTest { } @Test - @Ignore("b/140236227") public void testUpgradeToCurrentVersion() { // Create event tables bootstrapDbVersion50(mBadDb); @@ -464,7 +463,6 @@ public class CalendarDatabaseHelperTest { 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.Smoke; 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 class CalendarProvider2Test extends AndroidTestCase { 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 class CalendarProvider2Test extends AndroidTestCase { 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 class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { // 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { // 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class CalendarProvider2Test extends AndroidTestCase { 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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { "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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class ICalendarTest extends TestCase { @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 @@ public class CrossProfileCalendarHelperTest extends AndroidTestCase { 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 class CrossProfileCalendarHelperTest extends AndroidTestCase { } } - public void testProjectionNotWhitelisted_throwErrorForEvents() { + public void testProjectionNotInAllowedList_throwErrorForEvents() { final String[] projection = new String[] { Events._ID, Events.DESCRIPTION @@ -61,7 +61,7 @@ public class CrossProfileCalendarHelperTest extends AndroidTestCase { } } - public void testProjectionNotWhitelisted_throwErrorForInstances() { + public void testProjectionNotInAllowedList_throwErrorForInstances() { final String[] projection = new String[] { Instances._ID, Events.DESCRIPTION @@ -74,22 +74,22 @@ public class CrossProfileCalendarHelperTest extends AndroidTestCase { } } - 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)); } } |
