Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(527)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java

Issue 2322623002: [Remoting Android] Refactor GlDesktopView (Closed)
Patch Set: Add RenderController Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting; 5 package org.chromium.chromoting;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.graphics.Matrix; 8 import android.graphics.Matrix;
9 import android.graphics.PointF; 9 import android.graphics.PointF;
10 import android.graphics.Rect; 10 import android.graphics.Rect;
11 import android.view.GestureDetector; 11 import android.view.GestureDetector;
12 import android.view.MotionEvent; 12 import android.view.MotionEvent;
13 import android.view.ScaleGestureDetector; 13 import android.view.ScaleGestureDetector;
14 import android.view.ViewConfiguration; 14 import android.view.ViewConfiguration;
15 15
16 /** 16 /**
17 * This class is responsible for handling Touch input from the user. Touch even ts which manipulate 17 * This class is responsible for handling Touch input from the user. Touch even ts which manipulate
18 * the local canvas are handled in this class and any input which should be sent to the remote host 18 * the local canvas are handled in this class and any input which should be sent to the remote host
19 * are passed to the InputStrategyInterface implementation set by the DesktopVie w. 19 * are passed to the InputStrategyInterface implementation set by the DesktopVie w.
20 */ 20 */
21 public class TouchInputHandler { 21 public class TouchInputHandler {
22 private static final float EPSILON = 0.001f; 22 private static final float EPSILON = 0.001f;
23 23
24 private final DesktopView mViewer; 24 private final DesktopView mViewer;
25 private final Context mContext; 25 private final Context mContext;
26 private final RenderData mRenderData; 26 private final RenderData mRenderData;
27 private final DesktopCanvas mDesktopCanvas; 27 private DesktopCanvas mDesktopCanvas;
Hzj_jie 2016/09/08 21:37:33 Once init function has been removed, these fields
Yuwei 2016/09/08 23:09:15 Done. Made everything final-able final.
28 private InputStrategyInterface mInputStrategy; 28 private InputStrategyInterface mInputStrategy;
29 private RenderStub mRenderStub;
29 30
30 private GestureDetector mScroller; 31 private GestureDetector mScroller;
31 private ScaleGestureDetector mZoomer; 32 private ScaleGestureDetector mZoomer;
32 private TapGestureDetector mTapDetector; 33 private TapGestureDetector mTapDetector;
33 34
34 /** Used to disambiguate a 2-finger gesture as a swipe or a pinch. */ 35 /** Used to disambiguate a 2-finger gesture as a swipe or a pinch. */
35 private SwipePinchDetector mSwipePinchDetector; 36 private SwipePinchDetector mSwipePinchDetector;
36 37
37 // Used for processing cursor & scroller fling animations. 38 // Used for processing cursor & scroller fling animations.
38 // May consider using a List of AnimationJob if we have more than two animat ion jobs in 39 // May consider using a List of AnimationJob if we have more than two animat ion jobs in
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 * trigger more swipe actions. 87 * trigger more swipe actions.
87 */ 88 */
88 private boolean mSwipeCompleted = false; 89 private boolean mSwipeCompleted = false;
89 90
90 /** 91 /**
91 * Set to true when a 1 finger pan gesture originates with a longpress. Thi s means the user 92 * Set to true when a 1 finger pan gesture originates with a longpress. Thi s means the user
92 * is performing a drag operation. 93 * is performing a drag operation.
93 */ 94 */
94 private boolean mIsDragging = false; 95 private boolean mIsDragging = false;
95 96
97 private boolean mValid = false;
98
96 private Event.ParameterCallback<Boolean, Void> mProcessAnimationCallback; 99 private Event.ParameterCallback<Boolean, Void> mProcessAnimationCallback;
97 100
98 /** 101 /**
99 * This class implements fling animation for cursor 102 * This class implements fling animation for cursor
100 */ 103 */
101 private class CursorAnimationJob extends FlingAnimationJob { 104 private class CursorAnimationJob extends FlingAnimationJob {
102 public CursorAnimationJob(Context context) { 105 public CursorAnimationJob(Context context) {
103 super(context); 106 super(context);
104 } 107 }
105 108
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 @Override 180 @Override
178 public boolean isIndirectInputMode() { 181 public boolean isIndirectInputMode() {
179 return false; 182 return false;
180 } 183 }
181 } 184 }
182 185
183 public TouchInputHandler(DesktopView viewer, Context context) { 186 public TouchInputHandler(DesktopView viewer, Context context) {
184 mViewer = viewer; 187 mViewer = viewer;
185 mContext = context; 188 mContext = context;
186 mRenderData = new RenderData(); 189 mRenderData = new RenderData();
187 mDesktopCanvas = new DesktopCanvas(mViewer, mRenderData);
188 190
189 GestureListener listener = new GestureListener(); 191 GestureListener listener = new GestureListener();
190 mScroller = new GestureDetector(context, listener, null, false); 192 mScroller = new GestureDetector(context, listener, null, false);
191 193
192 // If long-press is enabled, the gesture-detector will not emit any furt her onScroll 194 // If long-press is enabled, the gesture-detector will not emit any furt her onScroll
193 // notifications after the onLongPress notification. Since onScroll is b eing used for 195 // notifications after the onLongPress notification. Since onScroll is b eing used for
194 // moving the cursor, it means that the cursor would become stuck if the finger were held 196 // moving the cursor, it means that the cursor would become stuck if the finger were held
195 // down too long. 197 // down too long.
196 mScroller.setIsLongpressEnabled(false); 198 mScroller.setIsLongpressEnabled(false);
197 199
(...skipping 13 matching lines...) Expand all
211 213
212 mCursorAnimationJob = new CursorAnimationJob(context); 214 mCursorAnimationJob = new CursorAnimationJob(context);
213 mScrollAnimationJob = new ScrollAnimationJob(context); 215 mScrollAnimationJob = new ScrollAnimationJob(context);
214 216
215 mProcessAnimationCallback = new Event.ParameterCallback<Boolean, Void>() { 217 mProcessAnimationCallback = new Event.ParameterCallback<Boolean, Void>() {
216 @Override 218 @Override
217 public Boolean run(Void p) { 219 public Boolean run(Void p) {
218 return processAnimation(); 220 return processAnimation();
219 } 221 }
220 }; 222 };
221
222 attachViewEvents(viewer);
223 } 223 }
224 224
225 /** 225 /**
226 * Steps forward the animation. 226 * Steps forward the animation.
227 * @return true if the animation is not finished yet. 227 * @return true if the animation is not finished yet.
228 */ 228 */
229 private boolean processAnimation() { 229 private boolean processAnimation() {
230 return mCursorAnimationJob.processAnimation() || mScrollAnimationJob.pro cessAnimation(); 230 return mCursorAnimationJob.processAnimation() || mScrollAnimationJob.pro cessAnimation();
231 } 231 }
232 232
233 /** 233 /**
234 * Start stepping animation when onCanvasRendered is triggered. 234 * Start stepping animation when onCanvasRendered is triggered.
235 */ 235 */
236 private void startAnimation() { 236 private void startAnimation() {
237 mViewer.onCanvasRendered().addSelfRemovable(mProcessAnimationCallback); 237 mRenderStub.onCanvasRendered().addSelfRemovable(mProcessAnimationCallbac k);
238 } 238 }
239 239
240 /** 240 /**
241 * Abort all animations. 241 * Abort all animations.
242 */ 242 */
243 private void abortAnimation() { 243 private void abortAnimation() {
244 mCursorAnimationJob.abortAnimation(); 244 mCursorAnimationJob.abortAnimation();
245 mScrollAnimationJob.abortAnimation(); 245 mScrollAnimationJob.abortAnimation();
246 } 246 }
247 247
248 public void init(Desktop desktop, final InputEventSender injector) { 248 public void init(Desktop desktop, RenderStub renderStub, final InputEventSen der injector) {
249 Preconditions.notNull(injector); 249 Preconditions.notNull(injector);
250 desktop.onInputModeChanged().add( 250 Preconditions.notNull(renderStub);
251 new Event.ParameterRunnable<InputModeChangedEventParameter>() { 251 mRenderStub = renderStub;
252 mDesktopCanvas = new DesktopCanvas(renderStub, mRenderData);
253
254 mValid = true;
joedow 2016/09/08 18:32:47 Can't you just detach the event handlers / remove
Yuwei 2016/09/08 19:12:16 The reason was that I didn't want to have a lot of
Hzj_jie 2016/09/08 21:37:33 Emmm ... Seems you are writing more codes by using
Yuwei 2016/09/08 23:09:15 s/HashMap/list of listener-event pairs/
Yuwei 2016/09/08 23:09:15 Simplified.
255
256 mViewer.onTouch().addSelfRemovable(
257 new Event.ParameterCallback<Boolean, TouchEventParameter>() {
252 @Override 258 @Override
253 public void run(InputModeChangedEventParameter parameter) { 259 public Boolean run(TouchEventParameter parameter) {
254 handleInputModeChanged(parameter, injector); 260 if (!mValid) {
261 return false;
262 }
263 parameter.handled = handleTouchEvent(parameter.event);
264 return true;
255 } 265 }
256 }); 266 });
257 267
258 desktop.onSystemUiVisibilityChanged().add( 268 desktop.onInputModeChanged().addSelfRemovable(
259 new Event.ParameterRunnable<SystemUiVisibilityChangedEventParame ter>() { 269 new Event.ParameterCallback<Boolean, InputModeChangedEventParame ter>() {
260 @Override 270 @Override
261 public void run(SystemUiVisibilityChangedEventParameter para meter) { 271 public Boolean run(InputModeChangedEventParameter parameter) {
272 if (!mValid) {
273 return false;
274 }
275 handleInputModeChanged(parameter, injector);
276 return true;
277 }
278 });
279
280 desktop.onSystemUiVisibilityChanged().addSelfRemovable(
281 new Event.ParameterCallback<Boolean, SystemUiVisibilityChangedEv entParameter>() {
282 @Override
283 public Boolean run(SystemUiVisibilityChangedEventParameter p arameter) {
284 if (!mValid) {
285 return false;
286 }
262 handleSystemUiVisibilityChanged(parameter); 287 handleSystemUiVisibilityChanged(parameter);
288 return true;
289 }
290 });
291
292 renderStub.onClientSizeChanged().addSelfRemovable(
293 new Event.ParameterCallback<Boolean, SizeChangedEventParameter>( ) {
294 @Override
295 public Boolean run(SizeChangedEventParameter parameter) {
296 if (!mValid) {
297 return false;
298 }
299 handleClientSizeChanged(parameter.width, parameter.heigh t);
300 return true;
301 }
302 });
303
304 renderStub.onHostSizeChanged().addSelfRemovable(
305 new Event.ParameterCallback<Boolean, SizeChangedEventParameter>( ) {
306 @Override
307 public Boolean run(SizeChangedEventParameter parameter) {
308 if (!mValid) {
309 return false;
310 }
311 handleHostSizeChanged(parameter.width, parameter.height) ;
312 return true;
263 } 313 }
264 }); 314 });
265 } 315 }
266 316
267 private void attachViewEvents(DesktopView viewer) { 317 public void invalidate() {
268 viewer.onTouch().add(new Event.ParameterRunnable<TouchEventParameter>() { 318 mValid = false;
269 @Override
270 public void run(TouchEventParameter parameter) {
271 parameter.handled = handleTouchEvent(parameter.event);
272 }
273 });
274 viewer.onClientSizeChanged().add(new Event.ParameterRunnable<SizeChanged EventParameter>() {
275 @Override
276 public void run(SizeChangedEventParameter parameter) {
277 handleClientSizeChanged(parameter.width, parameter.height);
278 }
279 });
280 viewer.onHostSizeChanged().add(new Event.ParameterRunnable<SizeChangedEv entParameter>() {
281 @Override
282 public void run(SizeChangedEventParameter parameter) {
283 handleHostSizeChanged(parameter.width, parameter.height);
284 }
285 });
286 } 319 }
287 320
288 private void handleInputModeChanged( 321 private void handleInputModeChanged(
289 InputModeChangedEventParameter parameter, InputEventSender injector) { 322 InputModeChangedEventParameter parameter, InputEventSender injector) {
290 final Desktop.InputMode inputMode = parameter.inputMode; 323 final Desktop.InputMode inputMode = parameter.inputMode;
291 final CapabilityManager.HostCapability hostTouchCapability = 324 final CapabilityManager.HostCapability hostTouchCapability =
292 parameter.hostCapability; 325 parameter.hostCapability;
293 // We need both input mode and host input capabilities to select the inp ut 326 // We need both input mode and host input capabilities to select the inp ut
294 // strategy. 327 // strategy.
295 if (!inputMode.isSet() || !hostTouchCapability.isSet()) { 328 if (!inputMode.isSet() || !hostTouchCapability.isSet()) {
(...skipping 13 matching lines...) Expand all
309 new SimulatedTouchInputStrategy(mRenderData, injecto r, mContext)); 342 new SimulatedTouchInputStrategy(mRenderData, injecto r, mContext));
310 } 343 }
311 break; 344 break;
312 345
313 default: 346 default:
314 // Unreachable, but required by Google Java style and findbugs. 347 // Unreachable, but required by Google Java style and findbugs.
315 assert false : "Unreached"; 348 assert false : "Unreached";
316 } 349 }
317 350
318 // Ensure the cursor state is updated appropriately. 351 // Ensure the cursor state is updated appropriately.
319 mViewer.cursorVisibilityChanged(mRenderData.drawCursor); 352 mRenderStub.setCursorVisibility(mRenderData.drawCursor);
320 } 353 }
321 354
322 private void handleSystemUiVisibilityChanged( 355 private void handleSystemUiVisibilityChanged(
323 SystemUiVisibilityChangedEventParameter parameter) { 356 SystemUiVisibilityChangedEventParameter parameter) {
324 if (parameter.softInputMethodVisible) { 357 if (parameter.softInputMethodVisible) {
325 mDesktopCanvas.setSystemUiOffsetValues(parameter.left, parameter.top , 358 mDesktopCanvas.setSystemUiOffsetValues(parameter.left, parameter.top ,
326 mRenderData.screenWidth - parameter.right, 359 mRenderData.screenWidth - parameter.right,
327 mRenderData.screenHeight - parameter.bottom); 360 mRenderData.screenHeight - parameter.bottom);
328 } else { 361 } else {
329 mDesktopCanvas.setSystemUiOffsetValues(0, 0, 0, 0); 362 mDesktopCanvas.setSystemUiOffsetValues(0, 0, 0, 0);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 moveCursor(imagePoint[0], imagePoint[1]); 463 moveCursor(imagePoint[0], imagePoint[1]);
431 } 464 }
432 465
433 /** Moves the cursor to the specified position on the remote host. */ 466 /** Moves the cursor to the specified position on the remote host. */
434 private void moveCursor(float newX, float newY) { 467 private void moveCursor(float newX, float newY) {
435 boolean cursorMoved = mRenderData.setCursorPosition(newX, newY); 468 boolean cursorMoved = mRenderData.setCursorPosition(newX, newY);
436 if (cursorMoved) { 469 if (cursorMoved) {
437 mInputStrategy.injectCursorMoveEvent((int) newX, (int) newY); 470 mInputStrategy.injectCursorMoveEvent((int) newX, (int) newY);
438 } 471 }
439 472
440 mViewer.cursorMoved(mRenderData.getCursorPosition()); 473 mRenderStub.moveCursor(mRenderData.getCursorPosition());
441 } 474 }
442 475
443 /** Processes a (multi-finger) swipe gesture. */ 476 /** Processes a (multi-finger) swipe gesture. */
444 private boolean onSwipe() { 477 private boolean onSwipe() {
445 if (mTotalMotionY > mSwipeThreshold) { 478 if (mTotalMotionY > mSwipeThreshold) {
446 // Swipe down occurred. 479 // Swipe down occurred.
447 mViewer.showActionBar(); 480 mViewer.showActionBar();
448 } else if (mTotalMotionY < -mSwipeThreshold) { 481 } else if (mTotalMotionY < -mSwipeThreshold) {
449 // Swipe up occurred. 482 // Swipe up occurred.
450 mViewer.showKeyboard(); 483 mViewer.showKeyboard();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 if (!mInputStrategy.isIndirectInputMode()) { 642 if (!mInputStrategy.isIndirectInputMode()) {
610 if (screenPointLiesOutsideImageBoundary(x, y)) { 643 if (screenPointLiesOutsideImageBoundary(x, y)) {
611 return false; 644 return false;
612 } 645 }
613 moveCursorToScreenPoint(x, y); 646 moveCursorToScreenPoint(x, y);
614 } 647 }
615 648
616 if (mInputStrategy.onTap(button)) { 649 if (mInputStrategy.onTap(button)) {
617 PointF pos = mRenderData.getCursorPosition(); 650 PointF pos = mRenderData.getCursorPosition();
618 651
619 mViewer.showInputFeedback(mInputStrategy.getShortPressFeedbackTy pe(), pos); 652 mRenderStub.showInputFeedback(mInputStrategy.getShortPressFeedba ckType(), pos);
620 } 653 }
621 return true; 654 return true;
622 } 655 }
623 656
624 /** Called when a long-press is triggered for one or more fingers. */ 657 /** Called when a long-press is triggered for one or more fingers. */
625 @Override 658 @Override
626 public void onLongPress(int pointerCount, float x, float y) { 659 public void onLongPress(int pointerCount, float x, float y) {
627 int button = mouseButtonFromPointerCount(pointerCount); 660 int button = mouseButtonFromPointerCount(pointerCount);
628 if (button == InputStub.BUTTON_UNDEFINED) { 661 if (button == InputStub.BUTTON_UNDEFINED) {
629 return; 662 return;
630 } 663 }
631 664
632 if (!mInputStrategy.isIndirectInputMode()) { 665 if (!mInputStrategy.isIndirectInputMode()) {
633 if (screenPointLiesOutsideImageBoundary(x, y)) { 666 if (screenPointLiesOutsideImageBoundary(x, y)) {
634 return; 667 return;
635 } 668 }
636 moveCursorToScreenPoint(x, y); 669 moveCursorToScreenPoint(x, y);
637 } 670 }
638 671
639 if (mInputStrategy.onPressAndHold(button)) { 672 if (mInputStrategy.onPressAndHold(button)) {
640 PointF pos = mRenderData.getCursorPosition(); 673 PointF pos = mRenderData.getCursorPosition();
641 674
642 mViewer.showInputFeedback(mInputStrategy.getLongPressFeedbackTyp e(), pos); 675 mRenderStub.showInputFeedback(mInputStrategy.getLongPressFeedbac kType(), pos);
643 mSuppressFling = true; 676 mSuppressFling = true;
644 mIsDragging = true; 677 mIsDragging = true;
645 } 678 }
646 } 679 }
647 680
648 /** Maps the number of fingers in a tap or long-press gesture to a mouse -button. */ 681 /** Maps the number of fingers in a tap or long-press gesture to a mouse -button. */
649 private int mouseButtonFromPointerCount(int pointerCount) { 682 private int mouseButtonFromPointerCount(int pointerCount) {
650 switch (pointerCount) { 683 switch (pointerCount) {
651 case 1: 684 case 1:
652 return InputStub.BUTTON_LEFT; 685 return InputStub.BUTTON_LEFT;
(...skipping 11 matching lines...) Expand all
664 float[] mappedPoints = mapScreenPointToImagePoint(screenX, screenY); 697 float[] mappedPoints = mapScreenPointToImagePoint(screenX, screenY);
665 698
666 float imageWidth = (float) mRenderData.imageWidth + EPSILON; 699 float imageWidth = (float) mRenderData.imageWidth + EPSILON;
667 float imageHeight = (float) mRenderData.imageHeight + EPSILON; 700 float imageHeight = (float) mRenderData.imageHeight + EPSILON;
668 701
669 return mappedPoints[0] < -EPSILON || mappedPoints[0] > imageWidth 702 return mappedPoints[0] < -EPSILON || mappedPoints[0] > imageWidth
670 || mappedPoints[1] < -EPSILON || mappedPoints[1] > imageHeig ht; 703 || mappedPoints[1] < -EPSILON || mappedPoints[1] > imageHeig ht;
671 } 704 }
672 } 705 }
673 } 706 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698