diff options
| author | 2023-03-27 15:16:43 +0000 | |
|---|---|---|
| committer | 2023-03-27 15:16:43 +0000 | |
| commit | bc952dca38f18b3d275d8647cb6c87e1321421a5 (patch) | |
| tree | 8b305f48b0f4d849efa56c1a875e4ae8cef1cae1 | |
| parent | dce3abf80d84263d578c19e285840e456cdaab7c (diff) | |
| parent | 0d4546d1d4407ae215b0bd9962f6bcc10de01754 (diff) | |
Merge "Fixes Toast.show() for visible background users." into udc-dev
4 files changed, 76 insertions, 52 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index ef9de18d47bd..746b8f70b6af 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -47,8 +47,8 @@ interface INotificationManager void cancelAllNotifications(String pkg, int userId); void clearData(String pkg, int uid, boolean fromApp); - void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, int displayId, @nullable ITransientNotificationCallback callback); - void enqueueToast(String pkg, IBinder token, ITransientNotification callback, int duration, int displayId); + 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, boolean isUiContext, int displayId); void cancelToast(String pkg, IBinder token); void finishToken(String pkg, IBinder token); diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index fceee4e01799..54d19eb79305 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -206,21 +206,23 @@ public class Toast { String pkg = mContext.getOpPackageName(); TN tn = mTN; tn.mNextView = mNextView; + final boolean isUiContext = mContext.isUiContext(); final int displayId = mContext.getDisplayId(); try { if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) { if (mNextView != null) { // It's a custom toast - service.enqueueToast(pkg, mToken, tn, mDuration, displayId); + service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } else { // It's a text toast ITransientNotificationCallback callback = new CallbackBinder(mCallbacks, mHandler); - service.enqueueTextToast(pkg, mToken, mText, mDuration, displayId, callback); + service.enqueueTextToast(pkg, mToken, mText, mDuration, isUiContext, displayId, + callback); } } else { - service.enqueueToast(pkg, mToken, tn, mDuration, displayId); + service.enqueueToast(pkg, mToken, tn, mDuration, isUiContext, displayId); } } catch (RemoteException e) { // Empty diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f09f7c2797e5..431925c57cb4 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -265,6 +265,7 @@ import android.util.SparseBooleanArray; import android.util.StatsEvent; import android.util.Xml; import android.util.proto.ProtoOutputStream; +import android.view.Display; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.RemoteViews; @@ -316,6 +317,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; +import com.android.server.utils.Slogf; import com.android.server.utils.quota.MultiRateLimiter; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.BackgroundActivityStartCallback; @@ -3288,19 +3290,22 @@ public class NotificationManagerService extends SystemService { @Override public void enqueueTextToast(String pkg, IBinder token, CharSequence text, int duration, - int displayId, @Nullable ITransientNotificationCallback callback) { - enqueueToast(pkg, token, text, null, duration, displayId, callback); + boolean isUiContext, int displayId, + @Nullable ITransientNotificationCallback textCallback) { + enqueueToast(pkg, token, text, /* callback= */ null, duration, isUiContext, displayId, + textCallback); } @Override public void enqueueToast(String pkg, IBinder token, ITransientNotification callback, - int duration, int displayId) { - enqueueToast(pkg, token, null, callback, duration, displayId, null); + int duration, boolean isUiContext, int displayId) { + enqueueToast(pkg, token, /* text= */ null, callback, duration, isUiContext, displayId, + /* textCallback= */ null); } private void enqueueToast(String pkg, IBinder token, @Nullable CharSequence text, - @Nullable ITransientNotification callback, int duration, int displayId, - @Nullable ITransientNotificationCallback textCallback) { + @Nullable ITransientNotification callback, int duration, boolean isUiContext, + int displayId, @Nullable ITransientNotificationCallback textCallback) { if (DBG) { Slog.i(TAG, "enqueueToast pkg=" + pkg + " token=" + token + " duration=" + duration + " displayId=" + displayId); @@ -3322,6 +3327,22 @@ public class NotificationManagerService extends SystemService { 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) { int callingPid = Binder.getCallingPid(); final long callingId = Binder.clearCallingIdentity(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 02c030d16f6a..be5a6d526b17 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -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.Ranking.USER_SENTIMENT_NEGATIVE; 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 com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING; @@ -278,7 +279,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; private static final String PKG_NO_CHANNELS = "com.example.no.channels"; 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 TestableNotificationManagerService mService; @@ -6539,8 +6541,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(1, mService.mToastQueue.size()); } @@ -6559,8 +6560,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(0, mService.mToastQueue.size()); } @@ -6583,12 +6583,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; // 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()); // second time trying to show the same toast, showToast isn't called again (total number of // invocations stays at one) - nmService.enqueueToast(testPackage, token, callback, 2000, 0); + enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); } @@ -6611,7 +6611,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; - nmService.enqueueToast(testPackage, token, callback, 2000, 0); + enqueueToast(nmService, testPackage, token, callback); verify(callback, times(1)).show(any()); } @@ -6636,8 +6636,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ITransientNotification callback2 = mock(ITransientNotification.class); INotificationManager nmService = (INotificationManager) mService.mService; - nmService.enqueueToast(testPackage, token1, callback1, 2000, 0); - nmService.enqueueToast(testPackage, token2, callback2, 2000, 0); + enqueueToast(nmService, testPackage, token1, callback1); + enqueueToast(nmService, testPackage, token2, callback2); assertEquals(2, mService.mToastQueue.size()); // Both toasts enqueued. verify(callback1, times(1)).show(any()); // First toast shown. @@ -6665,8 +6665,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), - "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); assertEquals(1, mService.mToastQueue.size()); } @@ -6685,8 +6684,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), - "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); assertEquals(1, mService.mToastQueue.size()); } @@ -6708,13 +6706,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INotificationManager nmService = (INotificationManager) mService.mService; // 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)) .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 // invocations stays at one) - nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } @@ -6736,7 +6734,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; - nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(0)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } @@ -6758,7 +6756,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; - nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); verify(mStatusBar, times(1)) .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } @@ -6779,7 +6777,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); 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(), anyInt()); } @@ -6800,7 +6798,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Binder token = new Binder(); INotificationManager nmService = (INotificationManager) mService.mService; - nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); // window token was added when enqueued ArgumentCaptor<Binder> binderCaptor = @@ -6836,8 +6834,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(true), any()); } @@ -6858,8 +6855,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, true); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), - "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } @@ -6880,8 +6876,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> toast should still enqueue - ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), - "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); assertEquals(1, mService.mToastQueue.size()); verify(mAm).setProcessImportant(any(), anyInt(), eq(false), any()); } @@ -6899,8 +6894,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(false); // enqueue toast -> no toasts enqueued - ((INotificationManager) mService.mService).enqueueTextToast(testPackage, new Binder(), - "Text", 2000, 0, null); + enqueueTextToast(testPackage, "Text"); verify(mStatusBar).showToast(anyInt(), any(), any(), any(), any(), anyInt(), any(), anyInt()); } @@ -6921,8 +6915,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); // enqueue toast -> no toasts enqueued - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(0, mService.mToastQueue.size()); } @@ -6944,8 +6937,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> no toasts enqueued - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(0, mService.mToastQueue.size()); } @@ -6967,8 +6959,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setAppInForegroundForToasts(mUid, false); // enqueue toast -> system toast can still be enqueued - ((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(), - new TestableToastCallback(), 2000, 0); + enqueueToast(testPackage, new TestableToastCallback()); assertEquals(1, mService.mToastQueue.size()); } @@ -6988,13 +6979,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Trying to quickly enqueue more toast than allowed. for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS + 1; i++) { - nmService.enqueueTextToast( - testPackage, - new Binder(), - "Text", - /* duration */ 2000, - /* displayId */ 0, - /* callback */ null); + enqueueTextToast(testPackage, "Text"); } // Only allowed number enqueued, rest ignored. assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); @@ -10718,4 +10703,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { String.valueOf(isOn), /* 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); + } } |