summaryrefslogtreecommitdiff
path: root/core/java/android/view
diff options
context:
space:
mode:
authorVishnu Nair <vishnun@google.com>2019-11-07 15:33:20 -0800
committerVishnu Nair <vishnun@google.com>2019-11-07 15:54:27 -0800
commit5cf25319775616f88d59768bd9dd0753afd0359f (patch)
tree68482078dd710dab7c5f07a6ec9d9c56cabb8f74 /core/java/android/view
parentf8a289110576dcff9c7486d8e4f80a85d9786f23 (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.aidl3
-rw-r--r--core/java/android/view/InputApplicationHandle.java8
-rw-r--r--core/java/android/view/InputEventReceiver.java11
-rw-r--r--core/java/android/view/SurfaceView.java16
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/WindowlessViewRoot.java24
-rw-r--r--core/java/android/view/WindowlessWindowManager.java32
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