| OLD | NEW |
| 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.Point; | 9 import android.graphics.Point; |
| 10 import android.graphics.PointF; | 10 import android.graphics.PointF; |
| 11 import android.graphics.Rect; | 11 import android.graphics.Rect; |
| 12 import android.view.GestureDetector; | 12 import android.view.GestureDetector; |
| 13 import android.view.MotionEvent; | 13 import android.view.MotionEvent; |
| 14 import android.view.ScaleGestureDetector; | 14 import android.view.ScaleGestureDetector; |
| 15 import android.view.ViewConfiguration; | 15 import android.view.ViewConfiguration; |
| 16 | 16 |
| 17 import org.chromium.chromoting.jni.Client; | |
| 18 | |
| 19 /** | 17 /** |
| 20 * This class is responsible for handling Touch input from the user. Touch even
ts which manipulate | 18 * This class is responsible for handling Touch input from the user. Touch even
ts which manipulate |
| 21 * the local canvas are handled in this class and any input which should be sent
to the remote host | 19 * the local canvas are handled in this class and any input which should be sent
to the remote host |
| 22 * are passed to the InputStrategyInterface implementation set by the DesktopVie
w. | 20 * are passed to the InputStrategyInterface implementation set by the DesktopVie
w. |
| 23 */ | 21 */ |
| 24 public class TouchInputHandler implements TouchInputHandlerInterface { | 22 public class TouchInputHandler { |
| 25 private final DesktopViewInterface mViewer; | 23 private final DesktopViewInterface mViewer; |
| 26 private final Context mContext; | 24 private final Context mContext; |
| 27 private final RenderData mRenderData; | 25 private final RenderData mRenderData; |
| 28 private final DesktopCanvas mDesktopCanvas; | 26 private final DesktopCanvas mDesktopCanvas; |
| 29 private InputStrategyInterface mInputStrategy; | 27 private InputStrategyInterface mInputStrategy; |
| 30 | 28 |
| 31 private GestureDetector mScroller; | 29 private GestureDetector mScroller; |
| 32 private ScaleGestureDetector mZoomer; | 30 private ScaleGestureDetector mZoomer; |
| 33 private TapGestureDetector mTapDetector; | 31 private TapGestureDetector mTapDetector; |
| 34 | 32 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 mEdgeSlopInPx = ViewConfiguration.get(context).getScaledEdgeSlop(); | 207 mEdgeSlopInPx = ViewConfiguration.get(context).getScaledEdgeSlop(); |
| 210 | 208 |
| 211 mInputStrategy = new NullInputStrategy(); | 209 mInputStrategy = new NullInputStrategy(); |
| 212 | 210 |
| 213 mCursorAnimationJob = new CursorAnimationJob(context); | 211 mCursorAnimationJob = new CursorAnimationJob(context); |
| 214 mScrollAnimationJob = new ScrollAnimationJob(context); | 212 mScrollAnimationJob = new ScrollAnimationJob(context); |
| 215 | 213 |
| 216 attachViewEvents(viewer); | 214 attachViewEvents(viewer); |
| 217 } | 215 } |
| 218 | 216 |
| 219 @Override | |
| 220 public void processAnimation() { | 217 public void processAnimation() { |
| 221 boolean active = mCursorAnimationJob.processAnimation(); | 218 boolean active = mCursorAnimationJob.processAnimation(); |
| 222 active |= mScrollAnimationJob.processAnimation(); | 219 active |= mScrollAnimationJob.processAnimation(); |
| 223 | 220 |
| 224 if (!active) { | 221 if (!active) { |
| 225 mViewer.setAnimationEnabled(false); | 222 mViewer.setAnimationEnabled(false); |
| 226 } | 223 } |
| 227 } | 224 } |
| 228 | 225 |
| 229 @Override | 226 public void init(Desktop desktop, final InputEventSender injector) { |
| 230 public void init(Desktop desktop, final Client client) { | 227 Preconditions.notNull(injector); |
| 231 Preconditions.notNull(client); | |
| 232 desktop.onInputModeChanged().add( | 228 desktop.onInputModeChanged().add( |
| 233 new Event.ParameterRunnable<InputModeChangedEventParameter>() { | 229 new Event.ParameterRunnable<InputModeChangedEventParameter>() { |
| 234 @Override | 230 @Override |
| 235 public void run(InputModeChangedEventParameter parameter) { | 231 public void run(InputModeChangedEventParameter parameter) { |
| 236 handleInputModeChanged(parameter, client); | 232 handleInputModeChanged(parameter, injector); |
| 237 } | 233 } |
| 238 }); | 234 }); |
| 239 | 235 |
| 240 desktop.onSoftInputMethodVisibilityChanged().add( | 236 desktop.onSoftInputMethodVisibilityChanged().add( |
| 241 new Event.ParameterRunnable<SoftInputMethodVisibilityChangedEven
tParameter>() { | 237 new Event.ParameterRunnable<SoftInputMethodVisibilityChangedEven
tParameter>() { |
| 242 @Override | 238 @Override |
| 243 public void run(SoftInputMethodVisibilityChangedEventParamet
er parameter) { | 239 public void run(SoftInputMethodVisibilityChangedEventParamet
er parameter) { |
| 244 handleSoftInputMethodVisibilityChanged(parameter); | 240 handleSoftInputMethodVisibilityChanged(parameter); |
| 245 } | 241 } |
| 246 }); | 242 }); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 260 } | 256 } |
| 261 }); | 257 }); |
| 262 viewer.onHostSizeChanged().add(new Event.ParameterRunnable<SizeChangedEv
entParameter>() { | 258 viewer.onHostSizeChanged().add(new Event.ParameterRunnable<SizeChangedEv
entParameter>() { |
| 263 @Override | 259 @Override |
| 264 public void run(SizeChangedEventParameter parameter) { | 260 public void run(SizeChangedEventParameter parameter) { |
| 265 handleHostSizeChanged(parameter.width, parameter.height); | 261 handleHostSizeChanged(parameter.width, parameter.height); |
| 266 } | 262 } |
| 267 }); | 263 }); |
| 268 } | 264 } |
| 269 | 265 |
| 270 private void handleInputModeChanged(InputModeChangedEventParameter parameter
, | 266 private void handleInputModeChanged( |
| 271 Client client) { | 267 InputModeChangedEventParameter parameter, InputEventSender injector)
{ |
| 272 final Desktop.InputMode inputMode = parameter.inputMode; | 268 final Desktop.InputMode inputMode = parameter.inputMode; |
| 273 final CapabilityManager.HostCapability hostTouchCapability = | 269 final CapabilityManager.HostCapability hostTouchCapability = |
| 274 parameter.hostCapability; | 270 parameter.hostCapability; |
| 275 // We need both input mode and host input capabilities to select the inp
ut | 271 // We need both input mode and host input capabilities to select the inp
ut |
| 276 // strategy. | 272 // strategy. |
| 277 if (!inputMode.isSet() || !hostTouchCapability.isSet()) { | 273 if (!inputMode.isSet() || !hostTouchCapability.isSet()) { |
| 278 return; | 274 return; |
| 279 } | 275 } |
| 280 | 276 |
| 281 switch (inputMode) { | 277 switch (inputMode) { |
| 282 case TRACKPAD: | 278 case TRACKPAD: |
| 283 setInputStrategy(new TrackpadInputStrategy(mRenderData, client))
; | 279 setInputStrategy(new TrackpadInputStrategy(mRenderData, injector
)); |
| 284 break; | 280 break; |
| 285 | 281 |
| 286 case TOUCH: | 282 case TOUCH: |
| 287 if (hostTouchCapability.isSupported()) { | 283 if (hostTouchCapability.isSupported()) { |
| 288 setInputStrategy(new TouchInputStrategy(mRenderData, client)
); | 284 setInputStrategy(new TouchInputStrategy(mRenderData, injecto
r)); |
| 289 } else { | 285 } else { |
| 290 setInputStrategy(new SimulatedTouchInputStrategy( | 286 setInputStrategy( |
| 291 mRenderData, client, mContext)); | 287 new SimulatedTouchInputStrategy(mRenderData, injecto
r, mContext)); |
| 292 } | 288 } |
| 293 break; | 289 break; |
| 294 | 290 |
| 295 default: | 291 default: |
| 296 // Unreachable, but required by Google Java style and findbugs. | 292 // Unreachable, but required by Google Java style and findbugs. |
| 297 assert false : "Unreached"; | 293 assert false : "Unreached"; |
| 298 } | 294 } |
| 299 | 295 |
| 300 // Ensure the cursor state is updated appropriately. | 296 // Ensure the cursor state is updated appropriately. |
| 301 // TODO (zijiehe): Move repaint control out of DesktopView. | 297 // TODO (zijiehe): Move repaint control out of DesktopView. |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 /** Called when the user is done zooming. Defers to onScale()'s judgemen
t. */ | 588 /** Called when the user is done zooming. Defers to onScale()'s judgemen
t. */ |
| 593 @Override | 589 @Override |
| 594 public void onScaleEnd(ScaleGestureDetector detector) { | 590 public void onScaleEnd(ScaleGestureDetector detector) { |
| 595 onScale(detector); | 591 onScale(detector); |
| 596 } | 592 } |
| 597 | 593 |
| 598 /** Called when the user taps the screen with one or more fingers. */ | 594 /** Called when the user taps the screen with one or more fingers. */ |
| 599 @Override | 595 @Override |
| 600 public boolean onTap(int pointerCount, float x, float y) { | 596 public boolean onTap(int pointerCount, float x, float y) { |
| 601 int button = mouseButtonFromPointerCount(pointerCount); | 597 int button = mouseButtonFromPointerCount(pointerCount); |
| 602 if (button == BUTTON_UNDEFINED) { | 598 if (button == InputStub.BUTTON_UNDEFINED) { |
| 603 return false; | 599 return false; |
| 604 } | 600 } |
| 605 | 601 |
| 606 if (!mInputStrategy.isIndirectInputMode()) { | 602 if (!mInputStrategy.isIndirectInputMode()) { |
| 607 moveCursorToScreenPoint(x, y); | 603 moveCursorToScreenPoint(x, y); |
| 608 } | 604 } |
| 609 | 605 |
| 610 if (mInputStrategy.onTap(button)) { | 606 if (mInputStrategy.onTap(button)) { |
| 611 Point pos; | 607 Point pos; |
| 612 synchronized (mRenderData) { | 608 synchronized (mRenderData) { |
| 613 pos = mRenderData.getCursorPosition(); | 609 pos = mRenderData.getCursorPosition(); |
| 614 } | 610 } |
| 615 mViewer.showInputFeedback(mInputStrategy.getShortPressFeedbackTy
pe(), pos); | 611 mViewer.showInputFeedback(mInputStrategy.getShortPressFeedbackTy
pe(), pos); |
| 616 } | 612 } |
| 617 return true; | 613 return true; |
| 618 } | 614 } |
| 619 | 615 |
| 620 /** Called when a long-press is triggered for one or more fingers. */ | 616 /** Called when a long-press is triggered for one or more fingers. */ |
| 621 @Override | 617 @Override |
| 622 public void onLongPress(int pointerCount, float x, float y) { | 618 public void onLongPress(int pointerCount, float x, float y) { |
| 623 int button = mouseButtonFromPointerCount(pointerCount); | 619 int button = mouseButtonFromPointerCount(pointerCount); |
| 624 if (button == BUTTON_UNDEFINED) { | 620 if (button == InputStub.BUTTON_UNDEFINED) { |
| 625 return; | 621 return; |
| 626 } | 622 } |
| 627 | 623 |
| 628 if (!mInputStrategy.isIndirectInputMode()) { | 624 if (!mInputStrategy.isIndirectInputMode()) { |
| 629 moveCursorToScreenPoint(x, y); | 625 moveCursorToScreenPoint(x, y); |
| 630 } | 626 } |
| 631 | 627 |
| 632 if (mInputStrategy.onPressAndHold(button)) { | 628 if (mInputStrategy.onPressAndHold(button)) { |
| 633 Point pos; | 629 Point pos; |
| 634 synchronized (mRenderData) { | 630 synchronized (mRenderData) { |
| 635 pos = mRenderData.getCursorPosition(); | 631 pos = mRenderData.getCursorPosition(); |
| 636 } | 632 } |
| 637 mViewer.showInputFeedback(mInputStrategy.getLongPressFeedbackTyp
e(), pos); | 633 mViewer.showInputFeedback(mInputStrategy.getLongPressFeedbackTyp
e(), pos); |
| 638 mSuppressFling = true; | 634 mSuppressFling = true; |
| 639 mIsDragging = true; | 635 mIsDragging = true; |
| 640 } | 636 } |
| 641 } | 637 } |
| 642 | 638 |
| 643 /** Maps the number of fingers in a tap or long-press gesture to a mouse
-button. */ | 639 /** Maps the number of fingers in a tap or long-press gesture to a mouse
-button. */ |
| 644 private int mouseButtonFromPointerCount(int pointerCount) { | 640 private int mouseButtonFromPointerCount(int pointerCount) { |
| 645 switch (pointerCount) { | 641 switch (pointerCount) { |
| 646 case 1: | 642 case 1: |
| 647 return BUTTON_LEFT; | 643 return InputStub.BUTTON_LEFT; |
| 648 case 2: | 644 case 2: |
| 649 return BUTTON_RIGHT; | 645 return InputStub.BUTTON_RIGHT; |
| 650 case 3: | 646 case 3: |
| 651 return BUTTON_MIDDLE; | 647 return InputStub.BUTTON_MIDDLE; |
| 652 default: | 648 default: |
| 653 return BUTTON_UNDEFINED; | 649 return InputStub.BUTTON_UNDEFINED; |
| 654 } | 650 } |
| 655 } | 651 } |
| 656 } | 652 } |
| 657 } | 653 } |
| OLD | NEW |