diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java index 17b675f93f86b..5007df574ec1c 100644 --- a/core/java/android/window/WindowContextController.java +++ b/core/java/android/window/WindowContextController.java @@ -16,16 +16,22 @@ package android.window; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.Bundle; import android.os.IBinder; +import android.util.Log; import android.view.IWindowManager; import android.view.WindowManager.LayoutParams.WindowType; import com.android.internal.annotations.VisibleForTesting; +import java.lang.annotation.Retention; + /** * The controller to manage {@link WindowContext}, such as attaching to a window manager node or * detaching from the current attached node. The user must call @@ -35,13 +41,43 @@ import com.android.internal.annotations.VisibleForTesting; * @hide */ public class WindowContextController { + // TODO(220049234): Disable attach debug logging before shipping. + private static final boolean DEBUG_ATTACH = true; + private static final String TAG = "WindowContextController"; + /** - * {@code true} to indicate that the {@code mToken} is associated with a + * {@link AttachStatus.STATUS_ATTACHED} to indicate that the {@code mToken} is associated with a * {@link com.android.server.wm.DisplayArea}. Note that {@code mToken} is able to attach a - * WindowToken after this flag sets to {@code true}. + * WindowToken after this flag sets to {@link AttachStatus.STATUS_ATTACHED}. */ @VisibleForTesting - public boolean mAttachedToDisplayArea; + public int mAttachedToDisplayArea = AttachStatus.STATUS_INITIALIZED; + + /** + * Status to indicate that the Window Context attach to a + * {@link com.android.server.wm.DisplayArea}. + */ + @Retention(SOURCE) + @IntDef({AttachStatus.STATUS_INITIALIZED, AttachStatus.STATUS_ATTACHED, + AttachStatus.STATUS_DETACHED, AttachStatus.STATUS_FAILED}) + public @interface AttachStatus{ + /** + * The Window Context haven't attached to a {@link com.android.server.wm.DisplayArea}. + */ + int STATUS_INITIALIZED = 0; + /** + * The Window Context has already attached to a {@link com.android.server.wm.DisplayArea}. + */ + int STATUS_ATTACHED = 1; + /** + * The Window Context has detached from a {@link com.android.server.wm.DisplayArea}. + */ + int STATUS_DETACHED = 2; + /** + * The Window Context fails to attach to a {@link com.android.server.wm.DisplayArea}. + */ + int STATUS_FAILED = 3; + } @NonNull private final WindowTokenClient mToken; @@ -65,11 +101,19 @@ public class WindowContextController { * DisplayArea. */ public void attachToDisplayArea(@WindowType int type, int displayId, @Nullable Bundle options) { - if (mAttachedToDisplayArea) { + if (mAttachedToDisplayArea == AttachStatus.STATUS_ATTACHED) { throw new IllegalStateException("A Window Context can be only attached to " + "a DisplayArea once."); } - mAttachedToDisplayArea = mToken.attachToDisplayArea(type, displayId, options); + mAttachedToDisplayArea = mToken.attachToDisplayArea(type, displayId, options) + ? AttachStatus.STATUS_ATTACHED : AttachStatus.STATUS_FAILED; + if (mAttachedToDisplayArea == AttachStatus.STATUS_FAILED) { + Log.w(TAG, "attachToDisplayArea fail, type:" + type + ", displayId:" + + displayId); + } else if (DEBUG_ATTACH) { + Log.d(TAG, "attachToDisplayArea success, type:" + type + ", displayId:" + + displayId); + } } /** @@ -93,18 +137,21 @@ public class WindowContextController { * @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder) */ public void attachToWindowToken(IBinder windowToken) { - if (!mAttachedToDisplayArea) { + if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) { throw new IllegalStateException("The Window Context should have been attached" - + " to a DisplayArea."); + + " to a DisplayArea. AttachToDisplayArea:" + mAttachedToDisplayArea); } mToken.attachToWindowToken(windowToken); } /** Detaches the window context from the node it's currently associated with. */ public void detachIfNeeded() { - if (mAttachedToDisplayArea) { + if (mAttachedToDisplayArea == AttachStatus.STATUS_ATTACHED) { mToken.detachFromWindowContainerIfNeeded(); - mAttachedToDisplayArea = false; + mAttachedToDisplayArea = AttachStatus.STATUS_DETACHED; + if (DEBUG_ATTACH) { + Log.d(TAG, "Detach Window Context."); + } } } } diff --git a/core/tests/coretests/src/android/window/WindowContextControllerTest.java b/core/tests/coretests/src/android/window/WindowContextControllerTest.java index 52cb9f318dd09..a52d2e88145fd 100644 --- a/core/tests/coretests/src/android/window/WindowContextControllerTest.java +++ b/core/tests/coretests/src/android/window/WindowContextControllerTest.java @@ -86,11 +86,13 @@ public class WindowContextControllerTest { mController.attachToDisplayArea(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY, null /* options */); - assertThat(mController.mAttachedToDisplayArea).isTrue(); + assertThat(mController.mAttachedToDisplayArea).isEqualTo( + WindowContextController.AttachStatus.STATUS_ATTACHED); mController.detachIfNeeded(); - assertThat(mController.mAttachedToDisplayArea).isFalse(); + assertThat(mController.mAttachedToDisplayArea).isEqualTo( + WindowContextController.AttachStatus.STATUS_DETACHED); } @Test(expected = IllegalStateException.class)