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

Commit 78f5d83a authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Wire user info and use user context for text toasts

Text toasts don't currently support multi-user. This CL prepares toasts
for multi-user by wiring the user information from who requested the
toast (in the form of uid) to ToastUI, where text toasts are actually
rendered.

We go only as far as obtaining a new user-specific context for that user
and using that to construct the view. Actual support will come in future
CLs.

Bug: 151414297
Test: atest android.widget.cts29.ToastTest android.widget.cts.ToastTest
      ToastWindowTest ToastUITest NotificationManagerServiceTest
      LegacyToastTest
Change-Id: I8c92453c6a2b73c31f9a41ca9ff463d194d4f44f
parent d58849ab
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ import android.os.ServiceManager;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;

import com.android.internal.annotations.GuardedBy;

@@ -610,10 +610,10 @@ public class Toast {
         */
        TN(Context context, String packageName, Binder token, List<Callback> callbacks,
                @Nullable Looper looper) {
            WindowManager windowManager = context.getSystemService(WindowManager.class);
            AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(context);
            mPresenter = new ToastPresenter(context, windowManager, accessibilityManager,
                    getService(), packageName);
            IAccessibilityManager accessibilityManager = IAccessibilityManager.Stub.asInterface(
                    ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
            mPresenter = new ToastPresenter(context, accessibilityManager, getService(),
                    packageName);
            mParams = mPresenter.getLayoutParams();
            mPackageName = packageName;
            mToken = token;
+19 −6
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -34,8 +35,10 @@ import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;

/**
@@ -49,12 +52,14 @@ public class ToastPresenter {
    private static final long SHORT_DURATION_TIMEOUT = 4000;
    private static final long LONG_DURATION_TIMEOUT = 7000;

    @VisibleForTesting
    public static final int TEXT_TOAST_LAYOUT = R.layout.transient_notification;

    /**
     * Returns the default text toast view for message {@code text}.
     */
    public static View getTextToastView(Context context, CharSequence text) {
        View view = LayoutInflater.from(context).inflate(
                R.layout.transient_notification, null);
        View view = LayoutInflater.from(context).inflate(TEXT_TOAST_LAYOUT, null);
        TextView textView = view.findViewById(com.android.internal.R.id.message);
        textView.setText(text);
        return view;
@@ -70,15 +75,23 @@ public class ToastPresenter {
    @Nullable private View mView;
    @Nullable private IBinder mToken;

    public ToastPresenter(Context context, WindowManager windowManager,
            AccessibilityManager accessibilityManager,
    public ToastPresenter(Context context, IAccessibilityManager accessibilityManager,
            INotificationManager notificationManager, String packageName) {
        mContext = context;
        mResources = context.getResources();
        mWindowManager = windowManager;
        mAccessibilityManager = accessibilityManager;
        mWindowManager = context.getSystemService(WindowManager.class);
        mNotificationManager = notificationManager;
        mPackageName = packageName;

        // We obtain AccessibilityManager manually via its constructor instead of using method
        // AccessibilityManager.getInstance() for 2 reasons:
        //   1. We want to be able to inject IAccessibilityManager in tests to verify behavior.
        //   2. getInstance() caches the instance for the process even if we pass a different
        //      context to it. This is problematic for multi-user because callers can pass a context
        //      created via Context.createContextAsUser().
        mAccessibilityManager = new AccessibilityManager(context, accessibilityManager,
                UserHandle.getCallingUserId());

        mParams = createLayoutParams();
    }

+2 −2
Original line number Diff line number Diff line
@@ -204,8 +204,8 @@ oneway interface IStatusBar
    /**
     * Displays a text toast.
     */
    void showToast(String packageName, IBinder token, CharSequence text, IBinder windowToken,
            int duration, @nullable ITransientNotificationCallback callback);
    void showToast(int uid, String packageName, IBinder token, CharSequence text,
            IBinder windowToken, int duration, @nullable ITransientNotificationCallback callback);

    /**
     * Cancels toast with token {@code token} in {@code packageName}.
+8 −6
Original line number Diff line number Diff line
@@ -322,10 +322,10 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
        default void suppressAmbientDisplay(boolean suppress) { }

        /**
         * @see IStatusBar#showToast(String, IBinder, CharSequence, IBinder, int,
         * @see IStatusBar#showToast(int, String, IBinder, CharSequence, IBinder, int,
         * ITransientNotificationCallback)
         */
        default void showToast(String packageName, IBinder token, CharSequence text,
        default void showToast(int uid, String packageName, IBinder token, CharSequence text,
                IBinder windowToken, int duration,
                @Nullable ITransientNotificationCallback callback) { }

@@ -798,7 +798,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
    }

    @Override
    public void showToast(String packageName, IBinder token, CharSequence text,
    public void showToast(int uid, String packageName, IBinder token, CharSequence text,
            IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback) {
        synchronized (mLock) {
            SomeArgs args = SomeArgs.obtain();
@@ -807,7 +807,8 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
            args.arg3 = text;
            args.arg4 = windowToken;
            args.arg5 = callback;
            args.argi1 = duration;
            args.argi1 = uid;
            args.argi2 = duration;
            mHandler.obtainMessage(MSG_SHOW_TOAST, args).sendToTarget();
        }
    }
@@ -1276,9 +1277,10 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
                    IBinder windowToken = (IBinder) args.arg4;
                    ITransientNotificationCallback callback =
                            (ITransientNotificationCallback) args.arg5;
                    int duration = args.argi1;
                    int uid = args.argi1;
                    int duration = args.argi2;
                    for (Callbacks callbacks : mCallbacks) {
                        callbacks.showToast(packageName, token, text, windowToken, duration,
                        callbacks.showToast(uid, packageName, token, text, windowToken, duration,
                                callback);
                    }
                    break;
+12 −13
Original line number Diff line number Diff line
@@ -24,10 +24,10 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;
import android.widget.ToastPresenter;

import com.android.internal.R;
@@ -48,9 +48,8 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks {
    private static final String TAG = "ToastUI";

    private final CommandQueue mCommandQueue;
    private final WindowManager mWindowManager;
    private final INotificationManager mNotificationManager;
    private final AccessibilityManager mAccessibilityManager;
    private final IAccessibilityManager mAccessibilityManager;
    private final int mGravity;
    private final int mY;
    @Nullable private ToastPresenter mPresenter;
@@ -59,18 +58,17 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks {
    @Inject
    public ToastUI(Context context, CommandQueue commandQueue) {
        this(context, commandQueue,
                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE),
                INotificationManager.Stub.asInterface(
                        ServiceManager.getService(Context.NOTIFICATION_SERVICE)),
                AccessibilityManager.getInstance(context));
                IAccessibilityManager.Stub.asInterface(
                        ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)));
    }

    @VisibleForTesting
    ToastUI(Context context, CommandQueue commandQueue, WindowManager windowManager,
            INotificationManager notificationManager, AccessibilityManager accessibilityManager) {
    ToastUI(Context context, CommandQueue commandQueue, INotificationManager notificationManager,
            @Nullable IAccessibilityManager accessibilityManager) {
        super(context);
        mCommandQueue = commandQueue;
        mWindowManager = windowManager;
        mNotificationManager = notificationManager;
        mAccessibilityManager = accessibilityManager;
        Resources resources = mContext.getResources();
@@ -85,15 +83,16 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks {

    @Override
    @MainThread
    public void showToast(String packageName, IBinder token, CharSequence text,
    public void showToast(int uid, String packageName, IBinder token, CharSequence text,
            IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback) {
        if (mPresenter != null) {
            hideCurrentToast();
        }
        View view = ToastPresenter.getTextToastView(mContext, text);
        Context context = mContext.createContextAsUser(UserHandle.getUserHandleForUid(uid), 0);
        View view = ToastPresenter.getTextToastView(context, text);
        mCallback = callback;
        mPresenter = new ToastPresenter(mContext, mWindowManager, mAccessibilityManager,
                mNotificationManager, packageName);
        mPresenter = new ToastPresenter(context, mAccessibilityManager, mNotificationManager,
                packageName);
        mPresenter.show(view, token, windowToken, duration, mGravity, 0, mY, 0, 0, mCallback);
    }

Loading