Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc952dca authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Fixes Toast.show() for visible background users." into udc-dev

parents dce3abf8 0d4546d1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);

+5 −3
Original line number Diff line number Diff line
@@ -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
+27 −6
Original line number Diff line number Diff line
@@ -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();
+42 −41
Original line number Diff line number Diff line
@@ -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);
    }
}