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

Commit 25704b6a authored by Charles Chen's avatar Charles Chen
Browse files

Fix VirtualDisplayTest failures

The failures are due to legacy behaviors in the test, which includes:
1. Use Toast without managed token
2. Show presentation on the default display

Currently, we need a managed window token for toast, and also the
display to show preentation should be a presentation display.
A built-in display isn't a presentation display by default.

In this CL, we
1. Use the default window type for Presentation
2. Use fullscreen overlay dialog on the default display
to fix this test

Bug: 223843046
Test: atest VirtualDisplayTest

Change-Id: Ifa790a3436ed487f4af79296e47a900d62cea375
parent ad724202
Loading
Loading
Loading
Loading
+86 −56
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package android.hardware.display;

import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.annotation.ColorInt;
import android.app.Dialog;
import android.app.Presentation;
import android.content.Context;
import android.graphics.Color;
@@ -33,8 +37,11 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams.Flags;
import android.widget.ImageView;

import androidx.test.filters.LargeTest;
@@ -110,7 +117,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
     * Ensures that an application can create a private virtual display and show
     * its own windows on it.
     */
    public void testPrivateVirtualDisplay() throws Exception {
    public void testPrivateVirtualDisplay() {
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
                WIDTH, HEIGHT, DENSITY, mSurface, 0);
        assertNotNull("virtual display must not be null", virtualDisplay);
@@ -120,9 +127,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
            assertDisplayRegistered(display, Display.FLAG_PRIVATE);

            // Show a private presentation on the display.
            assertDisplayCanShowPresentation("private presentation window",
                    display, BLUEISH,
                    WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, 0);
            assertDisplayCanShowPresentation("private presentation window", display, BLUEISH, 0);
        } finally {
            virtualDisplay.release();
        }
@@ -133,10 +138,9 @@ public class VirtualDisplayTest extends AndroidTestCase {
     * Ensures that an application can create a private presentation virtual display and show
     * its own windows on it.
     */
    public void testPrivatePresentationVirtualDisplay() throws Exception {
    public void testPrivatePresentationVirtualDisplay() {
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
                WIDTH, HEIGHT, DENSITY, mSurface,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);
                WIDTH, HEIGHT, DENSITY, mSurface, DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);
        assertNotNull("virtual display must not be null", virtualDisplay);

        Display display = virtualDisplay.getDisplay();
@@ -144,9 +148,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
            assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION);

            // Show a private presentation on the display.
            assertDisplayCanShowPresentation("private presentation window",
                    display, BLUEISH,
                    WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, 0);
            assertDisplayCanShowPresentation("private presentation window", display, BLUEISH, 0);
        } finally {
            virtualDisplay.release();
        }
@@ -161,7 +163,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
     * type to create the window.  Another choice might be SYSTEM_ALERT_WINDOW but
     * that requires a permission.
     */
    public void testPublicPresentationVirtualDisplay() throws Exception {
    public void testPublicPresentationVirtualDisplay() {
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
                WIDTH, HEIGHT, DENSITY, mSurface,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
@@ -177,29 +179,22 @@ public class VirtualDisplayTest extends AndroidTestCase {
            // virtual display automatically.
            Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
            assertDisplayCanShowPresentation("mirrored window",
                    defaultDisplay, GREENISH,
                    WindowManager.LayoutParams.TYPE_TOAST, 0);
                    defaultDisplay, GREENISH, 0);

            // Mirroring case with secure window (but display is not secure).
            // Show a window on the default display.  It should be replaced with black on
            // the virtual display.
            assertDisplayCanShowPresentation("mirrored secure window on non-secure display",
                    defaultDisplay, Color.BLACK,
                    WindowManager.LayoutParams.TYPE_TOAST,
                    WindowManager.LayoutParams.FLAG_SECURE);
                    defaultDisplay, Color.BLACK, WindowManager.LayoutParams.FLAG_SECURE);

            // Presentation case.
            // Show a normal presentation on the display.
            assertDisplayCanShowPresentation("presentation window",
                    display, BLUEISH,
                    WindowManager.LayoutParams.TYPE_TOAST, 0);
            assertDisplayCanShowPresentation("presentation window", display, BLUEISH, 0);

            // Presentation case with secure window (but display is not secure).
            // Show a normal presentation on the display.  It should be replaced with black.
            assertDisplayCanShowPresentation("secure presentation window on non-secure display",
                    display, Color.BLACK,
                    WindowManager.LayoutParams.TYPE_TOAST,
                    WindowManager.LayoutParams.FLAG_SECURE);
                    display, Color.BLACK, WindowManager.LayoutParams.FLAG_SECURE);
        } finally {
            virtualDisplay.release();
        }
