diff options
5 files changed, 50 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index edd3a3b073e4..80092074bc29 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -58,26 +58,25 @@ import java.io.PrintWriter; * This class represents an active client session. There is generally one * Session object per process that is interacting with the window manager. */ -final class Session extends IWindowSession.Stub +// Needs to be public and not final so we can mock during tests...sucks I know :( +public class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { final WindowManagerService mService; final IWindowSessionCallback mCallback; final IInputMethodClient mClient; - final IInputContext mInputContext; final int mUid; final int mPid; - final String mStringName; + private final String mStringName; SurfaceSession mSurfaceSession; - int mNumWindow = 0; - boolean mClientDead = false; - float mLastReportedAnimatorScale; + private int mNumWindow = 0; + private boolean mClientDead = false; + private float mLastReportedAnimatorScale; public Session(WindowManagerService service, IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { mService = service; mCallback = callback; mClient = client; - mInputContext = inputContext; mUid = Binder.getCallingUid(); mPid = Binder.getCallingPid(); mLastReportedAnimatorScale = service.getCurrentAnimatorScale(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b90dc93c41bd..2b5603dedc5a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -974,8 +974,13 @@ public class WindowManagerService extends IWindowManager.Stub LocalServices.addService(WindowManagerPolicy.class, mPolicy); - mPointerEventDispatcher = mInputManager != null - ? new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM)) : null; + if(mInputManager != null) { + final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM); + mPointerEventDispatcher = inputChannel != null + ? new PointerEventDispatcher(inputChannel) : null; + } else { + mPointerEventDispatcher = null; + } mFxSession = new SurfaceSession(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index afaaeb9adef7..862e8f02eaf7 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -427,11 +427,13 @@ class WindowToken extends WindowContainer<WindowState> { @Override void removeImmediately() { - super.removeImmediately(); if (mDisplayContent != null) { mDisplayContent.removeWindowToken(token); mService.mRoot.removeWindowTokenIfPossible(token); } + // Needs to occur after the token is removed from the display above to avoid attempt at + // duplicate removal of this window container from it's parent. + super.removeImmediately(); } void onDisplayChanged(DisplayContent dc) { diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java index fee47831bb0c..03cbb43f2ecb 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -17,6 +17,7 @@ package com.android.server.wm; import com.android.internal.policy.IShortcutService; +import com.android.server.input.InputManagerService; import android.content.Context; import android.content.res.CompatibilityInfo; @@ -79,7 +80,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STA import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -public class TestWindowManagerPolicy implements WindowManagerPolicy { +import static org.mockito.Mockito.mock; + +class TestWindowManagerPolicy implements WindowManagerPolicy { private static final String TAG = "TestWindowManagerPolicy"; private static WindowManagerService sWm = null; @@ -88,8 +91,8 @@ public class TestWindowManagerPolicy implements WindowManagerPolicy { if (sWm == null) { // We only want to do this once for the test process as we don't want WM to try to // register a bunch of local services again. - sWm = WindowManagerService.main( - context, null, true, false, false, new TestWindowManagerPolicy()); + sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false, + false, new TestWindowManagerPolicy()); } return sWm; } diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java index 1a4dff9c0c07..546c7da0a013 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java @@ -21,6 +21,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import android.content.Context; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -28,12 +29,14 @@ import android.support.test.runner.AndroidJUnit4; import android.view.IWindow; import android.view.WindowManager; +import static android.app.AppOpsManager.OP_NONE; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; /** * Tests for the {@link WindowState} class. @@ -49,6 +52,7 @@ public class WindowTokenTests { private WindowManagerService mWm = null; private final IWindow mIWindow = new TestIWindow(); + private final Session mMockSession = mock(Session.class); @Before public void setUp() throws Exception { @@ -86,6 +90,28 @@ public class WindowTokenTests { } @Test + public void testChildRemoval() throws Exception { + final TestWindowToken token = new TestWindowToken(); + final DisplayContent dc = mWm.getDefaultDisplayContentLocked(); + + assertEquals(token, dc.getWindowToken(token.token)); + + final WindowState window1 = createWindow(null, TYPE_APPLICATION, token); + final WindowState window2 = createWindow(null, TYPE_APPLICATION, token); + token.addWindow(window1); + token.addWindow(window2); + + window2.removeImmediately(); + // The token should still be mapped in the display content since it still has a child. + assertEquals(token, dc.getWindowToken(token.token)); + + window1.removeImmediately(); + // The token should have been removed from the display content since it no longer has a + // child. + assertEquals(null, dc.getWindowToken(token.token)); + } + + @Test public void testAdjustAnimLayer() throws Exception { final TestWindowToken token = new TestWindowToken(); final WindowState window1 = createWindow(null, TYPE_APPLICATION, token); @@ -157,14 +183,14 @@ public class WindowTokenTests { private WindowState createWindow(WindowState parent, int type, WindowToken token) { final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type); - return new WindowState(mWm, null, mIWindow, token, parent, 0, 0, attrs, 0, 0); + return new WindowState(mWm, mMockSession, mIWindow, token, parent, OP_NONE, 0, attrs, 0, 0); } /* Used so we can gain access to some protected members of the {@link WindowToken} class */ private class TestWindowToken extends WindowToken { TestWindowToken() { - super(mWm, null, 0, false, mWm.getDefaultDisplayContentLocked()); + super(mWm, mock(IBinder.class), 0, false, mWm.getDefaultDisplayContentLocked()); } int getWindowsCount() { |