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

Commit 30517800 authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Respect the hardware accelerated of ApplicationInfo" into main

parents fed9edc1 623d402b
Loading
Loading
Loading
Loading
+72 −6
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ import android.view.View.OnApplyWindowInsetsListener;
import android.view.accessibility.AccessibilityEvent;
import android.window.OnBackInvokedDispatcher;

import com.android.window.flags.Flags;

import java.util.Collections;
import java.util.List;

@@ -853,32 +855,96 @@ public abstract class Window {
    }

    /**
     * Set the window manager for use by this Window to, for example,
     * Creates and sets the window manager for use by this Window to, for example,
     * display panels.  This is <em>not</em> used for displaying the
     * Window itself -- that must be done by the client.
     * <p>
     * If {@code wm} is not {@code null}, this method will creates a new instance of
     * {@link WindowManager} with this window attached based on {@code wm}, or, otherwise,
     * based on {@link WindowManager} obtained from {@link #getContext()}.
     *
     * @param wm The window manager for adding new windows.
     * @param wm the window manager for adding new windows.
     * @param appToken the token of the window, which applies to
     *     the {@link WindowManager.LayoutParams#token} of {@link #getAttributes()} if specified.
     * @param appName the name of the window, which applies to
     *     the {@link WindowManager.LayoutParams#getTitle()} of {@link #getAttributes()}
     *     if specified.
     */
    public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {
        setWindowManager(wm, appToken, appName, false);
    }

    /**
     * Set the window manager for use by this Window to, for example,
     * Creates and sets the window manager for use by this Window to, for example,
     * display panels.  This is <em>not</em> used for displaying the
     * Window itself -- that must be done by the client.
     *
     * @param wm The window manager for adding new windows.
     * <p>
     * If {@code wm} is not {@code null}, this method will creates a new instance of
     * {@link WindowManager} with this window attached based on {@code wm}, or, otherwise,
     * based on {@link WindowManager} obtained from {@link #getContext()}.
     *
     * @param wm the window manager for adding new windows.
     * @param appToken the token of the window, which applies to
     *     the {@link WindowManager.LayoutParams#token} of {@link #getAttributes()} if specified.
     * @param appName the name of the window, which applies to
     *     the {@link WindowManager.LayoutParams#getTitle()} of {@link #getAttributes()}
     *     if specified.
     * @param hardwareAccelerated indicate whether this window or its sub-windows should be hardware
     *     accelerated, which is default to {@code false}.
     */
    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        setWindowManager(wm, appToken, appName, hardwareAccelerated, true /* createNewInstance */);
    }

    /**
     * Sets the window manager for use by this Window to, for example,
     * display panels.
     * <p>
     * If caller wants to create a new instance, this method will create a new instance of
     * {@link WindowManager} with this window attached based on {@code wm}, if specified, or
     * the {@link WindowManager} obtained from {@link #getContext()}.
     * <p>
     * Otherwise, this method attach this window via {@link WindowManager#setParentWindow} to either
     * provided {@code wm} or the {@link WindowManager} obtained from {@link #getContext()}.
     * <p>
     * This is <em>not</em> used for displaying the
     * Window itself -- that must be done by the client.
     *
     * @param wm the window manager for adding new windows.
     * @param appToken the token of the window, which applies to
     *     the {@link WindowManager.LayoutParams#token} of {@link #getAttributes()}
     *     if specified.
     * @param appName the name of the window, which applies to
     *     the {@link WindowManager.LayoutParams#getTitle()} of {@link #getAttributes()}
     *     if specified.
     * @param hardwareAccelerated indicate whether this window or its sub-windows should be hardware
     *     accelerated, which is default to {@code false}.
     * @param createLocalWindowManager indicate whether this window creates a new instance of
     *     {@link WindowManager} with this window attached, which is {@code true} by default.
     *
     * @hide
     */
    public void setWindowManager(
            @Nullable WindowManager wm,
            @Nullable IBinder appToken,
            @Nullable String appName,
            boolean hardwareAccelerated,
            boolean createLocalWindowManager) {
        // If the flag is not enabled, we can only create a new instance of WindowManager.
        createLocalWindowManager |= !Flags.enableWindowContextOverrideType();
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated;
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        if (createLocalWindowManager) {
            mWindowManager = wm.createLocalWindowManager(this);
        } else {
            mWindowManager = wm;
            wm.setParentWindow(this);
        }
    }

    void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
