From ceb9bd3342865c0f2c490eee9b56efc6f40437e1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 28 Sep 2014 12:27:21 -0700 Subject: [PATCH 1/9] Change bitstream restrictions to match default values --- .../limelight/binding/video/MediaCodecDecoderRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java index e8a5007c..cb4002e6 100644 --- a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -436,9 +436,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { LimeLog.info("Adding bitstream restrictions"); sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); - sps.vuiParams.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = false; - sps.vuiParams.bitstreamRestriction.max_bytes_per_pic_denom = 0; - sps.vuiParams.bitstreamRestriction.max_bits_per_mb_denom = 0; + sps.vuiParams.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = true; + sps.vuiParams.bitstreamRestriction.max_bytes_per_pic_denom = 2; + sps.vuiParams.bitstreamRestriction.max_bits_per_mb_denom = 1; sps.vuiParams.bitstreamRestriction.log2_max_mv_length_horizontal = 16; sps.vuiParams.bitstreamRestriction.log2_max_mv_length_vertical = 16; sps.vuiParams.bitstreamRestriction.num_reorder_frames = 0; From cafdc21bf2f00044ab5963e23a1e64e7271224b5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 28 Sep 2014 14:17:31 -0700 Subject: [PATCH 2/9] Prefer Samsung's OMX.SEC.AVC.Decoder if it's in the list of decoders --- .../video/MediaCodecDecoderRenderer.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java index cb4002e6..2a96821c 100644 --- a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -44,11 +44,20 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { private int numPpsIn; private int numIframeIn; + public static final List preferredDecoders; + public static final List blacklistedDecoderPrefixes; public static final List spsFixupBitstreamFixupDecoderPrefixes; public static final List spsFixupNumRefFixupDecoderPrefixes; public static final List whitelistedAdaptiveResolutionPrefixes; + static { + preferredDecoders = new LinkedList(); + + // This is the most reliable of Samsung's decoders + preferredDecoders.add("OMX.SEC.AVC.Decoder"); + } + static { blacklistedDecoderPrefixes = new LinkedList(); @@ -158,6 +167,31 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { return str; } + private static MediaCodecInfo findPreferredDecoder() { + // This is a different algorithm than the other findXXXDecoder functions, + // because we want to evaluate the decoders in our list's order + // rather than MediaCodecList's order + + for (String preferredDecoder : preferredDecoders) { + for (int i = 0; i < MediaCodecList.getCodecCount(); i++) { + MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); + + // Skip encoders + if (codecInfo.isEncoder()) { + continue; + } + + // Check for preferred decoders + if (preferredDecoder.equalsIgnoreCase(codecInfo.getName())) { + LimeLog.info("Preferred decoder choice is "+codecInfo.getName()); + return codecInfo; + } + } + } + + return null; + } + private static MediaCodecInfo findFirstDecoder() { for (int i = 0; i < MediaCodecList.getCodecCount(); i++) { MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); @@ -186,7 +220,13 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { } public static MediaCodecInfo findProbableSafeDecoder() { - // First look for decoders we know are safe + // First look for a preferred decoder by name + MediaCodecInfo info = findPreferredDecoder(); + if (info != null) { + return info; + } + + // Now look for decoders we know are safe try { // If this function completes, it will determine if the decoder is safe return findKnownSafeDecoder(); From d3438f49380639a787766cdcace8ea57b37bc5cd Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 28 Sep 2014 16:27:11 -0700 Subject: [PATCH 3/9] Update common jar --- libs/limelight-common.jar | Bin 418126 -> 418136 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/libs/limelight-common.jar b/libs/limelight-common.jar index 78eb0bd489e45d4b0885c2a9b5f9f06f257aaa52..4cfafd60d8b25ffab78f8455023f9b7df4d4972f 100644 GIT binary patch delta 7468 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�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 E16^#_C;$Ke From ad684a6f6b745f5fffd303e0d0f4856371c8e4af Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 28 Sep 2014 16:30:37 -0700 Subject: [PATCH 4/9] Merge version update --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7383b6ee..3b5530ef 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@  + android:versionCode="35" + android:versionName="2.5.5.1" > Date: Wed, 1 Oct 2014 20:24:40 -0700 Subject: [PATCH 5/9] Add axis scaling support --- libs/limelight-common.jar | Bin 418136 -> 418537 bytes .../binding/input/ControllerHandler.java | 25 ++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libs/limelight-common.jar b/libs/limelight-common.jar index 4cfafd60d8b25ffab78f8455023f9b7df4d4972f..0348acc13d669b6fa12132b3e7c66957bb28fe05 100644 GIT binary patch delta 1949 zcmYk7c~p{V8^+;P-YoO85ERLBDfhxm+%OUe+-1nEatUfwL?_g;Mfr?0Q*(LiH6^3DWM-O=f0l*u0Q`!m%dO}qPxh+ zqhJaO3b2u1?P8V0N^mVNxyAxJ=%5#z%JZJ~P&tmWbs+;0lKCWZgZH=Y9i@h1@qwZc zBr>UNUl8QbfQ2gJGx@=lbg9dKhh7gRuAgbXnJ-nV_q={6pSA(p5d5PeuIE;5HNM_e zn=`<@@}XeadYMzOzSzv5^gGyEKcL-h9GE<#Rc;azMYIf)-_{-|6g^0RKMRlGwJK1O z5kk+74`O%sPF!$;UYDl*)AICKa?@?BoHg%>`$Ex#8%@sD(L4;O$}W`<8k$5X=QqzsnDMtf(;jP{ zbUvr2bGDKeml=IaY(&q^OSPZWHdNW;ahr0$-o_8Ff0S*w6Wig~)1w`T@j5i^E$JXx zW*1fD#Xh9$*K|>MyzoB&NpW1D>qOqvAw*FfjiL}gH~xhS(HE}*v~0e`}QghPW4Wv zdb^*P0mRPK=SLo8@gfu4N`7v@fBe)sQIUF&HB7a@qS^7t`M*+@Q_bpFl+~+uFuEz9 zwU^97Tt!+-btJbWyi<}`yj|^%XJ;xpb%4(e(6c?zOM21NtP?|Vb2Z!B8&xvUWbPq; zo?|4)+bO+FWqFHK`sL3z9j?OiPyO8jn&u8ub@dWWaLQkJEx4zoDE$M>4&43r5Uq06 zbFqD;rY5~QXnOdC5C<$jdce6cX&W}XA8g3Fe9+%!BEm8H1>E&TID#W3tmhEFZqy+uu8BqS$H zc3<#k18gQKLSWFXzQ>_-G82F2t<&-%a$DXRYS~+qu`tb}jDL~#*!}hSWOSdz(3_?| z7#G^!F%1{xcor_RN^6Lpj_hNNln2ykR&gyIm7~MHsm>yv`G2@Jnq~Zwr>)N$wYxcD z!`tY|ifm#AYj8^F&)FSo*0()hly&LoDlHZ-My?&MJz{ijx4l2UPbzfD&LITP-9ujd zsG!2Ynspd#B$E2SWGC#QSJf1UR_3R3=+;vs+eJBVm^NNdWacZu3jNI#he#VxojF!Nn^M&)5`jmZk*ciaDLQxmL_^F-9!}dG@}B8EF7j3z{K!Ei*9u4OC#E_SL&>J{|e!mi)Hs(E=uT&DH+1sUAjEX zHG2HYo}Dq-=fP#|utmWpCT7bL z0tO2dM2zl+H2mP&P?#^MmPqh{%LK?ICzE^)!3Xh8Dkp1^8Y>D2ss2Y+BGk>diqMD; z7y(52LfQ;a9pY2r;P)+dfWZI%2+{4fnFmd$btWDtt619hNnr$M8A5mXR{W3eOIEKb{ delta 1526 zcmV&iwL1!1K^&P@L0 zLV5}P(=?_tolY*G7uEFLwJekrI#V&@JpHno(#YCuegN zMnijPMnP3BD2y(Z<;+%2ZK(Bfju9&`8bzHGN9#B>&Fty{EN=?$%8k4tuOp%gPmJJ6 z3lC_H)9!%QIMw^~_U%hhc)L89B*thYTiPjl4s<=D%^d*S+u<9BDM=Ip)x%Qf*|EGuIkim3Lh)8BJ8nxlBP;8tH9SEqQAUqQvF0 zTvtkRwxQ&T>*@wna&_x7PcVy|&938EoxG{FPe7)A;Hb9IZtFHy4b3H+Z<6PV@_?#i zw2pTDP{*qxa4_W~%tcmOrqMB+e@Bc0iTN6KGGp!QBUt1&5)D&`TPqTUDa2?@F*K8RVCNR z6|)7o$Y@gecj$7IzNbc*e!$TKUQN!I3 zty*2XrRNQPYU1zj(GpKaH?Y_IdzhhVejH&<^TQ~{2=S8;<=;JB0!uXN@n!Isk7M8~ zJ{|{8_;?Z=_wiNmH6Krbr+xeZXvW90;OjpA5d4vk=fF37{4w~Ze~&)_f9m5~;Lm)V z0MGk43109q@BecjFX9&;7x4$5mKbll;~m$3*B$S<<9#s(q3f6Q6*7GdYJvH4GZy+Y zQV+zUYCRI0RDYufuH$F59*%9pvHYtj{1Cslurau4u}vdb*k$~MA^tc7oq$l+Aj}mA zkfKN84Sox+ikqGne|!T^gfBiBoBEyPw3&<#_ee>`Lp>@c z>};wO3Jl4I3|GW7F8I3^pJOQF9O{FKSo%l`vLClS@J}CM+)6kg&LH0bz0B zg2Lj`4GW8l7ZMhiFO0WU+ID++jSM`;?!qgoozizZ7$2Nce{*Lc`I@q)bRdlUDLoa& z#=zJdOeq7SI55h>cty)R%~{t==#^*_{cNFQ1&84=6fWY3l(51wVxFMq3aEmu1^ej(F@rp}$wda27MEa1 z1_TP@Boj|$1ONbw2$ybL25|!DS(o8l24DgLT$iC*1|OF{Tm}V~XI%z70?=NUp;`tX zm!Dh)3YX4Z20a4WVwZ7V1~HdDUIsA&=xCR5UItt*JSq2%G-i-knm+4Ff443d=1|9;ek(Ur*1~me3l9xwe1~vj>lb3&C z1~dX&l$W((20#K8ZkP9A20a2AjF&cI20#N~K?au&Lk1$3n_>nkB;Z2^04`@~bZKX9 cZ*pZ&O9ci10000`08juK9RL6+L 1.0f) { normalizedInputVector.setX(1.0f); @@ -284,7 +305,7 @@ public class ControllerHandler { event.getAxisValue(mapping.rightStickYAxis), mapping.rightStickDeadzoneRadius); rightStickX = (short)(rightStickVector.getX() * 0x7FFE); - rightStickY = (short)(-rightStickVector.getY() * 0x7FFE); + rightStickY = (short)(-rightStickVector.getY() * 0x7FFE); } // Handle controllers with analog triggers From a726ba8ea79a34680b6f467457310df763792d4f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 3 Oct 2014 22:18:36 -0700 Subject: [PATCH 6/9] Add an ungrab key combo (Ctrl+Shift+Z). Ignore repeat key down events. Fix some mishandling of input events that could cause crashes. --- src/com/limelight/Game.java | 214 ++++++++++++++---- .../binding/input/evdev/EvdevWatcher.java | 40 +++- 2 files changed, 210 insertions(+), 44 deletions(-) diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index 4ba30d7a..15e82d51 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -69,6 +69,11 @@ public class Game extends Activity implements SurfaceHolder.Callback, private boolean toastsDisabled; private EvdevWatcher evdevWatcher; + private int modifierFlags = 0; + private boolean grabbedInput = true; + private boolean grabComboDown = false; + private static final int MODIFIER_CTRL = 0x1; + private static final int MODIFIER_SHIFT = 0x2; private ConfigurableDecoderRenderer decoderRenderer; @@ -315,6 +320,80 @@ public class Game extends Activity implements SurfaceHolder.Callback, wifiLock.release(); } + private Runnable toggleGrab = new Runnable() { + @Override + public void run() { + + if (evdevWatcher != null) { + if (grabbedInput) { + evdevWatcher.ungrabAll(); + } + else { + evdevWatcher.regrabAll(); + } + } + + grabbedInput = !grabbedInput; + } + }; + + // Returns true if the key stroke was consumed + private boolean handleMagicKeyCombos(short translatedKey, boolean down) { + int modifierMask = 0; + + // Mask off the high byte + translatedKey &= 0xff; + + if (translatedKey == KeyboardTranslator.VK_CONTROL) { + modifierMask = MODIFIER_CTRL; + } + else if (translatedKey == KeyboardTranslator.VK_SHIFT) { + modifierMask = MODIFIER_SHIFT; + } + + if (down) { + this.modifierFlags |= modifierMask; + } + else { + this.modifierFlags &= ~modifierMask; + } + + // Check if Ctrl+Shift+Z is pressed + if (translatedKey == KeyboardTranslator.VK_Z && + (modifierFlags & (MODIFIER_CTRL|MODIFIER_SHIFT)) == (MODIFIER_CTRL|MODIFIER_SHIFT)) + { + if (down) { + // Now that we've pressed the magic combo + // we'll wait for one of the keys to come up + grabComboDown = true; + } + else { + // Toggle the grab if Z comes up + Handler h = getWindow().getDecorView().getHandler(); + if (h != null) { + h.postDelayed(toggleGrab, 250); + } + + grabComboDown = false; + } + + return true; + } + // Toggle the grab if control or shift comes up + else if (grabComboDown) { + Handler h = getWindow().getDecorView().getHandler(); + if (h != null) { + h.postDelayed(toggleGrab, 250); + } + + grabComboDown = false; + return true; + } + + // Not a special combo + return false; + } + private static byte getModifierState(KeyEvent event) { byte modifier = 0; if (event.isShiftPressed()) { @@ -350,6 +429,21 @@ public class Game extends Activity implements SurfaceHolder.Callback, return super.onKeyDown(keyCode, event); } + // Let this method take duplicate key down events + if (handleMagicKeyCombos(translated, true)) { + return true; + } + + // Eat repeat down events + if (event.getRepeatCount() > 0) { + return true; + } + + // Pass through keyboard input if we're not grabbing + if (!grabbedInput) { + return super.onKeyDown(keyCode, event); + } + keybTranslator.sendKeyDown(translated, getModifierState(event)); } @@ -388,6 +482,15 @@ public class Game extends Activity implements SurfaceHolder.Callback, return super.onKeyUp(keyCode, event); } + if (handleMagicKeyCombos(translated, false)) { + return true; + } + + // Pass through keyboard input if we're not grabbing + if (!grabbedInput) { + return super.onKeyUp(keyCode, event); + } + keybTranslator.sendKeyUp(translated, getModifierState(event)); } @@ -404,25 +507,35 @@ public class Game extends Activity implements SurfaceHolder.Callback, return null; } } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) + + // Returns true if the event was consumed + private boolean handleMotionEvent(MotionEvent event) { + // Pass through keyboard input if we're not grabbing + if (!grabbedInput) { + return false; + } + + if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { + if (controllerHandler.handleMotionEvent(event)) { + return true; + } + } + else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { // This case is for touch-based input devices if (event.getSource() == InputDevice.SOURCE_TOUCHSCREEN || - event.getSource() == InputDevice.SOURCE_STYLUS) + event.getSource() == InputDevice.SOURCE_STYLUS) { int actionIndex = event.getActionIndex(); - + int eventX = (int)event.getX(actionIndex); int eventY = (int)event.getY(actionIndex); - + TouchContext context = getTouchContext(actionIndex); if (context == null) { - return super.onTouchEvent(event); + return false; } - + switch (event.getActionMasked()) { case MotionEvent.ACTION_POINTER_DOWN: @@ -444,15 +557,24 @@ public class Game extends Activity implements SurfaceHolder.Callback, touchContextMap[i].touchMoveEvent(eventX, eventY); } break; + case MotionEvent.ACTION_HOVER_MOVE: + // Send a mouse move update (if neccessary) + updateMousePosition((int)event.getX(), (int)event.getY()); + break; + case MotionEvent.ACTION_SCROLL: + // Send the vertical scroll packet + byte vScrollClicks = (byte) event.getAxisValue(MotionEvent.AXIS_VSCROLL); + conn.sendMouseScroll(vScrollClicks); + break; default: - return super.onTouchEvent(event); + return false; } } // This case is for mice else if (event.getSource() == InputDevice.SOURCE_MOUSE) { int changedButtons = event.getButtonState() ^ lastButtonState; - + if ((changedButtons & MotionEvent.BUTTON_PRIMARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_PRIMARY) != 0) { conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_LEFT); @@ -461,7 +583,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); } } - + if ((changedButtons & MotionEvent.BUTTON_SECONDARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) { conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_RIGHT); @@ -470,7 +592,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_RIGHT); } } - + if ((changedButtons & MotionEvent.BUTTON_TERTIARY) != 0) { if ((event.getButtonState() & MotionEvent.BUTTON_TERTIARY) != 0) { conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_MIDDLE); @@ -479,47 +601,41 @@ public class Game extends Activity implements SurfaceHolder.Callback, conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_MIDDLE); } } - + updateMousePosition((int)event.getX(), (int)event.getY()); - + lastButtonState = event.getButtonState(); } else { - return super.onTouchEvent(event); + // Unknown source + return false; } + // Handled a known source return true; } + + // Unknown class + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!handleMotionEvent(event)) { + return super.onTouchEvent(event); + } - return super.onTouchEvent(event); + return true; } @Override public boolean onGenericMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { - if (controllerHandler.handleMotionEvent(event)) { - return true; - } - } - else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) - { - switch (event.getActionMasked()) - { - case MotionEvent.ACTION_HOVER_MOVE: - // Send a mouse move update (if neccessary) - updateMousePosition((int)event.getX(), (int)event.getY()); - break; - case MotionEvent.ACTION_SCROLL: - // Send the vertical scroll packet - byte vScrollClicks = (byte) event.getAxisValue(MotionEvent.AXIS_VSCROLL); - conn.sendMouseScroll(vScrollClicks); - break; - } - return true; + if (!handleMotionEvent(event)) { + return super.onGenericMotionEvent(event); } - return super.onGenericMotionEvent(event); + return true; } private void updateMousePosition(int eventX, int eventY) { @@ -547,15 +663,13 @@ public class Game extends Activity implements SurfaceHolder.Callback, @Override public boolean onGenericMotion(View v, MotionEvent event) { - // Send it to the activity's motion event handler - return onGenericMotionEvent(event); + return handleMotionEvent(event); } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { - // Send it to the activity's touch event handler - return onTouchEvent(event); + return handleMotionEvent(event); } @Override @@ -706,4 +820,20 @@ public class Game extends Activity implements SurfaceHolder.Callback, public void mouseScroll(byte amount) { conn.sendMouseScroll(amount); } + + public void keyboardEvent(boolean buttonDown, short keyCode) { + short keyMap = keybTranslator.translate(keyCode); + if (keyMap != 0) { + if (handleMagicKeyCombos(keyMap, buttonDown)) { + return; + } + + if (buttonDown) { + keybTranslator.sendKeyDown(keyMap, (byte) 0); + } + else { + keybTranslator.sendKeyUp(keyMap, (byte) 0); + } + } + } } diff --git a/src/com/limelight/binding/input/evdev/EvdevWatcher.java b/src/com/limelight/binding/input/evdev/EvdevWatcher.java index 806901ec..67a5050c 100644 --- a/src/com/limelight/binding/input/evdev/EvdevWatcher.java +++ b/src/com/limelight/binding/input/evdev/EvdevWatcher.java @@ -2,6 +2,7 @@ package com.limelight.binding.input.evdev; import java.io.File; import java.util.HashMap; +import java.util.Map; import com.limelight.LimeLog; @@ -14,6 +15,7 @@ public class EvdevWatcher { private HashMap handlers = new HashMap(); private boolean shutdown = false; private boolean init = false; + private boolean ungrabbed = false; private EvdevListener listener; private Thread startThread; @@ -42,7 +44,11 @@ public class EvdevWatcher { } EvdevHandler handler = new EvdevHandler(PATH + "/" + fileName, listener); - handler.start(); + + // If we're ungrabbed now, don't start the handler + if (!ungrabbed) { + handler.start(); + } handlers.put(fileName, handler); } @@ -78,6 +84,31 @@ public class EvdevWatcher { return files; } + public void ungrabAll() { + synchronized (handlers) { + // Note that we're ungrabbed for now + ungrabbed = true; + + // Stop all handlers + for (EvdevHandler handler : handlers.values()) { + handler.stop(); + } + } + } + + public void regrabAll() { + synchronized (handlers) { + // We're regrabbing everything now + ungrabbed = false; + + for (Map.Entry entry : handlers.entrySet()) { + // We need to recreate each entry since we can't reuse a stopped one + entry.setValue(new EvdevHandler(PATH + "/" + entry.getKey(), listener)); + entry.getValue().start(); + } + } + } + public void start() { startThread = new Thread() { @Override @@ -119,10 +150,15 @@ public class EvdevWatcher { // Stop the observer observer.stopWatching(); - synchronized (handlers) { + synchronized (handlers) { // Stop creating new handlers shutdown = true; + // If we've already ungrabbed, there's nothing else to do + if (ungrabbed) { + return; + } + // Stop all handlers for (EvdevHandler handler : handlers.values()) { handler.stop(); From 67e22fca6bba2ea9381bf31508faddbd31646718 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 3 Oct 2014 22:49:36 -0700 Subject: [PATCH 7/9] Improve re-hiding of the system UI by using a proper system UI visibility listener --- src/com/limelight/Game.java | 50 +++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index 15e82d51..e0e42345 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -35,6 +35,7 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnGenericMotionListener; +import android.view.View.OnSystemUiVisibilityChangeListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.Window; @@ -43,7 +44,8 @@ import android.widget.Toast; public class Game extends Activity implements SurfaceHolder.Callback, - OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener + OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener, + OnSystemUiVisibilityChangeListener { private int lastMouseX = Integer.MIN_VALUE; private int lastMouseY = Integer.MIN_VALUE; @@ -138,6 +140,9 @@ public class Game extends Activity implements SurfaceHolder.Callback, getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); } + // Listen for UI visibility events + getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this); + // Change volume button behavior setVolumeControlStream(AudioManager.STREAM_MUSIC); @@ -275,11 +280,11 @@ public class Game extends Activity implements SurfaceHolder.Callback, } }; - private void hideSystemUi() { + private void hideSystemUi(int delay) { Handler h = getWindow().getDecorView().getHandler(); if (h != null) { h.removeCallbacks(hideSystemUi); - h.postDelayed(hideSystemUi, 1000); + h.postDelayed(hideSystemUi, delay); } } @@ -453,16 +458,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - // Pressing a volume button drops the immersive flag so the UI shows up again and doesn't - // go away. I'm not sure if that's a bug or a feature, but we're working around it here - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - Handler h = getWindow().getDecorView().getHandler(); - if (h != null) { - h.removeCallbacks(hideSystemUi); - h.postDelayed(hideSystemUi, 2000); - } - } - InputDevice dev = event.getDevice(); if (dev == null) { return super.onKeyUp(keyCode, event); @@ -705,8 +700,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, if (!displayedFailureDialog) { displayedFailureDialog = true; - Dialog.displayDialog(this, "Connection Error", "Starting "+stage.getName()+" failed", true); stopConnection(); + Dialog.displayDialog(this, "Connection Error", "Starting "+stage.getName()+" failed", true); } } @@ -716,8 +711,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, displayedFailureDialog = true; e.printStackTrace(); - Dialog.displayDialog(this, "Connection Terminated", "The connection failed unexpectedly", true); stopConnection(); + Dialog.displayDialog(this, "Connection Terminated", "The connection failed unexpectedly", true); } } @@ -731,7 +726,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, connecting = false; connected = true; - hideSystemUi(); + hideSystemUi(1000); } @Override @@ -836,4 +831,27 @@ public class Game extends Activity implements SurfaceHolder.Callback, } } } + + @Override + public void onSystemUiVisibilityChange(int visibility) { + // Don't do anything if we're not connected + if (!connected) { + return; + } + + // This flag is set for all devices + if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { + hideSystemUi(2000); + } + // This flag is only set on 4.4+ + else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && + (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { + hideSystemUi(2000); + } + // This flag is only set before 4.4+ + else if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT && + (visibility & View.SYSTEM_UI_FLAG_LOW_PROFILE) == 0) { + hideSystemUi(2000); + } + } } From 645ea683ee4a51f61819488ec5a90dbe136e9f2b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 3 Oct 2014 22:52:48 -0700 Subject: [PATCH 8/9] Increase the minimum deadzone to 12% because I'm paranoid --- .../limelight/binding/input/ControllerHandler.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/com/limelight/binding/input/ControllerHandler.java b/src/com/limelight/binding/input/ControllerHandler.java index 471ff411..a84ed130 100644 --- a/src/com/limelight/binding/input/ControllerHandler.java +++ b/src/com/limelight/binding/input/ControllerHandler.java @@ -143,9 +143,9 @@ public class ControllerHandler { if (mapping.leftStickDeadzoneRadius < 0.02f) { mapping.leftStickDeadzoneRadius = 0.20f; } - // Check that the deadzone is 10% at minimum - else if (mapping.leftStickDeadzoneRadius < 0.10f) { - mapping.leftStickDeadzoneRadius = 0.10f; + // Check that the deadzone is 12% at minimum + else if (mapping.leftStickDeadzoneRadius < 0.12f) { + mapping.leftStickDeadzoneRadius = 0.12f; } } } @@ -160,9 +160,9 @@ public class ControllerHandler { if (mapping.rightStickDeadzoneRadius < 0.02f) { mapping.rightStickDeadzoneRadius = 0.20f; } - // Check that the deadzone is 10% at minimum - else if (mapping.rightStickDeadzoneRadius < 0.10f) { - mapping.rightStickDeadzoneRadius = 0.10f; + // Check that the deadzone is 12% at minimum + else if (mapping.rightStickDeadzoneRadius < 0.12f) { + mapping.rightStickDeadzoneRadius = 0.12f; } } } From f56b7ff79ea2f252d9e83eec598e29abe23db177 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 3 Oct 2014 22:56:30 -0700 Subject: [PATCH 9/9] Bump to 2.5.6 --- AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3b5530ef..d7056e70 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:versionName="2.5.6" >