Loading core/java/android/app/INotificationManager.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -47,8 +47,8 @@ interface INotificationManager void cancelAllNotifications(String pkg, int userId); void cancelAllNotifications(String pkg, int userId); void clearData(String pkg, int uid, boolean fromApp); void clearData(String pkg, int uid, boolean fromApp); void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, int displayId, @nullable ITransientNotificationCallback callback); void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, boolean isUiContext, int displayId, @nullable ITransientNotificationCallback callback); void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, int displayId); void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, boolean isUiContext, int displayId); void cancelToast(String pkg, IBinder token); void cancelToast(String pkg, IBinder token); void finishToken(String pkg, IBinder token); void finishToken(String pkg, IBinder token); Loading core/java/android/widget/Toast.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -206,21 +206,23 @@ public class Toast { String pkg = mContext.getOpPackageName(); String pkg = mContext.getOpPackageName(); TN tn = mTN; TN tn = mTN; tn.mNextView = mNextView; tn.mNextView = mNextView; final boolean isUiContext = mContext.isUiContext(); final int displayId = mContext.getDisplayId(); final int displayId = mContext.getDisplayId(); try { try { if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) { if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) { if (mNextView != null) { if (mNextView != null) { // It's a custom toast // It's a custom toast service.enqueueToast(pkg, mToken, tn, mDuration, displayId); service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } else { } else { // It's a text toast // It's a text toast ITransientNotificationCallback callback = ITransientNotificationCallback callback = new CallbackBinder(mCallbacks, mHandler); new CallbackBinder(mCallbacks, mHandler); service.enqueueTextToast(pkg, mToken, mText, mDuration, displayId, callback); service.enqueueTextToast(pkg, mToken, mText, mDuration, isUiContext, displayId, callback); } } } else { } else { service.enqueueToast(pkg, mToken, tn, mDuration, displayId); service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } } } catch (RemoteException e) { } catch (RemoteException e) { // Empty // Empty Loading services/core/java/com/android/server/notification/NotificationManagerService.java +27 −6 Original line number Original line Diff line number Diff line Loading @@ -265,6 +265,7 @@ import android.util.SparseBooleanArray; import android.util.StatsEvent; import android.util.StatsEvent; import android.util.Xml; import android.util.Xml; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager; import android.widget.RemoteViews; import android.widget.RemoteViews; Loading Loading @@ -316,6 +317,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.Slogf; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.BackgroundActivityStartCallback; import com.android.server.wm.BackgroundActivityStartCallback; Loading Loading @@ -3288,19 +3290,22 @@ public class NotificationManagerService extends SystemService { @Override @Override public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, int displayId, @Nullable ITransientNotificationCallback callback) { boolean isUiContext, int displayId, enqueueToast(pkg, token, text, null, duration, displayId, callback); @Nullable ITransientNotificationCallback textCallback) { enqueueToast(pkg, token, text, /* callback= */ null, duration, isUiContext, displayId, textCallback); } } @Override @Override public void enqueueToast(String pkg, IBinder token, ITransientNotification callback, public void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, int displayId) { int duration, boolean isUiContext, int displayId) { enqueueToast(pkg, token, null, callback, duration, displayId, null); enqueueToast(pkg, token, /* text= */ null, callback, duration, isUiContext, displayId, /* textCallback= */ null); } } private void enqueueToast(String pkg, IBinder token, @Nullable CharSequence text, private void enqueueToast(String pkg, IBinder token, @Nullable CharSequence text, @Nullable ITransientNotification callback, int duration, int displayId, @Nullable ITransientNotification callback, int duration, boolean isUiContext, @Nullable ITransientNotificationCallback textCallback) { int displayId, @Nullable ITransientNotificationCallback textCallback) { if (DBG) { if (DBG) { Slog.i(TAG, "enqueueToast pkg=" + pkg + " token=" + token Slog.i(TAG, "enqueueToast pkg=" + pkg + " token=" + token + " duration=" + duration + " displayId=" + displayId); + " duration=" + duration + " displayId=" + displayId); Loading @@ -3322,6 +3327,22 @@ public class NotificationManagerService extends SystemService { return; return; } } if (!isUiContext && displayId == Display.DEFAULT_DISPLAY && UserManager.isVisibleBackgroundUsersEnabled()) { // When the caller is a visible background user using a non-ui context (like the // application context), the Toast must be displayed in the display the user was // started visible on int userId = UserHandle.getUserId(callingUid); int userDisplayId = mUmInternal.getMainDisplayAssignedToUser(userId); if (displayId != userDisplayId) { if (DBG) { Slogf.d(TAG, "Changing display id from %d to %d on user %d", displayId, userDisplayId, userId); } displayId = userDisplayId; } } synchronized (mToastQueue) { synchronized (mToastQueue) { int callingPid = Binder.getCallingPid(); int callingPid = Binder.getCallingPid(); final long callingId = Binder.clearCallingIdentity(); final long callingId = Binder.clearCallingIdentity(); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +42 −41 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN; import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING; Loading Loading @@ -278,7 +279,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; private static final String PKG_NO_CHANNELS = "com.example.no.channels"; private static final String PKG_NO_CHANNELS = "com.example.no.channels"; private static final int TEST_TASK_ID = 1; private static final int TEST_TASK_ID = 1; private static final int UID_HEADLESS = 1000000; private static final int UID_HEADLESS = 1_000_000; private static final int TOAST_DURATION = 2_000; private final int mUid = Binder.getCallingUid(); private final int mUid = Binder.getCallingUid(); private TestableNotificationManagerService mService; private TestableNotificationManagerService mService; Loading Loading @@ -6539,8 +6541,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6559,8 +6560,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6583,12 +6583,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; // first time trying to show the toast, showToast gets called // first time trying to show the toast, showToast gets called nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); // second time trying to show the same toast, showToast isn't called again (total number of // second time trying to show the same toast, showToast isn't called again (total number of // invocations stays at one) // invocations stays at one) nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); } } Loading @@ -6611,7 +6611,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback = mock(ITransientNotification.class); ITransientNotification callback = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); } } Loading @@ -6636,8 +6636,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback2 = mock(ITransientNotification.class); ITransientNotification callback2 = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueToast(testPackage, token1, callback1, 2000, 0); enqueueToast(nmService, testPackage, token1, callback1); nmService.enqueueToast(testPackage, token2, callback2, 2000, 0); enqueueToast(nmService, testPackage, token2, callback2); assertEquals(2, mService.mToastQueue.size()); // Both toasts enqueued. assertEquals(2, mService.mToastQueue.size()); // Both toasts enqueued. verify(callback1, times(1)).show(any()); // First toast shown. verify(callback1, times(1)).show(any()); // First toast shown. Loading Loading @@ -6665,8 +6665,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6685,8 +6684,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6708,13 +6706,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; // first time trying to show the toast, showToast gets called // first time trying to show the toast, showToast gets called nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); // second time trying to show the same toast, showToast isn't called again (total number of // second time trying to show the same toast, showToast isn't called again (total number of // invocations stays at one) // invocations stays at one) nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6736,7 +6734,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(0)) verify(mStatusBar, times(0)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6758,7 +6756,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6779,7 +6777,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); anyInt()); } } Loading @@ -6800,7 +6798,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); // window token was added when enqueued // window token was added when enqueued ArgumentCaptor<Binder> binderCaptor = ArgumentCaptor<Binder> binderCaptor = Loading Loading @@ -6836,8 +6834,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any()); } } Loading @@ -6858,8 +6855,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } } Loading @@ -6880,8 +6876,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } } Loading @@ -6899,8 +6894,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); .thenReturn(false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); anyInt()); } } Loading @@ -6921,8 +6915,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6944,8 +6937,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6967,8 +6959,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> system toast can still be enqueued // enqueue toast -> system toast can still be enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6988,13 +6979,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Trying to quickly enqueue more toast than allowed. // Trying to quickly enqueue more toast than allowed. for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { nmService.enqueueTextToast( enqueueTextToast(testPackage, "Text"); testPackage, new Binder(), "Text", /* duration */ 2000, /* displayId */ 0, /* callback */ null); } } // Only allowed number enqueued, rest ignored. // Only allowed number enqueued, rest ignored. assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); Loading Loading @@ -10718,4 +10703,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { String.valueOf(isOn), String.valueOf(isOn), /* makeDefault= */ false); /* makeDefault= */ false); } } private void enqueueToast(String testPackage, ITransientNotification callback) throws RemoteException { enqueueToast((INotificationManager) mService.mService, testPackage, new Binder(), callback); } private void enqueueToast(INotificationManager service, String testPackage, IBinder token, ITransientNotification callback) throws RemoteException { service.enqueueToast(testPackage, token, callback, TOAST_DURATION, /* isUiContext= */ true, DEFAULT_DISPLAY); } private void enqueueTextToast(String testPackage, CharSequence text) throws RemoteException { ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), text, TOAST_DURATION, /* isUiContext= */ true, DEFAULT_DISPLAY, /* textCallback= */ null); } } } Loading
core/java/android/app/INotificationManager.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -47,8 +47,8 @@ interface INotificationManager void cancelAllNotifications(String pkg, int userId); void cancelAllNotifications(String pkg, int userId); void clearData(String pkg, int uid, boolean fromApp); void clearData(String pkg, int uid, boolean fromApp); void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, int displayId, @nullable ITransientNotificationCallback callback); void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, boolean isUiContext, int displayId, @nullable ITransientNotificationCallback callback); void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, int displayId); void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, boolean isUiContext, int displayId); void cancelToast(String pkg, IBinder token); void cancelToast(String pkg, IBinder token); void finishToken(String pkg, IBinder token); void finishToken(String pkg, IBinder token); Loading
core/java/android/widget/Toast.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -206,21 +206,23 @@ public class Toast { String pkg = mContext.getOpPackageName(); String pkg = mContext.getOpPackageName(); TN tn = mTN; TN tn = mTN; tn.mNextView = mNextView; tn.mNextView = mNextView; final boolean isUiContext = mContext.isUiContext(); final int displayId = mContext.getDisplayId(); final int displayId = mContext.getDisplayId(); try { try { if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) { if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) { if (mNextView != null) { if (mNextView != null) { // It's a custom toast // It's a custom toast service.enqueueToast(pkg, mToken, tn, mDuration, displayId); service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } else { } else { // It's a text toast // It's a text toast ITransientNotificationCallback callback = ITransientNotificationCallback callback = new CallbackBinder(mCallbacks, mHandler); new CallbackBinder(mCallbacks, mHandler); service.enqueueTextToast(pkg, mToken, mText, mDuration, displayId, callback); service.enqueueTextToast(pkg, mToken, mText, mDuration, isUiContext, displayId, callback); } } } else { } else { service.enqueueToast(pkg, mToken, tn, mDuration, displayId); service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } } } catch (RemoteException e) { } catch (RemoteException e) { // Empty // Empty Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +27 −6 Original line number Original line Diff line number Diff line Loading @@ -265,6 +265,7 @@ import android.util.SparseBooleanArray; import android.util.StatsEvent; import android.util.StatsEvent; import android.util.Xml; import android.util.Xml; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager; import android.widget.RemoteViews; import android.widget.RemoteViews; Loading Loading @@ -316,6 +317,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.Slogf; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.BackgroundActivityStartCallback; import com.android.server.wm.BackgroundActivityStartCallback; Loading Loading @@ -3288,19 +3290,22 @@ public class NotificationManagerService extends SystemService { @Override @Override public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, int displayId, @Nullable ITransientNotificationCallback callback) { boolean isUiContext, int displayId, enqueueToast(pkg, token, text, null, duration, displayId, callback); @Nullable ITransientNotificationCallback textCallback) { enqueueToast(pkg, token, text, /* callback= */ null, duration, isUiContext, displayId, textCallback); } } @Override @Override public void enqueueToast(String pkg, IBinder token, ITransientNotification callback, public void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, int displayId) { int duration, boolean isUiContext, int displayId) { enqueueToast(pkg, token, null, callback, duration, displayId, null); enqueueToast(pkg, token, /* text= */ null, callback, duration, isUiContext, displayId, /* textCallback= */ null); } } private void enqueueToast(String pkg, IBinder token, @Nullable CharSequence text, private void enqueueToast(String pkg, IBinder token, @Nullable CharSequence text, @Nullable ITransientNotification callback, int duration, int displayId, @Nullable ITransientNotification callback, int duration, boolean isUiContext, @Nullable ITransientNotificationCallback textCallback) { int displayId, @Nullable ITransientNotificationCallback textCallback) { if (DBG) { if (DBG) { Slog.i(TAG, "enqueueToast pkg=" + pkg + " token=" + token Slog.i(TAG, "enqueueToast pkg=" + pkg + " token=" + token + " duration=" + duration + " displayId=" + displayId); + " duration=" + duration + " displayId=" + displayId); Loading @@ -3322,6 +3327,22 @@ public class NotificationManagerService extends SystemService { return; return; } } if (!isUiContext && displayId == Display.DEFAULT_DISPLAY && UserManager.isVisibleBackgroundUsersEnabled()) { // When the caller is a visible background user using a non-ui context (like the // application context), the Toast must be displayed in the display the user was // started visible on int userId = UserHandle.getUserId(callingUid); int userDisplayId = mUmInternal.getMainDisplayAssignedToUser(userId); if (displayId != userDisplayId) { if (DBG) { Slogf.d(TAG, "Changing display id from %d to %d on user %d", displayId, userDisplayId, userId); } displayId = userDisplayId; } } synchronized (mToastQueue) { synchronized (mToastQueue) { int callingPid = Binder.getCallingPid(); int callingPid = Binder.getCallingPid(); final long callingId = Binder.clearCallingIdentity(); final long callingId = Binder.clearCallingIdentity(); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +42 −41 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN; import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING; Loading Loading @@ -278,7 +279,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; private static final String PKG_NO_CHANNELS = "com.example.no.channels"; private static final String PKG_NO_CHANNELS = "com.example.no.channels"; private static final int TEST_TASK_ID = 1; private static final int TEST_TASK_ID = 1; private static final int UID_HEADLESS = 1000000; private static final int UID_HEADLESS = 1_000_000; private static final int TOAST_DURATION = 2_000; private final int mUid = Binder.getCallingUid(); private final int mUid = Binder.getCallingUid(); private TestableNotificationManagerService mService; private TestableNotificationManagerService mService; Loading Loading @@ -6539,8 +6541,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6559,8 +6560,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6583,12 +6583,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; // first time trying to show the toast, showToast gets called // first time trying to show the toast, showToast gets called nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); // second time trying to show the same toast, showToast isn't called again (total number of // second time trying to show the same toast, showToast isn't called again (total number of // invocations stays at one) // invocations stays at one) nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); } } Loading @@ -6611,7 +6611,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback = mock(ITransientNotification.class); ITransientNotification callback = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueToast(testPackage, token, callback, 2000, 0); enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); verify(callback, times(1)).show(any()); } } Loading @@ -6636,8 +6636,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback2 = mock(ITransientNotification.class); ITransientNotification callback2 = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueToast(testPackage, token1, callback1, 2000, 0); enqueueToast(nmService, testPackage, token1, callback1); nmService.enqueueToast(testPackage, token2, callback2, 2000, 0); enqueueToast(nmService, testPackage, token2, callback2); assertEquals(2, mService.mToastQueue.size()); // Both toasts enqueued. assertEquals(2, mService.mToastQueue.size()); // Both toasts enqueued. verify(callback1, times(1)).show(any()); // First toast shown. verify(callback1, times(1)).show(any()); // First toast shown. Loading Loading @@ -6665,8 +6665,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6685,8 +6684,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6708,13 +6706,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; // first time trying to show the toast, showToast gets called // first time trying to show the toast, showToast gets called nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); // second time trying to show the same toast, showToast isn't called again (total number of // second time trying to show the same toast, showToast isn't called again (total number of // invocations stays at one) // invocations stays at one) nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6736,7 +6734,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(0)) verify(mStatusBar, times(0)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6758,7 +6756,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } } Loading @@ -6779,7 +6777,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); anyInt()); } } Loading @@ -6800,7 +6798,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; INotificationManager nmService = (INotificationManager) mService.mService; nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); enqueueTextToast(testPackage, "Text"); // window token was added when enqueued // window token was added when enqueued ArgumentCaptor<Binder> binderCaptor = ArgumentCaptor<Binder> binderCaptor = Loading Loading @@ -6836,8 +6834,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any()); } } Loading @@ -6858,8 +6855,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } } Loading @@ -6880,8 +6876,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue // enqueue toast -> toast should still enqueue ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } } Loading @@ -6899,8 +6894,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); .thenReturn(false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), enqueueTextToast(testPackage, "Text"); "Text", 2000, 0, null); verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); anyInt()); } } Loading @@ -6921,8 +6915,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6944,8 +6937,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued // enqueue toast -> no toasts enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(0, mService.mToastQueue.size()); assertEquals(0, mService.mToastQueue.size()); } } Loading @@ -6967,8 +6959,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); setAppInForegroundForToasts(mUid, false); // enqueue toast -> system toast can still be enqueued // enqueue toast -> system toast can still be enqueued ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), enqueueToast(testPackage, new TestableToastCallback()); new TestableToastCallback(), 2000, 0); assertEquals(1, mService.mToastQueue.size()); assertEquals(1, mService.mToastQueue.size()); } } Loading @@ -6988,13 +6979,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Trying to quickly enqueue more toast than allowed. // Trying to quickly enqueue more toast than allowed. for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { nmService.enqueueTextToast( enqueueTextToast(testPackage, "Text"); testPackage, new Binder(), "Text", /* duration */ 2000, /* displayId */ 0, /* callback */ null); } } // Only allowed number enqueued, rest ignored. // Only allowed number enqueued, rest ignored. assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); Loading Loading @@ -10718,4 +10703,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { String.valueOf(isOn), String.valueOf(isOn), /* makeDefault= */ false); /* makeDefault= */ false); } } private void enqueueToast(String testPackage, ITransientNotification callback) throws RemoteException { enqueueToast((INotificationManager) mService.mService, testPackage, new Binder(), callback); } private void enqueueToast(INotificationManager service, String testPackage, IBinder token, ITransientNotification callback) throws RemoteException { service.enqueueToast(testPackage, token, callback, TOAST_DURATION, /* isUiContext= */ true, DEFAULT_DISPLAY); } private void enqueueTextToast(String testPackage, CharSequence text) throws RemoteException { ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), text, TOAST_DURATION, /* isUiContext= */ true, DEFAULT_DISPLAY, /* textCallback= */ null); } } }