diff options
| author | Vishnu Nair <vishnun@google.com> | 2019-11-07 15:33:20 -0800 |
|---|---|---|
| committer | Vishnu Nair <vishnun@google.com> | 2019-11-07 15:54:27 -0800 |
| commit | 5cf25319775616f88d59768bd9dd0753afd0359f (patch) | |
| tree | 68482078dd710dab7c5f07a6ec9d9c56cabb8f74 /core/java/android/view | |
| parent | f8a289110576dcff9c7486d8e4f80a85d9786f23 (diff) | |
Update input policy to handle embedded windows
ANR - If embedded windows are slow in handling inputs the system should blame the embedded app.
PointerDownOutsideFocus - if a user taps outside the currently focused window onto an
embedded window, treat it as if the host window was tapped.
Rename blessInputSurface -> grantInputChannel and add a name to embedded windows.
Bug: 134365580
Test: b WindowlessWmTest
Test: atest CtsWindowManagerDeviceTestCases:WindowlessWmTests
Change-Id: If88970cf6ce17669b41fec995535151a492fab12
Diffstat (limited to 'core/java/android/view')
| -rw-r--r-- | core/java/android/view/IWindowSession.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/view/InputApplicationHandle.java | 8 | ||||
| -rw-r--r-- | core/java/android/view/InputEventReceiver.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 16 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 15 | ||||
| -rw-r--r-- | core/java/android/view/WindowlessViewRoot.java | 24 | ||||
| -rw-r--r-- | core/java/android/view/WindowlessWindowManager.java | 32 |
7 files changed, 82 insertions, 27 deletions
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 6ce5ac4197ea..eaf6fca1b91f 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -314,5 +314,6 @@ interface IWindowSession { * Request the server to call setInputWindowInfo on a given Surface, and return * an input channel where the client can receive input. */ - void blessInputSurface(int displayId, in SurfaceControl surface, out InputChannel outInputChannel); + void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window, + in IBinder hostInputToken, out InputChannel outInputChannel); } diff --git a/core/java/android/view/InputApplicationHandle.java b/core/java/android/view/InputApplicationHandle.java index 5f6bc2352131..3d05e2a0b9f6 100644 --- a/core/java/android/view/InputApplicationHandle.java +++ b/core/java/android/view/InputApplicationHandle.java @@ -36,7 +36,7 @@ public final class InputApplicationHandle { // Dispatching timeout. public long dispatchingTimeoutNanos; - public IBinder token; + public final IBinder token; private native void nativeDispose(); @@ -44,6 +44,12 @@ public final class InputApplicationHandle { this.token = token; } + public InputApplicationHandle(InputApplicationHandle handle) { + this.token = handle.token; + this.dispatchingTimeoutNanos = handle.dispatchingTimeoutNanos; + this.name = handle.name; + } + @Override protected void finalize() throws Throwable { try { diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index ed8492e482c7..3080b42e81ce 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -17,6 +17,7 @@ package android.view; import android.annotation.UnsupportedAppUsage; +import android.os.IBinder; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -184,6 +185,16 @@ public abstract class InputEventReceiver { return false; } + /** + * @return Returns a token to identify the input channel. + */ + public IBinder getToken() { + if (mInputChannel == null) { + return null; + } + return mInputChannel.getToken(); + } + // Called from native code. @SuppressWarnings("unused") @UnsupportedAppUsage diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 59e9ed1512ee..0b5af2d01349 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -20,6 +20,8 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLA import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER; import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER; +import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.CompatibilityInfo.Translator; @@ -34,6 +36,7 @@ import android.graphics.Region; import android.graphics.RenderNode; import android.os.Build; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; import android.util.AttributeSet; @@ -1444,6 +1447,19 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } /** + * @return The token used to identify the windows input channel. + * @hide + */ + @TestApi + public @Nullable IBinder getInputToken() { + final ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot == null) { + return null; + } + return viewRoot.getInputToken(); + } + + /** * Set window stopped to false and update surface visibility when ViewRootImpl surface is * created. * @hide diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 85bf19f855bb..97adaf57f9b4 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -69,6 +69,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; @@ -1661,7 +1662,7 @@ public final class ViewRootImpl implements ViewParent, return mBlastBufferQueue.getSurface(); } - + private void setBoundsLayerCrop() { // mWinFrame is already adjusted for surface insets. So offset it and use it as // the cropping bounds. @@ -7179,7 +7180,7 @@ public final class ViewRootImpl implements ViewParent, if (mSurfaceControl.isValid()) { if (USE_BLAST_BUFFERQUEUE == false) { mSurface.copyFrom(mSurfaceControl); - } else { + } else { mSurface.transferFrom(getOrCreateBLASTSurface( (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f))); @@ -8932,6 +8933,16 @@ public final class ViewRootImpl implements ViewParent, } /** + * @return Returns a token used to identify the windows input channel. + */ + public IBinder getInputToken() { + if (mInputEventReceiver == null) { + return null; + } + return mInputEventReceiver.getToken(); + } + + /** * Class for managing the accessibility interaction connection * based on the global accessibility state. */ diff --git a/core/java/android/view/WindowlessViewRoot.java b/core/java/android/view/WindowlessViewRoot.java index c2500b89073e..addf8e242e3d 100644 --- a/core/java/android/view/WindowlessViewRoot.java +++ b/core/java/android/view/WindowlessViewRoot.java @@ -16,12 +16,11 @@ package android.view; -import android.content.res.Resources; -import android.content.Context; -import android.view.SurfaceControl; -import android.view.View; - +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; +import android.content.Context; +import android.os.IBinder; /** * Utility class for adding a view hierarchy to a SurfaceControl. @@ -31,10 +30,13 @@ import android.annotation.TestApi; */ @TestApi public class WindowlessViewRoot { - ViewRootImpl mViewRoot; - WindowlessWindowManager mWm; - public WindowlessViewRoot(Context c, Display d, SurfaceControl rootSurface) { - mWm = new WindowlessWindowManager(c.getResources().getConfiguration(), rootSurface); + private ViewRootImpl mViewRoot; + private WindowlessWindowManager mWm; + public WindowlessViewRoot(@NonNull Context c, @NonNull Display d, + @NonNull SurfaceControl rootSurface, + @Nullable IBinder hostInputToken) { + mWm = new WindowlessWindowManager(c.getResources().getConfiguration(), rootSurface, + hostInputToken); mViewRoot = new ViewRootImpl(c, d, mWm); } @@ -49,4 +51,8 @@ public class WindowlessViewRoot { t.apply(); }); } + + public void dispose() { + mViewRoot.dispatchDetachedFromWindow(); + } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 6c6046f1876f..403bfda78292 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -24,8 +24,6 @@ import android.os.RemoteException; import android.util.Log; import android.util.MergedConfiguration; import android.view.IWindowSession; -import android.view.SurfaceControl; -import android.view.SurfaceSession; import java.util.HashMap; @@ -60,18 +58,20 @@ class WindowlessWindowManager implements IWindowSession { final HashMap<IBinder, ResizeCompleteCallback> mResizeCompletionForWindow = new HashMap<IBinder, ResizeCompleteCallback>(); - final SurfaceSession mSurfaceSession = new SurfaceSession(); - final SurfaceControl mRootSurface; - final Configuration mConfiguration; - IWindowSession mRealWm; + private final SurfaceSession mSurfaceSession = new SurfaceSession(); + private final SurfaceControl mRootSurface; + private final Configuration mConfiguration; + private final IWindowSession mRealWm; + private final IBinder mHostInputToken; private int mForceHeight = -1; private int mForceWidth = -1; - WindowlessWindowManager(Configuration c, SurfaceControl rootSurface) { + WindowlessWindowManager(Configuration c, SurfaceControl rootSurface, IBinder hostInputToken) { mRootSurface = rootSurface; mConfiguration = new Configuration(c); mRealWm = WindowManagerGlobal.getWindowSession(); + mHostInputToken = hostInputToken; } /** @@ -87,6 +87,7 @@ class WindowlessWindowManager implements IWindowSession { /** * IWindowSession implementation. */ + @Override public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, @@ -101,10 +102,11 @@ class WindowlessWindowManager implements IWindowSession { mStateForWindow.put(window.asBinder(), new State(sc, attrs)); } - if ((attrs.inputFeatures & - WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { + if (((attrs.inputFeatures & + WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) && + (mHostInputToken != null)) { try { - mRealWm.blessInputSurface(displayId, sc, outInputChannel); + mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, outInputChannel); } catch (RemoteException e) { Log.e(TAG, "Failed to bless surface: " + e); } @@ -122,10 +124,12 @@ class WindowlessWindowManager implements IWindowSession { } @Override - public void remove(android.view.IWindow window) {} + public void remove(android.view.IWindow window) throws RemoteException { + mRealWm.remove(window); + } private boolean isOpaque(WindowManager.LayoutParams attrs) { - if (attrs.surfaceInsets != null && attrs.surfaceInsets.left != 0 || + if (attrs.surfaceInsets != null && attrs.surfaceInsets.left != 0 || attrs.surfaceInsets.top != 0 || attrs.surfaceInsets.right != 0 || attrs.surfaceInsets.bottom != 0) { return false; @@ -326,8 +330,8 @@ class WindowlessWindowManager implements IWindowSession { } @Override - public void blessInputSurface(int displayId, SurfaceControl surface, - InputChannel outInputChannel) { + public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window, + IBinder hostInputToken, InputChannel outInputChannel) { } @Override |
