diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index 66ab22d6..536469d0 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -84,6 +84,7 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Locale; +import java.util.Timer; public class Game extends Activity implements SurfaceHolder.Callback, @@ -94,6 +95,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, private int lastButtonState = 0; // Only 2 touches are supported + private Timer touchTimer; private final TouchContext[] touchContextMap = new TouchContext[2]; private long threeFingerDownTime = 0; @@ -477,14 +479,15 @@ public class Game extends Activity implements SurfaceHolder.Callback, inputManager.registerInputDeviceListener(keyboardTranslator, null); // Initialize touch contexts + touchTimer = new Timer("TouchTimer", true); for (int i = 0; i < touchContextMap.length; i++) { if (!prefConfig.touchscreenTrackpad) { - touchContextMap[i] = new AbsoluteTouchContext(conn, i, streamView); + touchContextMap[i] = new AbsoluteTouchContext(conn, i, streamView, touchTimer); } else { touchContextMap[i] = new RelativeTouchContext(conn, i, REFERENCE_HORIZ_RES, REFERENCE_VERT_RES, - streamView, prefConfig); + streamView, prefConfig, touchTimer); } } @@ -1028,6 +1031,10 @@ public class Game extends Activity implements SurfaceHolder.Callback, protected void onDestroy() { super.onDestroy(); + if (touchTimer != null) { + touchTimer.cancel(); + } + InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE); if (controllerHandler != null) { inputManager.unregisterInputDeviceListener(controllerHandler); diff --git a/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java b/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java index cfc76591..89ffff70 100644 --- a/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/touch/AbsoluteTouchContext.java @@ -22,12 +22,13 @@ public class AbsoluteTouchContext implements TouchContext { private boolean cancelled; private boolean confirmedLongPress; private boolean confirmedTap; - private Timer longPressTimer; - private Timer tapDownTimer; + private TimerTask longPressTimerTask; + private TimerTask tapDownTimerTask; private final NvConnection conn; private final int actionIndex; private final View targetView; + private final Timer timer; private final Handler handler; private final Runnable leftButtonUpRunnable = new Runnable() { @@ -48,11 +49,12 @@ public class AbsoluteTouchContext implements TouchContext { private static final int TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD = 100; private static final int TOUCH_DOWN_DEAD_ZONE_DISTANCE_THRESHOLD = 20; - public AbsoluteTouchContext(NvConnection conn, int actionIndex, View view) + public AbsoluteTouchContext(NvConnection conn, int actionIndex, View view, Timer timer) { this.conn = conn; this.actionIndex = actionIndex; this.targetView = view; + this.timer = timer; this.handler = new Handler(Looper.getMainLooper()); } @@ -137,18 +139,18 @@ public class AbsoluteTouchContext implements TouchContext { } private synchronized void startLongPressTimer() { - longPressTimer = new Timer(true); - longPressTimer.schedule(new TimerTask() { + cancelLongPressTimer(); + longPressTimerTask = new TimerTask() { @Override public void run() { synchronized (AbsoluteTouchContext.this) { // Check if someone cancelled us - if (longPressTimer == null) { + if (longPressTimerTask == null) { return; } // Uncancellable now - longPressTimer = null; + longPressTimerTask = null; // This timer should have already expired, but cancel it just in case cancelTapDownTimer(); @@ -161,41 +163,43 @@ public class AbsoluteTouchContext implements TouchContext { conn.sendMouseButtonDown(MouseButtonPacket.BUTTON_RIGHT); } } - }, LONG_PRESS_TIME_THRESHOLD); + }; + timer.schedule(longPressTimerTask, LONG_PRESS_TIME_THRESHOLD); } private synchronized void cancelLongPressTimer() { - if (longPressTimer != null) { - longPressTimer.cancel(); - longPressTimer = null; + if (longPressTimerTask != null) { + longPressTimerTask.cancel(); + longPressTimerTask = null; } } private synchronized void startTapDownTimer() { - tapDownTimer = new Timer(true); - tapDownTimer.schedule(new TimerTask() { + cancelTapDownTimer(); + tapDownTimerTask = new TimerTask() { @Override public void run() { synchronized (AbsoluteTouchContext.this) { // Check if someone cancelled us - if (tapDownTimer == null) { + if (tapDownTimerTask == null) { return; } // Uncancellable now - tapDownTimer = null; + tapDownTimerTask = null; // Start our tap tapConfirmed(); } } - }, TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD); + }; + timer.schedule(tapDownTimerTask, TOUCH_DOWN_DEAD_ZONE_TIME_THRESHOLD); } private synchronized void cancelTapDownTimer() { - if (tapDownTimer != null) { - tapDownTimer.cancel(); - tapDownTimer = null; + if (tapDownTimerTask != null) { + tapDownTimerTask.cancel(); + tapDownTimerTask = null; } } diff --git a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java index 2d619919..b5a4ecdf 100644 --- a/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/touch/RelativeTouchContext.java @@ -21,7 +21,7 @@ public class RelativeTouchContext implements TouchContext { private boolean confirmedMove; private boolean confirmedDrag; private boolean confirmedScroll; - private Timer dragTimer; + private TimerTask dragTimerTask; private double distanceMoved; private double xFactor, yFactor; private int pointerCount; @@ -33,6 +33,7 @@ public class RelativeTouchContext implements TouchContext { private final int referenceHeight; private final View targetView; private final PreferenceConfiguration prefConfig; + private final Timer timer; private final Handler handler; // Indexed by MouseButtonPacket.BUTTON_XXX - 1 @@ -78,7 +79,8 @@ public class RelativeTouchContext implements TouchContext { public RelativeTouchContext(NvConnection conn, int actionIndex, int referenceWidth, int referenceHeight, - View view, PreferenceConfiguration prefConfig) + View view, PreferenceConfiguration prefConfig, + Timer timer) { this.conn = conn; this.actionIndex = actionIndex; @@ -86,6 +88,7 @@ public class RelativeTouchContext implements TouchContext { this.referenceHeight = referenceHeight; this.targetView = view; this.prefConfig = prefConfig; + this.timer = timer; this.handler = new Handler(Looper.getMainLooper()); } @@ -185,11 +188,8 @@ public class RelativeTouchContext implements TouchContext { } private synchronized void startDragTimer() { - // Cancel any existing drag timers cancelDragTimer(); - - dragTimer = new Timer(true); - dragTimer.schedule(new TimerTask() { + dragTimerTask = new TimerTask() { @Override public void run() { synchronized (RelativeTouchContext.this) { @@ -204,25 +204,26 @@ public class RelativeTouchContext implements TouchContext { } // Check if someone cancelled us - if (dragTimer == null) { + if (dragTimerTask == null) { return; } // Uncancellable now - dragTimer = null; + dragTimerTask = null; // We haven't been cancelled before the timer expired so begin dragging confirmedDrag = true; conn.sendMouseButtonDown(getMouseButtonIndex()); } } - }, DRAG_TIME_THRESHOLD); + }; + timer.schedule(dragTimerTask, DRAG_TIME_THRESHOLD); } private synchronized void cancelDragTimer() { - if (dragTimer != null) { - dragTimer.cancel(); - dragTimer = null; + if (dragTimerTask != null) { + dragTimerTask.cancel(); + dragTimerTask = null; } }