Merge "Fix consumer closed input channel cause an error occurred (1/2)" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-05-11 05:56:35 +00:00
committed by Android (Google) Code Review
4 changed files with 43 additions and 26 deletions

View File

@@ -4638,14 +4638,17 @@ public final class ViewRootImpl implements ViewParent,
mInputQueueCallback = null;
mInputQueue = null;
}
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
}
try {
mWindowSession.remove(mWindow);
} catch (RemoteException e) {
}
// Dispose receiver would dispose client InputChannel, too. That could send out a socket
// broken event, so we need to unregister the server InputChannel when removing window to
// prevent server side receive the event and prompt error.
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
}
mDisplayManager.unregisterDisplayListener(mDisplayListener);

View File

@@ -191,6 +191,7 @@ public class WindowlessWindowManager implements IWindowSession {
throw new IllegalArgumentException(
"Invalid window token (never added or removed already)");
}
try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
t.remove(state.mSurfaceControl).apply();
}

View File

@@ -28,6 +28,7 @@ import android.util.ArrayMap;
import android.util.Slog;
import android.view.IWindow;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
/**
* Keeps track of embedded windows.
@@ -95,7 +96,7 @@ class EmbeddedWindowController {
void remove(IWindow client) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
if (mWindows.valueAt(i).mClient.asBinder() == client.asBinder()) {
mWindows.removeAt(i);
mWindows.removeAt(i).onRemoved();
return;
}
}
@@ -104,7 +105,7 @@ class EmbeddedWindowController {
void onWindowRemoved(WindowState host) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
if (mWindows.valueAt(i).mHostWindowState == host) {
mWindows.removeAt(i);
mWindows.removeAt(i).onRemoved();
}
}
}
@@ -132,6 +133,8 @@ class EmbeddedWindowController {
@Nullable final ActivityRecord mHostActivityRecord;
final int mOwnerUid;
final int mOwnerPid;
final WindowManagerService mWmService;
InputChannel mInputChannel;
/**
* @param clientToken client token used to clean up the map if the embedding process dies
@@ -142,8 +145,9 @@ class EmbeddedWindowController {
* @param ownerUid calling uid
* @param ownerPid calling pid used for anr blaming
*/
EmbeddedWindow(IWindow clientToken, WindowState hostWindowState, int ownerUid,
int ownerPid) {
EmbeddedWindow(WindowManagerService service, IWindow clientToken,
WindowState hostWindowState, int ownerUid, int ownerPid) {
mWmService = service;
mClient = clientToken;
mHostWindowState = hostWindowState;
mHostActivityRecord = (mHostWindowState != null) ? mHostWindowState.mActivityRecord
@@ -167,5 +171,29 @@ class EmbeddedWindowController {
return new InputApplicationHandle(
mHostWindowState.mInputWindowHandle.inputApplicationHandle);
}
InputChannel openInputChannel() {
final String name = getName();
final InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
mInputChannel = inputChannels[0];
final InputChannel clientChannel = inputChannels[1];
mWmService.mInputManager.registerInputChannel(mInputChannel);
if (mInputChannel.getToken() != clientChannel.getToken()) {
throw new IllegalStateException("Client and Server tokens are expected to"
+ "be the same");
}
return clientChannel;
}
void onRemoved() {
if (mInputChannel != null) {
mWmService.mInputManager.unregisterInputChannel(mInputChannel);
mInputChannel.dispose();
mInputChannel = null;
}
}
}
}

View File

@@ -8030,26 +8030,15 @@ public class WindowManagerService extends IWindowManager.Stub
IWindow window, IBinder hostInputToken, int flags, InputChannel outInputChannel) {
final InputApplicationHandle applicationHandle;
final String name;
final InputChannel[] inputChannels;
final InputChannel clientChannel;
final InputChannel serverChannel;
synchronized (mGlobalLock) {
EmbeddedWindowController.EmbeddedWindow win =
new EmbeddedWindowController.EmbeddedWindow(window,
new EmbeddedWindowController.EmbeddedWindow(this, window,
mInputToWindowMap.get(hostInputToken), callingUid, callingPid);
name = win.getName();
inputChannels = InputChannel.openInputChannelPair(name);
serverChannel = inputChannels[0];
clientChannel = inputChannels[1];
mInputManager.registerInputChannel(serverChannel);
clientChannel = win.openInputChannel();
mEmbeddedWindowController.add(clientChannel.getToken(), win);
if (serverChannel.getToken() != clientChannel.getToken()) {
throw new IllegalStateException("Client and Server channel are expected to"
+ "be the same");
}
applicationHandle = win.getApplicationHandle();
name = win.getName();
}
updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
@@ -8057,10 +8046,6 @@ public class WindowManagerService extends IWindowManager.Stub
clientChannel.transferTo(outInputChannel);
clientChannel.dispose();
// Prevent the java finalizer from breaking the input channel. But we won't
// do any further management so we just release the java ref and let the
// InputDispatcher hold the last ref.
serverChannel.release();
}
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,