Pass IWindow to InputWindowHandle.

This allows listeners to identify which WindowInfo belongs to which
IWindow. Using InputChannel token may not work since not every Window
has an InputChannel, but every window should have an IWindow token.
There may still be WindowInfo data that doesn't contain an IWindow token
if they were created as pure layers, and not windows.

Test: IWindow token sent to listeners
Bug: 188792659
Change-Id: Ie90453d40906c0ee8312a23a6f4c8e85310bbaf7
This commit is contained in:
chaviw
2021-08-11 09:26:43 -05:00
parent fd73c15e18
commit 0527f21cdb
5 changed files with 44 additions and 3 deletions

View File

@@ -44,6 +44,12 @@ public final class InputWindowHandle {
// channel and the server input channel will both contain this token.
public IBinder token;
/**
* The {@link IWindow} handle if InputWindowHandle is associated with a window, null otherwise.
*/
@Nullable
private IBinder windowToken;
// The window name.
public String name;
@@ -145,6 +151,7 @@ public final class InputWindowHandle {
.append(", visible=").append(visible)
.append(", scaleFactor=").append(scaleFactor)
.append(", transform=").append(transform)
.append(", windowToken=").append(getWindow())
.toString();
}
@@ -176,4 +183,12 @@ public final class InputWindowHandle {
public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
touchableRegionSurfaceControl = new WeakReference<>(bounds);
}
public void setWindowToken(IWindow iwindow) {
windowToken = iwindow.asBinder();
}
public IWindow getWindow() {
return IWindow.Stub.asInterface(windowToken);
}
}

View File

@@ -76,6 +76,7 @@ static struct {
jfieldID replaceTouchableRegionWithCrop;
WeakRefHandleField touchableRegionSurfaceControl;
jfieldID transform;
jfieldID windowToken;
} gInputWindowHandleClassInfo;
static struct {
@@ -215,6 +216,14 @@ bool NativeInputWindowHandle::updateInfo() {
mInfo.touchableRegionCropHandle.clear();
}
jobject windowTokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.windowToken);
if (windowTokenObj) {
mInfo.windowToken = ibinderForJavaObject(env, windowTokenObj);
env->DeleteLocalRef(windowTokenObj);
} else {
mInfo.windowToken.clear();
}
env->DeleteLocalRef(obj);
return true;
}
@@ -314,6 +323,9 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
ScopedLocalRef<jobject> matrixObj(env, AMatrix_newInstance(env, transformVals));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.transform, matrixObj.get());
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.windowToken,
javaObjectForIBinder(env, windowInfo.windowToken));
return inputWindowHandle;
}
@@ -441,6 +453,9 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
GET_FIELD_ID(gInputWindowHandleClassInfo.transform, clazz, "transform",
"Landroid/graphics/Matrix;");
GET_FIELD_ID(gInputWindowHandleClassInfo.windowToken, clazz, "windowToken",
"Landroid/os/IBinder;");
jclass weakRefClazz;
FIND_CLASS(weakRefClazz, "java/lang/ref/Reference");

View File

@@ -289,6 +289,7 @@ final class InputMonitor {
inputWindowHandle.setInputFeatures(w.mAttrs.inputFeatures);
inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
inputWindowHandle.setVisible(w.isVisible());
inputWindowHandle.setWindowToken(w.mClient);
final boolean focusable = w.canReceiveKeys()
&& (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Region;
import android.os.IBinder;
import android.view.IWindow;
import android.view.InputApplicationHandle;
import android.view.InputWindowHandle;
import android.view.SurfaceControl;
@@ -275,6 +276,14 @@ class InputWindowHandleWrapper {
mChanged = true;
}
void setWindowToken(IWindow windowToken) {
if (mHandle.getWindow() == windowToken) {
return;
}
mHandle.setWindowToken(windowToken);
mChanged = true;
}
@Override
public String toString() {
return mHandle + ", changed=" + mChanged;

View File

@@ -8256,7 +8256,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
name, applicationHandle, flags, privateFlags, type, null /* region */);
name, applicationHandle, flags, privateFlags, type, null /* region */, window);
clientChannel.copyTo(outInputChannel);
}
@@ -8264,9 +8264,10 @@ public class WindowManagerService extends IWindowManager.Stub
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
int displayId, SurfaceControl surface, String name,
InputApplicationHandle applicationHandle, int flags,
int privateFlags, int type, Region region) {
int privateFlags, int type, Region region, IWindow window) {
InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
h.token = channelToken;
h.setWindowToken(window);
h.name = name;
final int sanitizedFlags = flags & (LayoutParams.FLAG_NOT_TOUCHABLE
@@ -8322,7 +8323,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
applicationHandle, flags, privateFlags, win.mWindowType, region);
applicationHandle, flags, privateFlags, win.mWindowType, region, win.mClient);
}
/** Return whether layer tracing is enabled */