Use dedicated lock in InputController

Sharing the single lock with VirtualDeviceImpl doesn't make sense
since they don't really share resources which cannot be accessed
concurrently.

The shared lock lead to deadlock described in b/270703290, using
dedicated lock in InputController removes resource allocation cycle
which caused that deadlock instance.

Bug: 270703290
Test: atest VirtualMouseTest --iterations 20
Test: atest CtsHardwareTestCases
Test: atest CtsVirtualDevicesTestCases
Test: atest VirtualDeviceManagerServiceTest
Change-Id: Id12a945e182a5516ee06193a4fa475b863f11846
This commit is contained in:
Jan Sebechlebsky
2023-02-28 17:25:48 +01:00
committed by Ján Sebechlebský
parent 268ad5716f
commit 2d4ad02822
4 changed files with 6 additions and 8 deletions

View File

@@ -88,7 +88,7 @@ class InputController {
*/
private static final int DEVICE_NAME_MAX_LENGTH = 80;
final Object mLock;
final Object mLock = new Object();
/* Token -> file descriptor associations. */
@GuardedBy("mLock")
@@ -101,18 +101,17 @@ class InputController {
private final WindowManager mWindowManager;
private final DeviceCreationThreadVerifier mThreadVerifier;
InputController(@NonNull Object lock, @NonNull Handler handler,
InputController(@NonNull Handler handler,
@NonNull WindowManager windowManager) {
this(lock, new NativeWrapper(), handler, windowManager,
this(new NativeWrapper(), handler, windowManager,
// Verify that virtual devices are not created on the handler thread.
() -> !handler.getLooper().isCurrentThread());
}
@VisibleForTesting
InputController(@NonNull Object lock, @NonNull NativeWrapper nativeWrapper,
InputController(@NonNull NativeWrapper nativeWrapper,
@NonNull Handler handler, @NonNull WindowManager windowManager,
@NonNull DeviceCreationThreadVerifier threadVerifier) {
mLock = lock;
mHandler = handler;
mNativeWrapper = nativeWrapper;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

View File

@@ -251,7 +251,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
mDisplayManager = displayManager;
if (inputController == null) {
mInputController = new InputController(
mVirtualDeviceLock,
context.getMainThreadHandler(),
context.getSystemService(WindowManager.class));
} else {

View File

@@ -87,7 +87,7 @@ public class InputControllerTest {
// Allow virtual devices to be created on the looper thread for testing.
final InputController.DeviceCreationThreadVerifier threadVerifier = () -> true;
mInputController = new InputController(new Object(), mNativeWrapperMock,
mInputController = new InputController(mNativeWrapperMock,
new Handler(TestableLooper.get(this).getLooper()),
InstrumentationRegistry.getTargetContext().getSystemService(WindowManager.class),
threadVerifier);

View File

@@ -355,7 +355,7 @@ public class VirtualDeviceManagerServiceTest {
TestableLooper.get(this), mNativeWrapperMock, mIInputManagerMock);
// Allow virtual devices to be created on the looper thread for testing.
final InputController.DeviceCreationThreadVerifier threadVerifier = () -> true;
mInputController = new InputController(new Object(), mNativeWrapperMock,
mInputController = new InputController(mNativeWrapperMock,
new Handler(TestableLooper.get(this).getLooper()),
mContext.getSystemService(WindowManager.class), threadVerifier);
mSensorController =