@@ -214,7 +209,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
     * type to create the window.  Another choice might be SYSTEM_ALERT_WINDOW but
     * that requires a permission.
     */
    public void testSecurePublicPresentationVirtualDisplay() throws Exception {
    public void testSecurePublicPresentationVirtualDisplay() {
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
                WIDTH, HEIGHT, DENSITY, mSurface,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE
@@ -231,16 +226,12 @@ public class VirtualDisplayTest extends AndroidTestCase {
            // virtual display automatically.
            Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
            assertDisplayCanShowPresentation("mirrored secure window on secure display",
                    defaultDisplay, GREENISH,
                    WindowManager.LayoutParams.TYPE_TOAST,
                    WindowManager.LayoutParams.FLAG_SECURE);
                    defaultDisplay, GREENISH, WindowManager.LayoutParams.FLAG_SECURE);

            // Presentation case with secure window (and display is secure).
            // Show a normal presentation on the display.
            assertDisplayCanShowPresentation("secure presentation window on secure display",
                    display, BLUEISH,
                    WindowManager.LayoutParams.TYPE_TOAST,
                    WindowManager.LayoutParams.FLAG_SECURE);
                    display, BLUEISH, WindowManager.LayoutParams.FLAG_SECURE);
        } finally {
            virtualDisplay.release();
        }
@@ -251,7 +242,7 @@ public class VirtualDisplayTest extends AndroidTestCase {
     * Ensures that an application can create a trusted virtual display with the permission
     * {@code ADD_TRUSTED_DISPLAY}.
     */
    public void testTrustedVirtualDisplay() throws Exception {
    public void testTrustedVirtualDisplay() {
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
                WIDTH, HEIGHT, DENSITY, mSurface,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED);
@@ -299,35 +290,43 @@ public class VirtualDisplayTest extends AndroidTestCase {
        assertFalse("display must no longer be valid", display.isValid());
    }

    /**
     * Verifies that virtual display shows the expected {@code color}.
     * <p>
     * If {@code display} is the {@link Display#DEFAULT_DISPLAY default display}, show a fullscreen
     * overlay {@link Dialog} on the default display and verify if the dialog is mirrored to the
     * virtual display.
     * </p><p>
     * If {@code display} is a {@link VirtualDisplay}, show a {@link Presentation} on that virtual
     * display and verify the content.
     * </p>
     */
    private void assertDisplayCanShowPresentation(String message, final Display display,
            final int color, final int windowType, final int windowFlags) {
            @ColorInt final int color, @Flags final int windowFlags) {
        // At this point, we should not have seen any blue.
        assertTrue(message + ": display should not show content before window is shown",
                mImageListener.getColor() != color);

        final TestPresentation[] presentation = new TestPresentation[1];
        final Dialog[] dialogs = new Dialog[1];
        try {
            // Show the presentation.
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    presentation[0] = new TestPresentation(getContext(), display,
                            color, windowType, windowFlags);
                    presentation[0].show();
            runOnUiThread(() -> {
                if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
                    final Context windowContext = getContext().createWindowContext(display,
                            TYPE_APPLICATION_OVERLAY, null /* options */);
                    dialogs[0] = new TestDialog(windowContext, color, windowFlags);
                } else {
                    dialogs[0] = new TestPresentation(getContext(), display, color, windowFlags);
                }
                dialogs[0].show();
            });

            // Wait for the blue to be seen.
            // Wait for the color to be seen.
            assertTrue(message + ": display should show content after window is shown",
                    mImageListener.waitForColor(color, TIMEOUT));
        } finally {
            if (presentation[0] != null) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        presentation[0].dismiss();
                    }
                });
            if (dialogs[0] != null) {
                runOnUiThread(() -> dialogs[0].dismiss());
            }
        }
    }
@@ -360,13 +359,15 @@ public class VirtualDisplayTest extends AndroidTestCase {
        return null;
    }

    private final class TestPresentation extends Presentation {
    private static final class TestPresentation extends Presentation {
        @ColorInt
        private final int mColor;
        @Flags
        private final int mWindowFlags;

        public TestPresentation(Context context, Display display,
                int color, int windowType, int windowFlags) {
            super(context, display, 0 /* theme */, windowType);
        TestPresentation(Context context, Display display, @ColorInt int color,
                @Flags int windowFlags) {
            super(context, display);
            mColor = color;
            mWindowFlags = windowFlags;
        }
@@ -378,13 +379,42 @@ public class VirtualDisplayTest extends AndroidTestCase {
            setTitle(TAG);
            getWindow().addFlags(mWindowFlags);

            setContentView(createImageView(getContext(), mColor));
        }
    }

    private static final class TestDialog extends Dialog {
        @ColorInt
        private final int mColor;
        @Flags
        private final int mWindowFlags;

        TestDialog(Context context, @ColorInt int color, @Flags int windowFlags) {
            super(context, android.R.style.Theme_Material_NoActionBar_Fullscreen);
            mColor = color;
            mWindowFlags = windowFlags;
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            setTitle(TAG);
            final Window window = getWindow();
            window.setType(TYPE_APPLICATION_OVERLAY);
            window.addFlags(mWindowFlags);

            setContentView(createImageView(getContext(), mColor));
        }
    }

    private static View createImageView(Context context, @ColorInt int color) {
        // Create a solid color image to use as the content of the presentation.
            ImageView view = new ImageView(getContext());
            view.setImageDrawable(new ColorDrawable(mColor));
        ImageView view = new ImageView(context);
        view.setImageDrawable(new ColorDrawable(color));
        view.setLayoutParams(new LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
            setContentView(view);
        }
        return view;
    }

    /**