Handle some input events in the background thread
For better performance, made some latency sentive input events be
handled in the background thread instead of UI thread
Bug: 331179939
Bug: 347253952
Test: check the latency
Change-Id: Ib8e849abfedc9a606ccb0fbdffb9c7a696a82570
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachine.java b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
index 23269d9..b6de9bb 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachine.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
@@ -77,6 +77,7 @@
import android.system.virtualizationservice.VirtualMachineState;
import android.util.JsonReader;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -112,8 +113,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.zip.ZipFile;
@@ -174,6 +178,15 @@
private ParcelFileDescriptor mSwitchesSock;
private ParcelFileDescriptor mTrackpadSock;
+ private enum InputEventType {
+ TOUCH,
+ MOUSE,
+ TRACKPAD
+ }
+
+ private BlockingQueue<Pair<InputEventType, MotionEvent>> mInputEventQueue =
+ new LinkedBlockingQueue<>();
+
/**
* Status of a virtual machine
*
@@ -333,6 +346,8 @@
private final Executor mConsoleExecutor = Executors.newSingleThreadExecutor();
+ private ExecutorService mInputEventExecutor;
+
/** The configuration that is currently associated with this VM. */
@GuardedBy("mLock")
@NonNull
@@ -907,8 +922,7 @@
// Handle input devices here
List<InputDevice> inputDevices = new ArrayList<>();
- if (vmConfig.getCustomImageConfig() != null
- && rawConfig.displayConfig != null) {
+ if (vmConfig.getCustomImageConfig() != null && rawConfig.displayConfig != null) {
if (vmConfig.getCustomImageConfig().useTouch()) {
ParcelFileDescriptor[] pfds = ParcelFileDescriptor.createSocketPair();
mTouchSock = pfds[0];
@@ -983,6 +997,17 @@
/** @hide */
public boolean sendMouseEvent(MotionEvent event) {
+ try {
+ mInputEventQueue.add(Pair.create(InputEventType.MOUSE, event));
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ return false;
+ }
+ }
+
+ /** @hide */
+ private boolean sendMouseEventInternal(MotionEvent event) {
if (mMouseSock == null) {
Log.d(TAG, "mMouseSock == null");
return false;
@@ -1071,6 +1096,17 @@
/** @hide */
public boolean sendMultiTouchEvent(MotionEvent event) {
+ try {
+ mInputEventQueue.add(Pair.create(InputEventType.TOUCH, event));
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ return false;
+ }
+ }
+
+ /** @hide */
+ private boolean sendMultiTouchEventInternal(MotionEvent event) {
if (mTouchSock == null) {
Log.d(TAG, "mTouchSock == null");
return false;
@@ -1157,6 +1193,17 @@
/** @hide */
public boolean sendTrackpadEvent(MotionEvent event) {
+ try {
+ mInputEventQueue.add(Pair.create(InputEventType.TRACKPAD, event));
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ return false;
+ }
+ }
+
+ /** @hide */
+ private boolean sendTrackpadEventInternal(MotionEvent event) {
if (mTrackpadSock == null) {
Log.d(TAG, "mTrackpadSock == null");
return false;
@@ -1476,7 +1523,29 @@
} else if (mVmOutputCaptured) {
consoleOutFd = mConsoleOutWriter;
}
-
+ mInputEventExecutor = Executors.newSingleThreadExecutor();
+ mInputEventExecutor.execute(
+ () -> {
+ while (true) {
+ try {
+ Pair<InputEventType, MotionEvent> event =
+ mInputEventQueue.take();
+ switch (event.first) {
+ case TOUCH:
+ sendMultiTouchEventInternal(event.second);
+ break;
+ case TRACKPAD:
+ sendTrackpadEventInternal(event.second);
+ break;
+ case MOUSE:
+ sendMouseEventInternal(event.second);
+ break;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+ });
ParcelFileDescriptor consoleInFd = null;
if (mConnectVmConsole) {
consoleInFd = mPtyFd;
@@ -1738,6 +1807,9 @@
try {
mVirtualMachine.stop();
dropVm();
+ if (mInputEventExecutor != null) {
+ mInputEventExecutor.shutdownNow();
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
} catch (ServiceSpecificException e) {