Set tablet mode if there is a physical keyboard
and also virtual keyboard shows
Bug: 353823512
Test: attach and detach a physical keyboard, and check UI style and
virtual keyboard
Change-Id: I06c3fa209cf312c7299f9a726c4b7c40b78b2ce5
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachine.java b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
index b6de9bb..a51f7e1 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachine.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachine.java
@@ -1192,6 +1192,25 @@
}
/** @hide */
+ public boolean sendTabletModeEvent(boolean tabletMode) {
+ if (mSwitchesSock == null) {
+ Log.d(TAG, "mSwitcheSock == null");
+ return false;
+ }
+
+ // from include/uapi/linux/input-event-codes.h in the kernel.
+ short EV_SYN = 0x00;
+ short EV_SW = 0x05;
+ short SW_TABLET_MODE = 0x01;
+ short SYN_REPORT = 0x00;
+ return writeEventsToSock(
+ mSwitchesSock,
+ Arrays.asList(
+ new InputEvent(EV_SW, SW_TABLET_MODE, tabletMode ? 1 : 0),
+ new InputEvent(EV_SYN, SYN_REPORT, 0)));
+ }
+
+ /** @hide */
public boolean sendTrackpadEvent(MotionEvent event) {
try {
mInputEventQueue.add(Pair.create(InputEventType.TRACKPAD, event));
diff --git a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
index 8bb0fd4..694aa57 100644
--- a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
+++ b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
@@ -28,6 +28,7 @@
import android.crosvm.ICrosvmAndroidDisplayService;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -77,7 +78,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-public class MainActivity extends Activity {
+public class MainActivity extends Activity implements InputManager.InputDeviceListener {
private static final String TAG = "VmLauncherApp";
private static final String VM_NAME = "my_custom_vm";
private static final boolean DEBUG = true;
@@ -256,6 +257,56 @@
return !isVolumeKey(keyCode) && mVirtualMachine.sendKeyEvent(event);
}
+ private void registerInputDeviceListener() {
+ InputManager inputManager = getSystemService(InputManager.class);
+ if (inputManager == null) {
+ Log.e(TAG, "failed to registerInputDeviceListener because InputManager is null");
+ return;
+ }
+ inputManager.registerInputDeviceListener(this, null);
+ }
+
+ private void unregisterInputDeviceListener() {
+ InputManager inputManager = getSystemService(InputManager.class);
+ if (inputManager == null) {
+ Log.e(TAG, "failed to unregisterInputDeviceListener because InputManager is null");
+ return;
+ }
+ inputManager.unregisterInputDeviceListener(this);
+ }
+
+ private void setTabletModeConditionally() {
+ if (mVirtualMachine == null) {
+ Log.e(TAG, "failed to setTabletModeConditionally because VirtualMachine is null");
+ return;
+ }
+ for (int id : InputDevice.getDeviceIds()) {
+ InputDevice d = InputDevice.getDevice(id);
+ if (!d.isVirtual() && d.isEnabled() && d.isFullKeyboard()) {
+ Log.d(TAG, "the device has a physical keyboard, turn off tablet mode");
+ mVirtualMachine.sendTabletModeEvent(false);
+ return;
+ }
+ }
+ mVirtualMachine.sendTabletModeEvent(true);
+ Log.d(TAG, "the device doesn't have a physical keyboard, turn on tablet mode");
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ setTabletModeConditionally();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ setTabletModeConditionally();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ setTabletModeConditionally();
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -460,6 +511,13 @@
windowInsetsController.setSystemBarsBehavior(
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
windowInsetsController.hide(WindowInsets.Type.systemBars());
+ registerInputDeviceListener();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setTabletModeConditionally();
}
@Override
@@ -494,6 +552,7 @@
if (mExecutorService != null) {
mExecutorService.shutdownNow();
}
+ unregisterInputDeviceListener();
Log.d(TAG, "destroyed");
}