Loading core/java/android/view/Window.java +72 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading core/java/android/window/WindowContext.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,6 +69,8 @@ public class WindowContext extends ContextWrapper implements WindowProvider, private WindowManager mWindowManager; private Window mWindow; /** * Default implementation of {@link WindowContext} * <p> Loading Loading @@ -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 === */ Loading core/tests/coretests/src/android/window/WindowContextTest.java +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading Loading
core/java/android/view/Window.java +72 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
core/java/android/window/WindowContext.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,6 +69,8 @@ public class WindowContext extends ContextWrapper implements WindowProvider, private WindowManager mWindowManager; private Window mWindow; /** * Default implementation of {@link WindowContext} * <p> Loading Loading @@ -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 === */ Loading
core/tests/coretests/src/android/window/WindowContextTest.java +35 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading