From ea92d977333bef11c6ab243d785a1b2d9c1f66ff Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Thu, 8 Dec 2016 07:33:13 -0800 Subject: [PATCH] Don't return null in WS.getTopParentWindow on child detach Fixed issue with WindowState.getTopParentWindow() returning null when the child window is removed from it's parent. In this case it should return itself as the method documentation states. Change-Id: Iae40ca21241306048cae136887afc88593a6898d Fixes: 33446267 Test: bit FrameworksServicesTests:com.android.server.wm.WindowStateTests --- .../com/android/server/wm/WindowState.java | 19 +++++++++++++------ .../android/server/wm/WindowStateTests.java | 5 +++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 5eab7950a529e..e2027fd8764bd 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2883,7 +2883,7 @@ class WindowState extends WindowContainer implements WindowManagerP mShowToOwnerOnly = showToOwnerOnly; } - boolean isHiddenFromUserLocked() { + private boolean isHiddenFromUserLocked() { // Child windows are evaluated based on their parent window. final WindowState win = getTopParentWindow(); if (win.mAttrs.type < FIRST_SYSTEM_WINDOW @@ -3552,16 +3552,23 @@ class WindowState extends WindowContainer implements WindowManagerP /** Returns the topmost parent window if this is a child of another window, else this. */ WindowState getTopParentWindow() { - WindowState w = this; - while (w != null && w.mIsChildWindow) { - w = w.getParentWindow(); + WindowState current = this; + WindowState topParent = current; + while (current != null && current.mIsChildWindow) { + current = current.getParentWindow(); + // Parent window can be null if the child is detached from it's parent already, but + // someone still has a reference to access it. So, we return the top parent value we + // already have instead of null. + if (current != null) { + topParent = current; + } } - return w; + return topParent; } boolean isParentWindowHidden() { final WindowState parent = getParentWindow(); - return (parent == null) ? false : parent.mHidden; + return parent != null && parent.mHidden; } void setWillReplaceWindow(boolean animate) { diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index 69bfc8fa471ba..df35b7eedaf63 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -116,6 +116,11 @@ public class WindowStateTests extends WindowTestsBase { assertEquals(root, child1.getTopParentWindow()); assertEquals(child1, child2.getParentWindow()); assertEquals(root, child2.getTopParentWindow()); + + // Test case were child is detached from parent. + root.removeChild(child1); + assertEquals(child1, child1.getTopParentWindow()); + assertEquals(child1, child2.getParentWindow()); } @Test