Loading services/core/java/com/android/server/notification/NotificationManagerService.java +24 −36 Original line number Original line Diff line number Diff line Loading @@ -617,7 +617,7 @@ public class NotificationManagerService extends SystemService { { { final int pid; final int pid; final String pkg; final String pkg; ITransientNotification callback; final ITransientNotification callback; int duration; int duration; Binder token; Binder token; Loading @@ -634,10 +634,6 @@ public class NotificationManagerService extends SystemService { this.duration = duration; this.duration = duration; } } void update(ITransientNotification callback) { this.callback = callback; } void dump(PrintWriter pw, String prefix, DumpFilter filter) { void dump(PrintWriter pw, String prefix, DumpFilter filter) { if (filter != null && !filter.matches(pkg)) return; if (filter != null && !filter.matches(pkg)) return; pw.println(prefix + this); pw.println(prefix + this); Loading Loading @@ -1993,32 +1989,38 @@ public class NotificationManagerService extends SystemService { long callingId = Binder.clearCallingIdentity(); long callingId = Binder.clearCallingIdentity(); try { try { ToastRecord record; ToastRecord record; int index; int index = indexOfToastLocked(pkg, callback); // All packages aside from the android package can enqueue one toast at a time // If it's already in the queue, we update it in place, we don't if (!isSystemToast) { // move it to the end of the queue. index = indexOfToastPackageLocked(pkg); } else { index = indexOfToastLocked(pkg, callback); } // If the package already has a toast, we update its toast // in the queue, we don't move it to the end of the queue. if (index >= 0) { if (index >= 0) { record = mToastQueue.get(index); record = mToastQueue.get(index); record.update(duration); record.update(duration); try { record.callback.hide(); } catch (RemoteException e) { } record.update(callback); } else { } else { // Limit the number of toasts that any given package except the android // package can enqueue. Prevents DOS attacks and deals with leaks. if (!isSystemToast) { int count = 0; final int N = mToastQueue.size(); for (int i=0; i<N; i++) { final ToastRecord r = mToastQueue.get(i); if (r.pkg.equals(pkg)) { count++; if (count >= MAX_PACKAGE_NOTIFICATIONS) { Slog.e(TAG, "Package has already posted " + count + " toasts. Not showing more. Package=" + pkg); return; } } } } Binder token = new Binder(); Binder token = new Binder(); mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY); mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY); record = new ToastRecord(callingPid, pkg, callback, duration, token); record = new ToastRecord(callingPid, pkg, callback, duration, token); mToastQueue.add(record); mToastQueue.add(record); index = mToastQueue.size() - 1; index = mToastQueue.size() - 1; } keepProcessAliveIfNeededLocked(callingPid); keepProcessAliveIfNeededLocked(callingPid); } // If it's at index 0, it's the current toast. It doesn't matter if it's // If it's at index 0, it's the current toast. It doesn't matter if it's // new or just been updated. Call back and tell it to show itself. // new or just been updated. Call back and tell it to show itself. // If the callback fails, this will remove it from the list, so don't // If the callback fails, this will remove it from the list, so don't Loading Loading @@ -5098,21 +5100,7 @@ public class NotificationManagerService extends SystemService { int len = list.size(); int len = list.size(); for (int i=0; i<len; i++) { for (int i=0; i<len; i++) { ToastRecord r = list.get(i); ToastRecord r = list.get(i); if (r.pkg.equals(pkg) && r.callback.asBinder().equals(cbak)) { if (r.pkg.equals(pkg) && r.callback.asBinder() == cbak) { return i; } } return -1; } @GuardedBy("mToastQueue") int indexOfToastPackageLocked(String pkg) { ArrayList<ToastRecord> list = mToastQueue; int len = list.size(); for (int i=0; i<len; i++) { ToastRecord r = list.get(i); if (r.pkg.equals(pkg)) { return i; return i; } } } } Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +24 −36 Original line number Original line Diff line number Diff line Loading @@ -617,7 +617,7 @@ public class NotificationManagerService extends SystemService { { { final int pid; final int pid; final String pkg; final String pkg; ITransientNotification callback; final ITransientNotification callback; int duration; int duration; Binder token; Binder token; Loading @@ -634,10 +634,6 @@ public class NotificationManagerService extends SystemService { this.duration = duration; this.duration = duration; } } void update(ITransientNotification callback) { this.callback = callback; } void dump(PrintWriter pw, String prefix, DumpFilter filter) { void dump(PrintWriter pw, String prefix, DumpFilter filter) { if (filter != null && !filter.matches(pkg)) return; if (filter != null && !filter.matches(pkg)) return; pw.println(prefix + this); pw.println(prefix + this); Loading Loading @@ -1993,32 +1989,38 @@ public class NotificationManagerService extends SystemService { long callingId = Binder.clearCallingIdentity(); long callingId = Binder.clearCallingIdentity(); try { try { ToastRecord record; ToastRecord record; int index; int index = indexOfToastLocked(pkg, callback); // All packages aside from the android package can enqueue one toast at a time // If it's already in the queue, we update it in place, we don't if (!isSystemToast) { // move it to the end of the queue. index = indexOfToastPackageLocked(pkg); } else { index = indexOfToastLocked(pkg, callback); } // If the package already has a toast, we update its toast // in the queue, we don't move it to the end of the queue. if (index >= 0) { if (index >= 0) { record = mToastQueue.get(index); record = mToastQueue.get(index); record.update(duration); record.update(duration); try { record.callback.hide(); } catch (RemoteException e) { } record.update(callback); } else { } else { // Limit the number of toasts that any given package except the android // package can enqueue. Prevents DOS attacks and deals with leaks. if (!isSystemToast) { int count = 0; final int N = mToastQueue.size(); for (int i=0; i<N; i++) { final ToastRecord r = mToastQueue.get(i); if (r.pkg.equals(pkg)) { count++; if (count >= MAX_PACKAGE_NOTIFICATIONS) { Slog.e(TAG, "Package has already posted " + count + " toasts. Not showing more. Package=" + pkg); return; } } } } Binder token = new Binder(); Binder token = new Binder(); mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY); mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY); record = new ToastRecord(callingPid, pkg, callback, duration, token); record = new ToastRecord(callingPid, pkg, callback, duration, token); mToastQueue.add(record); mToastQueue.add(record); index = mToastQueue.size() - 1; index = mToastQueue.size() - 1; } keepProcessAliveIfNeededLocked(callingPid); keepProcessAliveIfNeededLocked(callingPid); } // If it's at index 0, it's the current toast. It doesn't matter if it's // If it's at index 0, it's the current toast. It doesn't matter if it's // new or just been updated. Call back and tell it to show itself. // new or just been updated. Call back and tell it to show itself. // If the callback fails, this will remove it from the list, so don't // If the callback fails, this will remove it from the list, so don't Loading Loading @@ -5098,21 +5100,7 @@ public class NotificationManagerService extends SystemService { int len = list.size(); int len = list.size(); for (int i=0; i<len; i++) { for (int i=0; i<len; i++) { ToastRecord r = list.get(i); ToastRecord r = list.get(i); if (r.pkg.equals(pkg) && r.callback.asBinder().equals(cbak)) { if (r.pkg.equals(pkg) && r.callback.asBinder() == cbak) { return i; } } return -1; } @GuardedBy("mToastQueue") int indexOfToastPackageLocked(String pkg) { ArrayList<ToastRecord> list = mToastQueue; int len = list.size(); for (int i=0; i<len; i++) { ToastRecord r = list.get(i); if (r.pkg.equals(pkg)) { return i; return i; } } } } Loading