Merge "Fix consumer closed input channel cause an error occurred (1/2)" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
488cd2c4ff
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user