Loading core/java/android/service/notification/ZenModeConfig.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.service.notification; package android.service.notification; import android.app.ActivityManager; import android.app.NotificationManager.Policy; import android.app.NotificationManager.Policy; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; Loading @@ -23,6 +24,7 @@ import android.content.res.Resources; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.provider.Settings.Global; import android.provider.Settings.Global; import android.text.TextUtils; import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateFormat; Loading Loading @@ -728,6 +730,7 @@ public class ZenModeConfig implements Parcelable { return new Uri.Builder().scheme(Condition.SCHEME) return new Uri.Builder().scheme(Condition.SCHEME) .authority(SYSTEM_AUTHORITY) .authority(SYSTEM_AUTHORITY) .appendPath(EVENT_PATH) .appendPath(EVENT_PATH) .appendQueryParameter("userId", Long.toString(event.userId)) .appendQueryParameter("calendar", Long.toString(event.calendar)) .appendQueryParameter("calendar", Long.toString(event.calendar)) .appendQueryParameter("reply", Integer.toString(event.reply)) .appendQueryParameter("reply", Integer.toString(event.reply)) .build(); .build(); Loading @@ -745,6 +748,7 @@ public class ZenModeConfig implements Parcelable { && conditionId.getPathSegments().get(0).equals(EVENT_PATH); && conditionId.getPathSegments().get(0).equals(EVENT_PATH); if (!isEvent) return null; if (!isEvent) return null; final EventInfo rt = new EventInfo(); final EventInfo rt = new EventInfo(); rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL); rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), EventInfo.ANY_CALENDAR); EventInfo.ANY_CALENDAR); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); Loading @@ -758,6 +762,7 @@ public class ZenModeConfig implements Parcelable { public static final int REPLY_YES_OR_MAYBE = 1; public static final int REPLY_YES_OR_MAYBE = 1; public static final int REPLY_YES = 2; public static final int REPLY_YES = 2; public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR public int reply; public int reply; Loading @@ -770,16 +775,23 @@ public class ZenModeConfig implements Parcelable { public boolean equals(Object o) { public boolean equals(Object o) { if (!(o instanceof EventInfo)) return false; if (!(o instanceof EventInfo)) return false; final EventInfo other = (EventInfo) o; final EventInfo other = (EventInfo) o; return calendar == other.calendar return userId == other.userId && calendar == other.calendar && reply == other.reply; && reply == other.reply; } } public EventInfo copy() { public EventInfo copy() { final EventInfo rt = new EventInfo(); final EventInfo rt = new EventInfo(); rt.userId = userId; rt.calendar = calendar; rt.calendar = calendar; rt.reply = reply; rt.reply = reply; return rt; return rt; } } public static int resolveUserId(int userId) { return userId == UserHandle.USER_NULL ? ActivityManager.getCurrentUser() : userId; } } } // ==== End built-in system conditions ==== // ==== End built-in system conditions ==== Loading services/core/java/com/android/server/notification/CalendarTracker.java +64 −22 Original line number Original line Diff line number Diff line Loading @@ -26,8 +26,11 @@ import android.database.Cursor; import android.net.Uri; import android.net.Uri; import android.provider.BaseColumns; import android.provider.BaseColumns; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Calendars; import android.provider.CalendarContract.Events; import android.provider.CalendarContract.Instances; import android.provider.CalendarContract.Instances; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenModeConfig.EventInfo; import android.util.ArraySet; import android.util.Log; import android.util.Log; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -63,13 +66,15 @@ public class CalendarTracker { private static final String ATTENDEE_SELECTION = Attendees.EVENT_ID + " = ? AND " private static final String ATTENDEE_SELECTION = Attendees.EVENT_ID + " = ? AND " + Attendees.ATTENDEE_EMAIL + " = ?"; + Attendees.ATTENDEE_EMAIL + " = ?"; private final Context mContext; private final Context mSystemContext; private final Context mUserContext; private Callback mCallback; private Callback mCallback; private boolean mRegistered; private boolean mRegistered; public CalendarTracker(Context context) { public CalendarTracker(Context systemContext, Context userContext) { mContext = context; mSystemContext = systemContext; mUserContext = userContext; } } public void setCallback(Callback callback) { public void setCallback(Callback callback) { Loading @@ -81,11 +86,12 @@ public class CalendarTracker { public void dump(String prefix, PrintWriter pw) { public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("mCallback="); pw.println(mCallback); pw.print(prefix); pw.print("mCallback="); pw.println(mCallback); pw.print(prefix); pw.print("mRegistered="); pw.println(mRegistered); pw.print(prefix); pw.print("mRegistered="); pw.println(mRegistered); pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId()); } } public void dumpContent(Uri uri) { public void dumpContent(Uri uri) { Log.d(TAG, "dumpContent: " + uri); Log.d(TAG, "dumpContent: " + uri); final Cursor cursor = mContext.getContentResolver().query(uri, null, null, null, null); final Cursor cursor = mUserContext.getContentResolver().query(uri, null, null, null, null); try { try { int r = 0; int r = 0; while (cursor.moveToNext()) { while (cursor.moveToNext()) { Loading Loading @@ -126,36 +132,61 @@ public class CalendarTracker { } } } } private ArraySet<Long> getPrimaryCalendars() { 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"; Cursor cursor = null; try { cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection, selection, null, null); while (cursor != null && cursor.moveToNext()) { rt.add(cursor.getLong(0)); } } finally { if (cursor != null) { cursor.close(); } } if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start)); return rt; } public CheckEventResult checkEvent(EventInfo filter, long time) { public CheckEventResult checkEvent(EventInfo filter, long time) { final Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon(); final Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon(); ContentUris.appendId(uriBuilder, time); ContentUris.appendId(uriBuilder, time); ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD); ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD); final Uri uri = uriBuilder.build(); final Uri uri = uriBuilder.build(); final Cursor cursor = mContext.getContentResolver().query(uri, INSTANCE_PROJECTION, null, final Cursor cursor = mUserContext.getContentResolver().query(uri, INSTANCE_PROJECTION, null, INSTANCE_ORDER_BY); null, null, INSTANCE_ORDER_BY); final CheckEventResult result = new CheckEventResult(); final CheckEventResult result = new CheckEventResult(); result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; try { try { while (cursor.moveToNext()) { final ArraySet<Long> primaryCalendars = getPrimaryCalendars(); while (cursor != null && cursor.moveToNext()) { final long begin = cursor.getLong(0); final long begin = cursor.getLong(0); final long end = cursor.getLong(1); final long end = cursor.getLong(1); final String title = cursor.getString(2); final String title = cursor.getString(2); final boolean visible = cursor.getInt(3) == 1; final boolean calendarVisible = cursor.getInt(3) == 1; final int eventId = cursor.getInt(4); final int eventId = cursor.getInt(4); final String owner = cursor.getString(5); final String owner = cursor.getString(5); final long calendarId = cursor.getLong(6); final long calendarId = cursor.getLong(6); final int availability = cursor.getInt(7); final int availability = cursor.getInt(7); if (DEBUG) Log.d(TAG, String.format("%s %s-%s v=%s a=%s eid=%s o=%s cid=%s", title, final boolean calendarPrimary = primaryCalendars.contains(calendarId); new Date(begin), new Date(end), visible, availabilityToString(availability), if (DEBUG) Log.d(TAG, String.format("%s %s-%s v=%s a=%s eid=%s o=%s cid=%s p=%s", eventId, owner, calendarId)); title, new Date(begin), new Date(end), calendarVisible, availabilityToString(availability), eventId, owner, calendarId, calendarPrimary)); final boolean meetsTime = time >= begin && time < end; final boolean meetsTime = time >= begin && time < end; final boolean meetsCalendar = visible final boolean meetsCalendar = calendarVisible && calendarPrimary && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId) && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId); && availability != Instances.AVAILABILITY_FREE; final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE; if (meetsCalendar) { if (meetsCalendar && meetsAvailability) { if (DEBUG) Log.d(TAG, " MEETS CALENDAR"); if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY"); final boolean meetsAttendee = meetsAttendee(filter, eventId, owner); final boolean meetsAttendee = meetsAttendee(filter, eventId, owner); if (meetsAttendee) { if (meetsAttendee) { if (DEBUG) Log.d(TAG, " MEETS ATTENDEE"); if (DEBUG) Log.d(TAG, " MEETS ATTENDEE"); Loading @@ -172,19 +203,22 @@ public class CalendarTracker { } } } } } finally { } finally { if (cursor != null) { cursor.close(); cursor.close(); } } } return result; return result; } } private boolean meetsAttendee(EventInfo filter, int eventId, String email) { private boolean meetsAttendee(EventInfo filter, int eventId, String email) { final long start = System.currentTimeMillis(); String selection = ATTENDEE_SELECTION; String selection = ATTENDEE_SELECTION; String[] selectionArgs = { Integer.toString(eventId), email }; String[] selectionArgs = { Integer.toString(eventId), email }; if (DEBUG_ATTENDEES) { if (DEBUG_ATTENDEES) { selection = null; selection = null; selectionArgs = null; selectionArgs = null; } } final Cursor cursor = mContext.getContentResolver().query(Attendees.CONTENT_URI, final Cursor cursor = mUserContext.getContentResolver().query(Attendees.CONTENT_URI, ATTENDEE_PROJECTION, selection, selectionArgs, null); ATTENDEE_PROJECTION, selection, selectionArgs, null); try { try { if (cursor.getCount() == 0) { if (cursor.getCount() == 0) { Loading @@ -208,18 +242,25 @@ public class CalendarTracker { return rt; return rt; } finally { } finally { cursor.close(); cursor.close(); if (DEBUG) Log.d(TAG, "meetsAttendee took " + (System.currentTimeMillis() - start)); } } } } private void setRegistered(boolean registered) { private void setRegistered(boolean registered) { if (mRegistered == registered) return; if (mRegistered == registered) return; final ContentResolver cr = mContext.getContentResolver(); final ContentResolver cr = mSystemContext.getContentResolver(); final int userId = mUserContext.getUserId(); if (mRegistered) { if (mRegistered) { if (DEBUG) Log.d(TAG, "unregister content observer u=" + userId); cr.unregisterContentObserver(mObserver); cr.unregisterContentObserver(mObserver); } } mRegistered = registered; mRegistered = registered; if (DEBUG) Log.d(TAG, "mRegistered = " + registered + " u=" + userId); if (mRegistered) { if (mRegistered) { cr.registerContentObserver(Instances.CONTENT_URI, false, mObserver); if (DEBUG) Log.d(TAG, "register content observer u=" + userId); cr.registerContentObserver(Instances.CONTENT_URI, true, mObserver, userId); cr.registerContentObserver(Events.CONTENT_URI, true, mObserver, userId); cr.registerContentObserver(Calendars.CONTENT_URI, true, mObserver, userId); } } } } Loading Loading @@ -260,7 +301,8 @@ public class CalendarTracker { private final ContentObserver mObserver = new ContentObserver(null) { private final ContentObserver mObserver = new ContentObserver(null) { @Override @Override public void onChange(boolean selfChange, Uri u) { public void onChange(boolean selfChange, Uri u) { if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange + " uri=" + u); if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange + " uri=" + u + " u=" + mUserContext.getUserId()); mCallback.onChanged(); mCallback.onChanged(); } } Loading services/core/java/com/android/server/notification/ConditionProviders.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -130,8 +130,8 @@ public class ConditionProviders extends ManagedServices { } } @Override @Override public void onUserSwitched() { public void onUserSwitched(int user) { super.onUserSwitched(); super.onUserSwitched(user); if (mCallback != null) { if (mCallback != null) { mCallback.onUserSwitched(); mCallback.onUserSwitched(); } } Loading services/core/java/com/android/server/notification/EventConditionProvider.java +105 −17 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,12 @@ import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.Condition; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig; Loading @@ -31,6 +36,7 @@ import android.service.notification.ZenModeConfig.EventInfo; import android.util.ArraySet; import android.util.ArraySet; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import com.android.server.notification.CalendarTracker.CheckEventResult; import com.android.server.notification.CalendarTracker.CheckEventResult; import com.android.server.notification.NotificationManagerService.DumpFilter; import com.android.server.notification.NotificationManagerService.DumpFilter; Loading @@ -51,17 +57,21 @@ public class EventConditionProvider extends SystemConditionProviderService { private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final int REQUEST_CODE_EVALUATE = 1; private static final int REQUEST_CODE_EVALUATE = 1; private static final String EXTRA_TIME = "time"; private static final String EXTRA_TIME = "time"; private static final long CHANGE_DELAY = 2 * 1000; // coalesce chatty calendar changes private final Context mContext = this; private final Context mContext = this; private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>(); private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>(); private final CalendarTracker mTracker = new CalendarTracker(mContext); private final SparseArray<CalendarTracker> mTrackers = new SparseArray<>(); private final Handler mWorker; private boolean mConnected; private boolean mConnected; private boolean mRegistered; private boolean mRegistered; private boolean mBootComplete; // don't hammer the calendar provider until boot completes. private boolean mBootComplete; // don't hammer the calendar provider until boot completes. private long mNextAlarmTime; public EventConditionProvider() { public EventConditionProvider(Looper worker) { if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()"); if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()"); mWorker = new Handler(worker); } } @Override @Override Loading @@ -80,13 +90,17 @@ public class EventConditionProvider extends SystemConditionProviderService { pw.print(" mConnected="); pw.println(mConnected); pw.print(" mConnected="); pw.println(mConnected); pw.print(" mRegistered="); pw.println(mRegistered); pw.print(" mRegistered="); pw.println(mRegistered); pw.print(" mBootComplete="); pw.println(mBootComplete); pw.print(" mBootComplete="); pw.println(mBootComplete); dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, System.currentTimeMillis()); pw.println(" mSubscriptions="); pw.println(" mSubscriptions="); for (Uri conditionId : mSubscriptions) { for (Uri conditionId : mSubscriptions) { pw.print(" "); pw.print(" "); pw.println(conditionId); pw.println(conditionId); } } pw.println(" mTracker="); pw.println(" mTrackers="); mTracker.dump(" ", pw); for (int i = 0; i < mTrackers.size(); i++) { pw.print(" user="); pw.println(mTrackers.keyAt(i)); mTrackers.valueAt(i).dump(" ", pw); } } } @Override @Override Loading @@ -94,7 +108,16 @@ public class EventConditionProvider extends SystemConditionProviderService { if (DEBUG) Slog.d(TAG, "onBootComplete"); if (DEBUG) Slog.d(TAG, "onBootComplete"); if (mBootComplete) return; if (mBootComplete) return; mBootComplete = true; mBootComplete = true; evaluateSubscriptions(); final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { reloadTrackers(); } }, filter); reloadTrackers(); } } @Override @Override Loading Loading @@ -146,14 +169,39 @@ public class EventConditionProvider extends SystemConditionProviderService { return (IConditionProvider) onBind(null); return (IConditionProvider) onBind(null); } } private void reloadTrackers() { if (DEBUG) Slog.d(TAG, "reloadTrackers"); for (int i = 0; i < mTrackers.size(); i++) { mTrackers.valueAt(i).setCallback(null); } mTrackers.clear(); for (UserHandle user : UserManager.get(mContext).getUserProfiles()) { final Context context = user.isOwner() ? mContext : getContextForUser(mContext, user); if (context == null) { Slog.w(TAG, "Unable to create context for user " + user.getIdentifier()); continue; } mTrackers.put(user.getIdentifier(), new CalendarTracker(mContext, context)); } evaluateSubscriptions(); } private void evaluateSubscriptions() { private void evaluateSubscriptions() { if (DEBUG) Log.d(TAG, "evaluateSubscriptions"); if (!mWorker.hasCallbacks(mEvaluateSubscriptionsW)) { mWorker.post(mEvaluateSubscriptionsW); } } private void evaluateSubscriptionsW() { if (DEBUG) Slog.d(TAG, "evaluateSubscriptions"); if (!mBootComplete) { if (!mBootComplete) { if (DEBUG) Log.d(TAG, "Skipping evaluate before boot complete"); if (DEBUG) Slog.d(TAG, "Skipping evaluate before boot complete"); return; return; } } final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); mTracker.setCallback(mSubscriptions.isEmpty() ? null : mTrackerCallback); for (int i = 0; i < mTrackers.size(); i++) { mTrackers.valueAt(i).setCallback(mSubscriptions.isEmpty() ? null : mTrackerCallback); } setRegistered(!mSubscriptions.isEmpty()); setRegistered(!mSubscriptions.isEmpty()); long reevaluateAt = 0; long reevaluateAt = 0; for (Uri conditionId : mSubscriptions) { for (Uri conditionId : mSubscriptions) { Loading @@ -162,7 +210,30 @@ public class EventConditionProvider extends SystemConditionProviderService { notifyCondition(conditionId, Condition.STATE_FALSE, "badConditionId"); notifyCondition(conditionId, Condition.STATE_FALSE, "badConditionId"); continue; continue; } } final CheckEventResult result = mTracker.checkEvent(event, now); CheckEventResult result = null; if (event.calendar == EventInfo.ANY_CALENDAR) { // event could exist on any tracker for (int i = 0; i < mTrackers.size(); i++) { final CalendarTracker tracker = mTrackers.valueAt(i); final CheckEventResult r = tracker.checkEvent(event, now); if (result == null) { result = r; } else { result.inEvent |= r.inEvent; result.recheckAt = Math.min(result.recheckAt, r.recheckAt); } } } else { // event should exist on one tracker final int userId = EventInfo.resolveUserId(event.userId); final CalendarTracker tracker = mTrackers.get(userId); if (tracker == null) { Slog.w(TAG, "No calendar tracker found for user " + userId); notifyCondition(conditionId, Condition.STATE_FALSE, "badUserId"); continue; } result = tracker.checkEvent(event, now); } if (result.recheckAt != 0 && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) { if (result.recheckAt != 0 && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) { reevaluateAt = result.recheckAt; reevaluateAt = result.recheckAt; } } Loading @@ -172,11 +243,12 @@ public class EventConditionProvider extends SystemConditionProviderService { } } notifyCondition(conditionId, Condition.STATE_TRUE, "inEventNow"); notifyCondition(conditionId, Condition.STATE_TRUE, "inEventNow"); } } updateAlarm(now, reevaluateAt); rescheduleAlarm(now, reevaluateAt); if (DEBUG) Log.d(TAG, "evaluateSubscriptions took " + (System.currentTimeMillis() - now)); if (DEBUG) Slog.d(TAG, "evaluateSubscriptions took " + (System.currentTimeMillis() - now)); } } private void updateAlarm(long now, long time) { private void rescheduleAlarm(long now, long time) { mNextAlarmTime = time; final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE_EVALUATE, REQUEST_CODE_EVALUATE, Loading @@ -196,8 +268,8 @@ public class EventConditionProvider extends SystemConditionProviderService { } } private void notifyCondition(Uri conditionId, int state, String reason) { private void notifyCondition(Uri conditionId, int state, String reason) { if (DEBUG) Slog.d(TAG, "notifyCondition " + Condition.stateToString(state) if (DEBUG) Slog.d(TAG, "notifyCondition " + conditionId + " " + " reason=" + reason); + Condition.stateToString(state) + " reason=" + reason); notifyCondition(createCondition(conditionId, state)); notifyCondition(createCondition(conditionId, state)); } } Loading @@ -223,19 +295,35 @@ public class EventConditionProvider extends SystemConditionProviderService { } } } } private static Context getContextForUser(Context context, UserHandle user) { try { return context.createPackageContextAsUser(context.getPackageName(), 0, user); } catch (NameNotFoundException e) { return null; } } private final CalendarTracker.Callback mTrackerCallback = new CalendarTracker.Callback() { private final CalendarTracker.Callback mTrackerCallback = new CalendarTracker.Callback() { @Override @Override public void onChanged() { public void onChanged() { if (DEBUG) Log.d(TAG, "mTrackerCallback.onChanged"); if (DEBUG) Slog.d(TAG, "mTrackerCallback.onChanged"); evaluateSubscriptions(); mWorker.removeCallbacks(mEvaluateSubscriptionsW); mWorker.postDelayed(mEvaluateSubscriptionsW, CHANGE_DELAY); } } }; }; private BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction()); if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction()); evaluateSubscriptions(); evaluateSubscriptions(); } } }; }; private final Runnable mEvaluateSubscriptionsW = new Runnable() { @Override public void run() { evaluateSubscriptionsW(); } }; } } services/core/java/com/android/server/notification/ManagedServices.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -216,8 +216,8 @@ abstract public class ManagedServices { } } } } public void onUserSwitched() { public void onUserSwitched(int user) { if (DEBUG) Slog.d(TAG, "onUserSwitched"); if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user); if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); return; return; Loading Loading
core/java/android/service/notification/ZenModeConfig.java +13 −1 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.service.notification; package android.service.notification; import android.app.ActivityManager; import android.app.NotificationManager.Policy; import android.app.NotificationManager.Policy; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; Loading @@ -23,6 +24,7 @@ import android.content.res.Resources; import android.net.Uri; import android.net.Uri; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.provider.Settings.Global; import android.provider.Settings.Global; import android.text.TextUtils; import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateFormat; Loading Loading @@ -728,6 +730,7 @@ public class ZenModeConfig implements Parcelable { return new Uri.Builder().scheme(Condition.SCHEME) return new Uri.Builder().scheme(Condition.SCHEME) .authority(SYSTEM_AUTHORITY) .authority(SYSTEM_AUTHORITY) .appendPath(EVENT_PATH) .appendPath(EVENT_PATH) .appendQueryParameter("userId", Long.toString(event.userId)) .appendQueryParameter("calendar", Long.toString(event.calendar)) .appendQueryParameter("calendar", Long.toString(event.calendar)) .appendQueryParameter("reply", Integer.toString(event.reply)) .appendQueryParameter("reply", Integer.toString(event.reply)) .build(); .build(); Loading @@ -745,6 +748,7 @@ public class ZenModeConfig implements Parcelable { && conditionId.getPathSegments().get(0).equals(EVENT_PATH); && conditionId.getPathSegments().get(0).equals(EVENT_PATH); if (!isEvent) return null; if (!isEvent) return null; final EventInfo rt = new EventInfo(); final EventInfo rt = new EventInfo(); rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL); rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), rt.calendar = tryParseLong(conditionId.getQueryParameter("calendar"), EventInfo.ANY_CALENDAR); EventInfo.ANY_CALENDAR); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0); Loading @@ -758,6 +762,7 @@ public class ZenModeConfig implements Parcelable { public static final int REPLY_YES_OR_MAYBE = 1; public static final int REPLY_YES_OR_MAYBE = 1; public static final int REPLY_YES = 2; public static final int REPLY_YES = 2; public int userId = UserHandle.USER_NULL; // USER_NULL = unspecified - use current user public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR public long calendar = ANY_CALENDAR; // CalendarContract.Calendars._ID, or ANY_CALENDAR public int reply; public int reply; Loading @@ -770,16 +775,23 @@ public class ZenModeConfig implements Parcelable { public boolean equals(Object o) { public boolean equals(Object o) { if (!(o instanceof EventInfo)) return false; if (!(o instanceof EventInfo)) return false; final EventInfo other = (EventInfo) o; final EventInfo other = (EventInfo) o; return calendar == other.calendar return userId == other.userId && calendar == other.calendar && reply == other.reply; && reply == other.reply; } } public EventInfo copy() { public EventInfo copy() { final EventInfo rt = new EventInfo(); final EventInfo rt = new EventInfo(); rt.userId = userId; rt.calendar = calendar; rt.calendar = calendar; rt.reply = reply; rt.reply = reply; return rt; return rt; } } public static int resolveUserId(int userId) { return userId == UserHandle.USER_NULL ? ActivityManager.getCurrentUser() : userId; } } } // ==== End built-in system conditions ==== // ==== End built-in system conditions ==== Loading
services/core/java/com/android/server/notification/CalendarTracker.java +64 −22 Original line number Original line Diff line number Diff line Loading @@ -26,8 +26,11 @@ import android.database.Cursor; import android.net.Uri; import android.net.Uri; import android.provider.BaseColumns; import android.provider.BaseColumns; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Attendees; import android.provider.CalendarContract.Calendars; import android.provider.CalendarContract.Events; import android.provider.CalendarContract.Instances; import android.provider.CalendarContract.Instances; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenModeConfig.EventInfo; import android.util.ArraySet; import android.util.Log; import android.util.Log; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -63,13 +66,15 @@ public class CalendarTracker { private static final String ATTENDEE_SELECTION = Attendees.EVENT_ID + " = ? AND " private static final String ATTENDEE_SELECTION = Attendees.EVENT_ID + " = ? AND " + Attendees.ATTENDEE_EMAIL + " = ?"; + Attendees.ATTENDEE_EMAIL + " = ?"; private final Context mContext; private final Context mSystemContext; private final Context mUserContext; private Callback mCallback; private Callback mCallback; private boolean mRegistered; private boolean mRegistered; public CalendarTracker(Context context) { public CalendarTracker(Context systemContext, Context userContext) { mContext = context; mSystemContext = systemContext; mUserContext = userContext; } } public void setCallback(Callback callback) { public void setCallback(Callback callback) { Loading @@ -81,11 +86,12 @@ public class CalendarTracker { public void dump(String prefix, PrintWriter pw) { public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("mCallback="); pw.println(mCallback); pw.print(prefix); pw.print("mCallback="); pw.println(mCallback); pw.print(prefix); pw.print("mRegistered="); pw.println(mRegistered); pw.print(prefix); pw.print("mRegistered="); pw.println(mRegistered); pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId()); } } public void dumpContent(Uri uri) { public void dumpContent(Uri uri) { Log.d(TAG, "dumpContent: " + uri); Log.d(TAG, "dumpContent: " + uri); final Cursor cursor = mContext.getContentResolver().query(uri, null, null, null, null); final Cursor cursor = mUserContext.getContentResolver().query(uri, null, null, null, null); try { try { int r = 0; int r = 0; while (cursor.moveToNext()) { while (cursor.moveToNext()) { Loading Loading @@ -126,36 +132,61 @@ public class CalendarTracker { } } } } private ArraySet<Long> getPrimaryCalendars() { 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"; Cursor cursor = null; try { cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection, selection, null, null); while (cursor != null && cursor.moveToNext()) { rt.add(cursor.getLong(0)); } } finally { if (cursor != null) { cursor.close(); } } if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start)); return rt; } public CheckEventResult checkEvent(EventInfo filter, long time) { public CheckEventResult checkEvent(EventInfo filter, long time) { final Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon(); final Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon(); ContentUris.appendId(uriBuilder, time); ContentUris.appendId(uriBuilder, time); ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD); ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD); final Uri uri = uriBuilder.build(); final Uri uri = uriBuilder.build(); final Cursor cursor = mContext.getContentResolver().query(uri, INSTANCE_PROJECTION, null, final Cursor cursor = mUserContext.getContentResolver().query(uri, INSTANCE_PROJECTION, null, INSTANCE_ORDER_BY); null, null, INSTANCE_ORDER_BY); final CheckEventResult result = new CheckEventResult(); final CheckEventResult result = new CheckEventResult(); result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; result.recheckAt = time + EVENT_CHECK_LOOKAHEAD; try { try { while (cursor.moveToNext()) { final ArraySet<Long> primaryCalendars = getPrimaryCalendars(); while (cursor != null && cursor.moveToNext()) { final long begin = cursor.getLong(0); final long begin = cursor.getLong(0); final long end = cursor.getLong(1); final long end = cursor.getLong(1); final String title = cursor.getString(2); final String title = cursor.getString(2); final boolean visible = cursor.getInt(3) == 1; final boolean calendarVisible = cursor.getInt(3) == 1; final int eventId = cursor.getInt(4); final int eventId = cursor.getInt(4); final String owner = cursor.getString(5); final String owner = cursor.getString(5); final long calendarId = cursor.getLong(6); final long calendarId = cursor.getLong(6); final int availability = cursor.getInt(7); final int availability = cursor.getInt(7); if (DEBUG) Log.d(TAG, String.format("%s %s-%s v=%s a=%s eid=%s o=%s cid=%s", title, final boolean calendarPrimary = primaryCalendars.contains(calendarId); new Date(begin), new Date(end), visible, availabilityToString(availability), if (DEBUG) Log.d(TAG, String.format("%s %s-%s v=%s a=%s eid=%s o=%s cid=%s p=%s", eventId, owner, calendarId)); title, new Date(begin), new Date(end), calendarVisible, availabilityToString(availability), eventId, owner, calendarId, calendarPrimary)); final boolean meetsTime = time >= begin && time < end; final boolean meetsTime = time >= begin && time < end; final boolean meetsCalendar = visible final boolean meetsCalendar = calendarVisible && calendarPrimary && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId) && (filter.calendar == ANY_CALENDAR || filter.calendar == calendarId); && availability != Instances.AVAILABILITY_FREE; final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE; if (meetsCalendar) { if (meetsCalendar && meetsAvailability) { if (DEBUG) Log.d(TAG, " MEETS CALENDAR"); if (DEBUG) Log.d(TAG, " MEETS CALENDAR & AVAILABILITY"); final boolean meetsAttendee = meetsAttendee(filter, eventId, owner); final boolean meetsAttendee = meetsAttendee(filter, eventId, owner); if (meetsAttendee) { if (meetsAttendee) { if (DEBUG) Log.d(TAG, " MEETS ATTENDEE"); if (DEBUG) Log.d(TAG, " MEETS ATTENDEE"); Loading @@ -172,19 +203,22 @@ public class CalendarTracker { } } } } } finally { } finally { if (cursor != null) { cursor.close(); cursor.close(); } } } return result; return result; } } private boolean meetsAttendee(EventInfo filter, int eventId, String email) { private boolean meetsAttendee(EventInfo filter, int eventId, String email) { final long start = System.currentTimeMillis(); String selection = ATTENDEE_SELECTION; String selection = ATTENDEE_SELECTION; String[] selectionArgs = { Integer.toString(eventId), email }; String[] selectionArgs = { Integer.toString(eventId), email }; if (DEBUG_ATTENDEES) { if (DEBUG_ATTENDEES) { selection = null; selection = null; selectionArgs = null; selectionArgs = null; } } final Cursor cursor = mContext.getContentResolver().query(Attendees.CONTENT_URI, final Cursor cursor = mUserContext.getContentResolver().query(Attendees.CONTENT_URI, ATTENDEE_PROJECTION, selection, selectionArgs, null); ATTENDEE_PROJECTION, selection, selectionArgs, null); try { try { if (cursor.getCount() == 0) { if (cursor.getCount() == 0) { Loading @@ -208,18 +242,25 @@ public class CalendarTracker { return rt; return rt; } finally { } finally { cursor.close(); cursor.close(); if (DEBUG) Log.d(TAG, "meetsAttendee took " + (System.currentTimeMillis() - start)); } } } } private void setRegistered(boolean registered) { private void setRegistered(boolean registered) { if (mRegistered == registered) return; if (mRegistered == registered) return; final ContentResolver cr = mContext.getContentResolver(); final ContentResolver cr = mSystemContext.getContentResolver(); final int userId = mUserContext.getUserId(); if (mRegistered) { if (mRegistered) { if (DEBUG) Log.d(TAG, "unregister content observer u=" + userId); cr.unregisterContentObserver(mObserver); cr.unregisterContentObserver(mObserver); } } mRegistered = registered; mRegistered = registered; if (DEBUG) Log.d(TAG, "mRegistered = " + registered + " u=" + userId); if (mRegistered) { if (mRegistered) { cr.registerContentObserver(Instances.CONTENT_URI, false, mObserver); if (DEBUG) Log.d(TAG, "register content observer u=" + userId); cr.registerContentObserver(Instances.CONTENT_URI, true, mObserver, userId); cr.registerContentObserver(Events.CONTENT_URI, true, mObserver, userId); cr.registerContentObserver(Calendars.CONTENT_URI, true, mObserver, userId); } } } } Loading Loading @@ -260,7 +301,8 @@ public class CalendarTracker { private final ContentObserver mObserver = new ContentObserver(null) { private final ContentObserver mObserver = new ContentObserver(null) { @Override @Override public void onChange(boolean selfChange, Uri u) { public void onChange(boolean selfChange, Uri u) { if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange + " uri=" + u); if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange + " uri=" + u + " u=" + mUserContext.getUserId()); mCallback.onChanged(); mCallback.onChanged(); } } Loading
services/core/java/com/android/server/notification/ConditionProviders.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -130,8 +130,8 @@ public class ConditionProviders extends ManagedServices { } } @Override @Override public void onUserSwitched() { public void onUserSwitched(int user) { super.onUserSwitched(); super.onUserSwitched(user); if (mCallback != null) { if (mCallback != null) { mCallback.onUserSwitched(); mCallback.onUserSwitched(); } } Loading
services/core/java/com/android/server/notification/EventConditionProvider.java +105 −17 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,12 @@ import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.Condition; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig; Loading @@ -31,6 +36,7 @@ import android.service.notification.ZenModeConfig.EventInfo; import android.util.ArraySet; import android.util.ArraySet; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import com.android.server.notification.CalendarTracker.CheckEventResult; import com.android.server.notification.CalendarTracker.CheckEventResult; import com.android.server.notification.NotificationManagerService.DumpFilter; import com.android.server.notification.NotificationManagerService.DumpFilter; Loading @@ -51,17 +57,21 @@ public class EventConditionProvider extends SystemConditionProviderService { private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE"; private static final int REQUEST_CODE_EVALUATE = 1; private static final int REQUEST_CODE_EVALUATE = 1; private static final String EXTRA_TIME = "time"; private static final String EXTRA_TIME = "time"; private static final long CHANGE_DELAY = 2 * 1000; // coalesce chatty calendar changes private final Context mContext = this; private final Context mContext = this; private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>(); private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>(); private final CalendarTracker mTracker = new CalendarTracker(mContext); private final SparseArray<CalendarTracker> mTrackers = new SparseArray<>(); private final Handler mWorker; private boolean mConnected; private boolean mConnected; private boolean mRegistered; private boolean mRegistered; private boolean mBootComplete; // don't hammer the calendar provider until boot completes. private boolean mBootComplete; // don't hammer the calendar provider until boot completes. private long mNextAlarmTime; public EventConditionProvider() { public EventConditionProvider(Looper worker) { if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()"); if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()"); mWorker = new Handler(worker); } } @Override @Override Loading @@ -80,13 +90,17 @@ public class EventConditionProvider extends SystemConditionProviderService { pw.print(" mConnected="); pw.println(mConnected); pw.print(" mConnected="); pw.println(mConnected); pw.print(" mRegistered="); pw.println(mRegistered); pw.print(" mRegistered="); pw.println(mRegistered); pw.print(" mBootComplete="); pw.println(mBootComplete); pw.print(" mBootComplete="); pw.println(mBootComplete); dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, System.currentTimeMillis()); pw.println(" mSubscriptions="); pw.println(" mSubscriptions="); for (Uri conditionId : mSubscriptions) { for (Uri conditionId : mSubscriptions) { pw.print(" "); pw.print(" "); pw.println(conditionId); pw.println(conditionId); } } pw.println(" mTracker="); pw.println(" mTrackers="); mTracker.dump(" ", pw); for (int i = 0; i < mTrackers.size(); i++) { pw.print(" user="); pw.println(mTrackers.keyAt(i)); mTrackers.valueAt(i).dump(" ", pw); } } } @Override @Override Loading @@ -94,7 +108,16 @@ public class EventConditionProvider extends SystemConditionProviderService { if (DEBUG) Slog.d(TAG, "onBootComplete"); if (DEBUG) Slog.d(TAG, "onBootComplete"); if (mBootComplete) return; if (mBootComplete) return; mBootComplete = true; mBootComplete = true; evaluateSubscriptions(); final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { reloadTrackers(); } }, filter); reloadTrackers(); } } @Override @Override Loading Loading @@ -146,14 +169,39 @@ public class EventConditionProvider extends SystemConditionProviderService { return (IConditionProvider) onBind(null); return (IConditionProvider) onBind(null); } } private void reloadTrackers() { if (DEBUG) Slog.d(TAG, "reloadTrackers"); for (int i = 0; i < mTrackers.size(); i++) { mTrackers.valueAt(i).setCallback(null); } mTrackers.clear(); for (UserHandle user : UserManager.get(mContext).getUserProfiles()) { final Context context = user.isOwner() ? mContext : getContextForUser(mContext, user); if (context == null) { Slog.w(TAG, "Unable to create context for user " + user.getIdentifier()); continue; } mTrackers.put(user.getIdentifier(), new CalendarTracker(mContext, context)); } evaluateSubscriptions(); } private void evaluateSubscriptions() { private void evaluateSubscriptions() { if (DEBUG) Log.d(TAG, "evaluateSubscriptions"); if (!mWorker.hasCallbacks(mEvaluateSubscriptionsW)) { mWorker.post(mEvaluateSubscriptionsW); } } private void evaluateSubscriptionsW() { if (DEBUG) Slog.d(TAG, "evaluateSubscriptions"); if (!mBootComplete) { if (!mBootComplete) { if (DEBUG) Log.d(TAG, "Skipping evaluate before boot complete"); if (DEBUG) Slog.d(TAG, "Skipping evaluate before boot complete"); return; return; } } final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis(); mTracker.setCallback(mSubscriptions.isEmpty() ? null : mTrackerCallback); for (int i = 0; i < mTrackers.size(); i++) { mTrackers.valueAt(i).setCallback(mSubscriptions.isEmpty() ? null : mTrackerCallback); } setRegistered(!mSubscriptions.isEmpty()); setRegistered(!mSubscriptions.isEmpty()); long reevaluateAt = 0; long reevaluateAt = 0; for (Uri conditionId : mSubscriptions) { for (Uri conditionId : mSubscriptions) { Loading @@ -162,7 +210,30 @@ public class EventConditionProvider extends SystemConditionProviderService { notifyCondition(conditionId, Condition.STATE_FALSE, "badConditionId"); notifyCondition(conditionId, Condition.STATE_FALSE, "badConditionId"); continue; continue; } } final CheckEventResult result = mTracker.checkEvent(event, now); CheckEventResult result = null; if (event.calendar == EventInfo.ANY_CALENDAR) { // event could exist on any tracker for (int i = 0; i < mTrackers.size(); i++) { final CalendarTracker tracker = mTrackers.valueAt(i); final CheckEventResult r = tracker.checkEvent(event, now); if (result == null) { result = r; } else { result.inEvent |= r.inEvent; result.recheckAt = Math.min(result.recheckAt, r.recheckAt); } } } else { // event should exist on one tracker final int userId = EventInfo.resolveUserId(event.userId); final CalendarTracker tracker = mTrackers.get(userId); if (tracker == null) { Slog.w(TAG, "No calendar tracker found for user " + userId); notifyCondition(conditionId, Condition.STATE_FALSE, "badUserId"); continue; } result = tracker.checkEvent(event, now); } if (result.recheckAt != 0 && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) { if (result.recheckAt != 0 && (reevaluateAt == 0 || result.recheckAt < reevaluateAt)) { reevaluateAt = result.recheckAt; reevaluateAt = result.recheckAt; } } Loading @@ -172,11 +243,12 @@ public class EventConditionProvider extends SystemConditionProviderService { } } notifyCondition(conditionId, Condition.STATE_TRUE, "inEventNow"); notifyCondition(conditionId, Condition.STATE_TRUE, "inEventNow"); } } updateAlarm(now, reevaluateAt); rescheduleAlarm(now, reevaluateAt); if (DEBUG) Log.d(TAG, "evaluateSubscriptions took " + (System.currentTimeMillis() - now)); if (DEBUG) Slog.d(TAG, "evaluateSubscriptions took " + (System.currentTimeMillis() - now)); } } private void updateAlarm(long now, long time) { private void rescheduleAlarm(long now, long time) { mNextAlarmTime = time; final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); final AlarmManager alarms = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE_EVALUATE, REQUEST_CODE_EVALUATE, Loading @@ -196,8 +268,8 @@ public class EventConditionProvider extends SystemConditionProviderService { } } private void notifyCondition(Uri conditionId, int state, String reason) { private void notifyCondition(Uri conditionId, int state, String reason) { if (DEBUG) Slog.d(TAG, "notifyCondition " + Condition.stateToString(state) if (DEBUG) Slog.d(TAG, "notifyCondition " + conditionId + " " + " reason=" + reason); + Condition.stateToString(state) + " reason=" + reason); notifyCondition(createCondition(conditionId, state)); notifyCondition(createCondition(conditionId, state)); } } Loading @@ -223,19 +295,35 @@ public class EventConditionProvider extends SystemConditionProviderService { } } } } private static Context getContextForUser(Context context, UserHandle user) { try { return context.createPackageContextAsUser(context.getPackageName(), 0, user); } catch (NameNotFoundException e) { return null; } } private final CalendarTracker.Callback mTrackerCallback = new CalendarTracker.Callback() { private final CalendarTracker.Callback mTrackerCallback = new CalendarTracker.Callback() { @Override @Override public void onChanged() { public void onChanged() { if (DEBUG) Log.d(TAG, "mTrackerCallback.onChanged"); if (DEBUG) Slog.d(TAG, "mTrackerCallback.onChanged"); evaluateSubscriptions(); mWorker.removeCallbacks(mEvaluateSubscriptionsW); mWorker.postDelayed(mEvaluateSubscriptionsW, CHANGE_DELAY); } } }; }; private BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction()); if (DEBUG) Slog.d(TAG, "onReceive " + intent.getAction()); evaluateSubscriptions(); evaluateSubscriptions(); } } }; }; private final Runnable mEvaluateSubscriptionsW = new Runnable() { @Override public void run() { evaluateSubscriptionsW(); } }; } }
services/core/java/com/android/server/notification/ManagedServices.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -216,8 +216,8 @@ abstract public class ManagedServices { } } } } public void onUserSwitched() { public void onUserSwitched(int user) { if (DEBUG) Slog.d(TAG, "onUserSwitched"); if (DEBUG) Slog.d(TAG, "onUserSwitched u=" + user); if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { if (Arrays.equals(mLastSeenProfileIds, mUserProfiles.getCurrentProfileIds())) { if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); if (DEBUG) Slog.d(TAG, "Current profile IDs didn't change, skipping rebindServices()."); return; return; Loading