From 84fcd3ae6a2f0ef1f6a38e6e33de20ca805956b0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 28 Jun 2022 22:07:40 -0500 Subject: [PATCH] Use requestMetaKeyEvent API on Samsung devices Inspired by #1078 --- app/src/main/java/com/limelight/Game.java | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index b818bd9d..0d3beaea 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -78,6 +78,8 @@ import android.widget.TextView; import android.widget.Toast; import java.io.ByteArrayInputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -597,6 +599,35 @@ public class Game extends Activity implements SurfaceHolder.Callback, } } + public void setMetaKeyCaptureState(boolean enabled) { + // This uses custom APIs present on some Samsung devices to allow capture of + // meta key events while streaming. + try { + Class semWindowManager = Class.forName("com.samsung.android.view.SemWindowManager"); + Method getInstanceMethod = semWindowManager.getMethod("getInstance"); + Object manager = getInstanceMethod.invoke(null); + + if (manager != null) { + Class[] parameterTypes = new Class[2]; + parameterTypes[0] = String.class; + parameterTypes[1] = boolean.class; + Method requestMetaKeyEventMethod = semWindowManager.getDeclaredMethod("requestMetaKeyEvent", parameterTypes); + requestMetaKeyEventMethod.invoke(manager, this.getComponentName(), enabled); + } + else { + LimeLog.warning("SemWindowManager.getInstance() returned null"); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + @Override public void onUserLeaveHint() { super.onUserLeaveHint(); @@ -1696,6 +1727,9 @@ public class Game extends Activity implements SurfaceHolder.Callback, // Enable cursor visibility again inputCaptureProvider.disableCapture(); + // Disable meta key capture + setMetaKeyCaptureState(false); + if (!displayedFailureDialog) { displayedFailureDialog = true; LimeLog.severe("Connection terminated: " + errorCode); @@ -1807,6 +1841,9 @@ public class Game extends Activity implements SurfaceHolder.Callback, // Keep the display on getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + // Enable meta key capture + setMetaKeyCaptureState(true); + // Update GameManager state to indicate we're in game UiHelper.notifyStreamConnected(Game.this);