Loading core/java/android/service/notification/ZenModeConfig.java +24 −9 Original line number Diff line number Diff line Loading @@ -473,6 +473,15 @@ public class ZenModeConfig implements Parcelable { } } private static Long tryParseLong(String value, Long defValue) { if (TextUtils.isEmpty(value)) return defValue; try { return Long.parseLong(value); } catch (NumberFormatException e) { return defValue; } } public static ZenModeConfig readXml(XmlPullParser parser) throws XmlPullParserException, IOException { int type = parser.getEventType(); Loading Loading @@ -1288,7 +1297,9 @@ public class ZenModeConfig implements Parcelable { .authority(SYSTEM_AUTHORITY) .appendPath(EVENT_PATH) .appendQueryParameter("userId", Long.toString(event.userId)) .appendQueryParameter("calendar", event.calendar != null ? event.calendar : "") .appendQueryParameter("calendar", event.calName != null ? event.calName : "") .appendQueryParameter("calendarId", event.calendarId != null ? event.calendarId.toString() : "") .appendQueryParameter("reply", Integer.toString(event.reply)) .build(); } Loading @@ -1306,10 +1317,11 @@ public class ZenModeConfig implements Parcelable { if (!isEvent) return null; final EventInfo rt = new EventInfo(); rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL); rt.calendar = conditionId.getQueryParameter("calendar"); if (TextUtils.isEmpty(rt.calendar) || tryParseLong(rt.calendar, -1L) != -1L) { rt.calendar = null; rt.calName = conditionId.getQueryParameter("calendar"); if (TextUtils.isEmpty(rt.calName)) { rt.calName = null; } rt.calendarId = tryParseLong(conditionId.getQueryParameter("calendarId"), null); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); return rt; } Loading @@ -1324,12 +1336,13 @@ public class ZenModeConfig implements Parcelable { public static final int REPLY_YES = 2; public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user public String calendar; // CalendarContract.Calendars.OWNER_ACCOUNT, or null for any public String calName; // CalendarContract.Calendars.DISPLAY_NAME, or null for any public Long calendarId; // Calendars._ID, or null if restored from < Q calendar public int reply; @Override public int hashCode() { return 0; return Objects.hash(userId, calName, calendarId, reply); } @Override Loading @@ -1337,15 +1350,17 @@ public class ZenModeConfig implements Parcelable { if (!(o instanceof EventInfo)) return false; final EventInfo other = (EventInfo) o; return userId == other.userId && Objects.equals(calendar, other.calendar) && reply == other.reply; && Objects.equals(calName, other.calName) && reply == other.reply && Objects.equals(calendarId, other.calendarId); } public EventInfo copy() { final EventInfo rt = new EventInfo(); rt.userId = userId; rt.calendar = calendar; rt.calName = calName; rt.reply = reply; rt.calendarId = calendarId; return rt; } Loading services/core/java/com/android/server/notification/CalendarTracker.java +21 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.provider.BaseColumns; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Calendars; import android.provider.CalendarContract.Events; Loading Loading @@ -89,13 +88,13 @@ public class CalendarTracker { pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId()); } private ArraySet<Long> getPrimaryCalendars() { private ArraySet<Long> getCalendarsWithAccess() { final long start = System.currentTimeMillis(); final ArraySet<Long> rt = new ArraySet<>(); final String primary = "\"primary\""; final String[] projection = { Calendars._ID, "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary }; final String selection = primary + " = 1"; final String[] projection = { Calendars._ID }; final String selection = Calendars.CALENDAR_ACCESS_LEVEL + " >= " + Calendars.CAL_ACCESS_CONTRIBUTOR + " AND " + Calendars.SYNC_EVENTS + " = 1"; Cursor cursor = null; try { cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection, Loading @@ -108,7 +107,9 @@ public class CalendarTracker { cursor.close(); } } if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start)); if (DEBUG) { Log.d(TAG, "getCalendarsWithAccess took " + (System.currentTimeMillis() - start)); } return rt; } Loading @@ -122,7 +123,7 @@ public class CalendarTracker { final CheckEventResult result = new CheckEventResult(); result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; try { final ArraySet<Long> primaryCalendars = getPrimaryCalendars(); final ArraySet<Long> calendars = getCalendarsWithAccess(); while (cursor != null && cursor.moveToNext()) { final long begin = cursor.getLong(0); final long end = cursor.getLong(1); Loading @@ -133,17 +134,19 @@ public class CalendarTracker { final String owner = cursor.getString(6); final long calendarId = cursor.getLong(7); final int availability = cursor.getInt(8); final boolean calendarPrimary = primaryCalendars.contains(calendarId); if (DEBUG) Log.d(TAG, String.format( "%s %s-%s v=%s a=%s eid=%s n=%s o=%s cid=%s p=%s", title, new Date(begin), new Date(end), calendarVisible, final boolean canAccessCal = calendars.contains(calendarId); if (DEBUG) { Log.d(TAG, String.format("title=%s time=%s-%s vis=%s availability=%s " + "eventId=%s name=%s owner=%s calId=%s canAccessCal=%s", title, new Date(begin), new Date(end), calendarVisible, availabilityToString(availability), eventId, name, owner, calendarId, calendarPrimary)); canAccessCal)); } final boolean meetsTime = time >= begin && time < end; final boolean meetsCalendar = calendarVisible && calendarPrimary && (filter.calendar == null || Objects.equals(filter.calendar, owner) || Objects.equals(filter.calendar, name)); final boolean meetsCalendar = calendarVisible && canAccessCal && ((filter.calName == null && filter.calendarId == null) || (Objects.equals(filter.calendarId, calendarId)) || Objects.equals(filter.calName, name)); final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE; if (meetsCalendar && meetsAvailability) { if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY"); Loading services/core/java/com/android/server/notification/EventConditionProvider.java +1 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -221,7 +220,7 @@ public class EventConditionProvider extends SystemConditionProviderService { continue; } CheckEventResult result = null; if (event.calendar == null) { // any calendar if (event.calName == null) { // any calendar // event could exist on any tracker for (int i = 0; i < mTrackers.size(); i++) { final CalendarTracker tracker = mTrackers.valueAt(i); Loading services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.notification; import static junit.framework.Assert.assertEquals; import android.app.NotificationManager.Policy; import android.net.Uri; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenPolicy; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; Loading Loading @@ -112,6 +114,30 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); } @Test public void testParseOldEvent() { EventInfo oldEvent = new EventInfo(); oldEvent.userId = 1; oldEvent.calName = "calName"; oldEvent.calendarId = null; // old events will have null ids Uri conditionId = ZenModeConfig.toEventConditionId(oldEvent); EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId); assertEquals(oldEvent, eventParsed); } @Test public void testParseNewEvent() { EventInfo event = new EventInfo(); event.userId = 1; event.calName = "calName"; event.calendarId = 12345L; Uri conditionId = ZenModeConfig.toEventConditionId(event); EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId); assertEquals(event, eventParsed); } private ZenModeConfig getMutedNotificationsConfig() { ZenModeConfig config = new ZenModeConfig(); // Allow alarms, media, and system Loading Loading
core/java/android/service/notification/ZenModeConfig.java +24 −9 Original line number Diff line number Diff line Loading @@ -473,6 +473,15 @@ public class ZenModeConfig implements Parcelable { } } private static Long tryParseLong(String value, Long defValue) { if (TextUtils.isEmpty(value)) return defValue; try { return Long.parseLong(value); } catch (NumberFormatException e) { return defValue; } } public static ZenModeConfig readXml(XmlPullParser parser) throws XmlPullParserException, IOException { int type = parser.getEventType(); Loading Loading @@ -1288,7 +1297,9 @@ public class ZenModeConfig implements Parcelable { .authority(SYSTEM_AUTHORITY) .appendPath(EVENT_PATH) .appendQueryParameter("userId", Long.toString(event.userId)) .appendQueryParameter("calendar", event.calendar != null ? event.calendar : "") .appendQueryParameter("calendar", event.calName != null ? event.calName : "") .appendQueryParameter("calendarId", event.calendarId != null ? event.calendarId.toString() : "") .appendQueryParameter("reply", Integer.toString(event.reply)) .build(); } Loading @@ -1306,10 +1317,11 @@ public class ZenModeConfig implements Parcelable { if (!isEvent) return null; final EventInfo rt = new EventInfo(); rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL); rt.calendar = conditionId.getQueryParameter("calendar"); if (TextUtils.isEmpty(rt.calendar) || tryParseLong(rt.calendar, -1L) != -1L) { rt.calendar = null; rt.calName = conditionId.getQueryParameter("calendar"); if (TextUtils.isEmpty(rt.calName)) { rt.calName = null; } rt.calendarId = tryParseLong(conditionId.getQueryParameter("calendarId"), null); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); return rt; } Loading @@ -1324,12 +1336,13 @@ public class ZenModeConfig implements Parcelable { public static final int REPLY_YES = 2; public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user public String calendar; // CalendarContract.Calendars.OWNER_ACCOUNT, or null for any public String calName; // CalendarContract.Calendars.DISPLAY_NAME, or null for any public Long calendarId; // Calendars._ID, or null if restored from < Q calendar public int reply; @Override public int hashCode() { return 0; return Objects.hash(userId, calName, calendarId, reply); } @Override Loading @@ -1337,15 +1350,17 @@ public class ZenModeConfig implements Parcelable { if (!(o instanceof EventInfo)) return false; final EventInfo other = (EventInfo) o; return userId == other.userId && Objects.equals(calendar, other.calendar) && reply == other.reply; && Objects.equals(calName, other.calName) && reply == other.reply && Objects.equals(calendarId, other.calendarId); } public EventInfo copy() { final EventInfo rt = new EventInfo(); rt.userId = userId; rt.calendar = calendar; rt.calName = calName; rt.reply = reply; rt.calendarId = calendarId; return rt; } Loading
services/core/java/com/android/server/notification/CalendarTracker.java +21 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.provider.BaseColumns; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Calendars; import android.provider.CalendarContract.Events; Loading Loading @@ -89,13 +88,13 @@ public class CalendarTracker { pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId()); } private ArraySet<Long> getPrimaryCalendars() { private ArraySet<Long> getCalendarsWithAccess() { final long start = System.currentTimeMillis(); final ArraySet<Long> rt = new ArraySet<>(); final String primary = "\"primary\""; final String[] projection = { Calendars._ID, "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary }; final String selection = primary + " = 1"; final String[] projection = { Calendars._ID }; final String selection = Calendars.CALENDAR_ACCESS_LEVEL + " >= " + Calendars.CAL_ACCESS_CONTRIBUTOR + " AND " + Calendars.SYNC_EVENTS + " = 1"; Cursor cursor = null; try { cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection, Loading @@ -108,7 +107,9 @@ public class CalendarTracker { cursor.close(); } } if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start)); if (DEBUG) { Log.d(TAG, "getCalendarsWithAccess took " + (System.currentTimeMillis() - start)); } return rt; } Loading @@ -122,7 +123,7 @@ public class CalendarTracker { final CheckEventResult result = new CheckEventResult(); result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; try { final ArraySet<Long> primaryCalendars = getPrimaryCalendars(); final ArraySet<Long> calendars = getCalendarsWithAccess(); while (cursor != null && cursor.moveToNext()) { final long begin = cursor.getLong(0); final long end = cursor.getLong(1); Loading @@ -133,17 +134,19 @@ public class CalendarTracker { final String owner = cursor.getString(6); final long calendarId = cursor.getLong(7); final int availability = cursor.getInt(8); final boolean calendarPrimary = primaryCalendars.contains(calendarId); if (DEBUG) Log.d(TAG, String.format( "%s %s-%s v=%s a=%s eid=%s n=%s o=%s cid=%s p=%s", title, new Date(begin), new Date(end), calendarVisible, final boolean canAccessCal = calendars.contains(calendarId); if (DEBUG) { Log.d(TAG, String.format("title=%s time=%s-%s vis=%s availability=%s " + "eventId=%s name=%s owner=%s calId=%s canAccessCal=%s", title, new Date(begin), new Date(end), calendarVisible, availabilityToString(availability), eventId, name, owner, calendarId, calendarPrimary)); canAccessCal)); } final boolean meetsTime = time >= begin && time < end; final boolean meetsCalendar = calendarVisible && calendarPrimary && (filter.calendar == null || Objects.equals(filter.calendar, owner) || Objects.equals(filter.calendar, name)); final boolean meetsCalendar = calendarVisible && canAccessCal && ((filter.calName == null && filter.calendarId == null) || (Objects.equals(filter.calendarId, calendarId)) || Objects.equals(filter.calName, name)); final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE; if (meetsCalendar && meetsAvailability) { if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY"); Loading
services/core/java/com/android/server/notification/EventConditionProvider.java +1 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -221,7 +220,7 @@ public class EventConditionProvider extends SystemConditionProviderService { continue; } CheckEventResult result = null; if (event.calendar == null) { // any calendar if (event.calName == null) { // any calendar // event could exist on any tracker for (int i = 0; i < mTrackers.size(); i++) { final CalendarTracker tracker = mTrackers.valueAt(i); Loading
services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package com.android.server.notification; import static junit.framework.Assert.assertEquals; import android.app.NotificationManager.Policy; import android.net.Uri; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenPolicy; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; Loading Loading @@ -112,6 +114,30 @@ public class ZenModeConfigTest extends UiServiceTestCase { assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config)); } @Test public void testParseOldEvent() { EventInfo oldEvent = new EventInfo(); oldEvent.userId = 1; oldEvent.calName = "calName"; oldEvent.calendarId = null; // old events will have null ids Uri conditionId = ZenModeConfig.toEventConditionId(oldEvent); EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId); assertEquals(oldEvent, eventParsed); } @Test public void testParseNewEvent() { EventInfo event = new EventInfo(); event.userId = 1; event.calName = "calName"; event.calendarId = 12345L; Uri conditionId = ZenModeConfig.toEventConditionId(event); EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId); assertEquals(event, eventParsed); } private ZenModeConfig getMutedNotificationsConfig() { ZenModeConfig config = new ZenModeConfig(); // Allow alarms, media, and system Loading