+27 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.ComponentCallbacks;
import android.content.ComponentCallbacksController;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Display;
@@ -68,6 +69,8 @@ public class WindowContext extends ContextWrapper implements WindowProvider,

    private WindowManager mWindowManager;

    private Window mWindow;

    /**
     * Default implementation of {@link WindowContext}
     * <p>
@@ -213,14 +216,35 @@ public class WindowContext extends ContextWrapper implements WindowProvider,
     * Associates {@code window} to this {@code WindowContext} and attach {@code window} to
     * associated {@link WindowManager}.
     * <p>
     * Note that this method must be called before {@link WindowManager#addView}.
     * Note that this method must be called before {@link WindowManager#addView} and
     * a {@code WindowContext} only can attach one {@code window}.
     * <p>
     * If there's a use case to attach another window, please {@link Context#createWindowContext}
     * instead.
     *
     * @param window the window to attach.
     * @throws IllegalStateException if window has been attached.
     */
    public void attachWindow(@NonNull View window) {
        if (!Flags.enableWindowContextOverrideType()) {
            return;
        }
        final Window wrapper = new WindowWrapper(this, window);
        ((WindowManagerImpl) mWindowManager).setParentWindow(wrapper);
        if (mWindow != null) {
            throw new IllegalStateException(
                    "This WindowContext has already attached a window. Window=" + mWindow
                    + " Please create another WindowContext if you want to attach another window."
            );
        }
        mWindow = new WindowWrapper(this, window);
        final boolean hardwareAccelerated =
                (getApplicationInfo().flags & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0;
        mWindow.setWindowManager(
                mWindowManager,
                getWindowContextToken(),
                null /* appName */,
                hardwareAccelerated,
                false /* createLocalWindowManager */
        );
    }

/* === WindowProvider APIs === */
+35 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
@@ -75,6 +76,8 @@ import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;

import com.android.frameworks.coretests.R;
import com.android.internal.jank.Cuj;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.util.GcUtils;
import com.android.window.flags.Flags;

@@ -517,6 +520,38 @@ public class WindowContextTest {
        assertThat(params.type).isEqualTo(TYPE_APPLICATION_OVERLAY);
    }

    @EnableFlags(Flags.FLAG_ENABLE_WINDOW_CONTEXT_OVERRIDE_TYPE)
    @Test
    public void testBuildInteractionJankMonitorConfigWithWindowAttached_notCrash() {
        final ApplicationInfo appInfo = mWindowContext.getApplicationInfo();
        // Enable hardware accelerated to initialize thread renderer, which is essential to
        // build InteractionJankMonitor Configuration
        final int origFlags = appInfo.flags;
        appInfo.flags |= ApplicationInfo.FLAG_HARDWARE_ACCELERATED;
        try {
            final View window = new View(mWindowContext);
            final AttachStateListener listener = new AttachStateListener();
            window.addOnAttachStateChangeListener(listener);

            final WindowManager wm = mWindowContext.getSystemService(WindowManager.class);
            mWindowContext.attachWindow(window);

            mInstrumentation.runOnMainSync(() ->
                    wm.addView(window, new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY)));

            try {
                assertTrue(listener.mLatch.await(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS));
            } catch (InterruptedException e) {
                fail("Fail due to " + e);
            }

            assertThat(InteractionJankMonitor.Configuration.Builder.withView(
                    Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, window).build()).isNotNull();
        } finally {
            appInfo.flags = origFlags;
        }
    }

    private WindowContext createWindowContext() {
        return createWindowContext(TYPE_APPLICATION_OVERLAY);
    }