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 |
17 /** | 19 /** |
18 * This class is responsible for handling Touch input from the user. Touch even
ts which manipulate | 20 * This class is responsible for handling Touch input from the user. Touch even
ts which manipulate |
19 * the local canvas are handled in this class and any input which should be sent
to the remote host | 21 * the local canvas are handled in this class and any input which should be sent
to the remote host |
20 * are passed to the InputStrategyInterface implementation set by the DesktopVie
w. | 22 * are passed to the InputStrategyInterface implementation set by the DesktopVie
w. |
21 */ | 23 */ |
22 public class TouchInputHandler implements TouchInputHandlerInterface { | 24 public class TouchInputHandler implements TouchInputHandlerInterface { |
23 private final DesktopViewInterface mViewer; | 25 private final DesktopViewInterface mViewer; |
| 26 private final Context mContext; |
24 private final RenderData mRenderData; | 27 private final RenderData mRenderData; |
25 private final DesktopCanvas mDesktopCanvas; | 28 private final DesktopCanvas mDesktopCanvas; |
26 private InputStrategyInterface mInputStrategy; | 29 private InputStrategyInterface mInputStrategy; |
27 | 30 |
28 private GestureDetector mScroller; | 31 private GestureDetector mScroller; |
29 private ScaleGestureDetector mZoomer; | 32 private ScaleGestureDetector mZoomer; |
30 private TapGestureDetector mTapDetector; | 33 private TapGestureDetector mTapDetector; |
31 | 34 |
32 /** 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. */ |
33 private SwipePinchDetector mSwipePinchDetector; | 36 private SwipePinchDetector mSwipePinchDetector; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 176 } |
174 | 177 |
175 @Override | 178 @Override |
176 public boolean isIndirectInputMode() { | 179 public boolean isIndirectInputMode() { |
177 return false; | 180 return false; |
178 } | 181 } |
179 } | 182 } |
180 | 183 |
181 public TouchInputHandler(DesktopViewInterface viewer, Context context, Rende
rData renderData) { | 184 public TouchInputHandler(DesktopViewInterface viewer, Context context, Rende
rData renderData) { |
182 mViewer = viewer; | 185 mViewer = viewer; |
| 186 mContext = context; |
183 mRenderData = renderData; | 187 mRenderData = renderData; |
184 mDesktopCanvas = new DesktopCanvas(mViewer, mRenderData); | 188 mDesktopCanvas = new DesktopCanvas(mViewer, mRenderData); |
185 | 189 |
186 GestureListener listener = new GestureListener(); | 190 GestureListener listener = new GestureListener(); |
187 mScroller = new GestureDetector(context, listener, null, false); | 191 mScroller = new GestureDetector(context, listener, null, false); |
188 | 192 |
189 // If long-press is enabled, the gesture-detector will not emit any furt
her onScroll | 193 // If long-press is enabled, the gesture-detector will not emit any furt
her onScroll |
190 // notifications after the onLongPress notification. Since onScroll is b
eing used for | 194 // notifications after the onLongPress notification. Since onScroll is b
eing used for |
191 // moving the cursor, it means that the cursor would become stuck if the
finger were held | 195 // moving the cursor, it means that the cursor would become stuck if the
finger were held |
192 // down too long. | 196 // down too long. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 mDesktopCanvas.repositionImageWithZoom(true); | 254 mDesktopCanvas.repositionImageWithZoom(true); |
251 } | 255 } |
252 | 256 |
253 @Override | 257 @Override |
254 public void onHostSizeChanged(int width, int height) { | 258 public void onHostSizeChanged(int width, int height) { |
255 moveViewport((float) width / 2, (float) height / 2); | 259 moveViewport((float) width / 2, (float) height / 2); |
256 mDesktopCanvas.resizeImageToFitScreen(); | 260 mDesktopCanvas.resizeImageToFitScreen(); |
257 } | 261 } |
258 | 262 |
259 @Override | 263 @Override |
260 public void onSoftInputMethodVisibilityChanged(boolean inputMethodVisible, R
ect bounds) { | |
261 synchronized (mRenderData) { | |
262 if (inputMethodVisible) { | |
263 mDesktopCanvas.setInputMethodOffsetValues(mRenderData.screenWidt
h - bounds.right, | |
264 mRenderData.screenHeig
ht - bounds.bottom); | |
265 } else { | |
266 mDesktopCanvas.setInputMethodOffsetValues(0, 0); | |
267 } | |
268 } | |
269 | |
270 mDesktopCanvas.repositionImage(true); | |
271 } | |
272 | |
273 @Override | |
274 public void processAnimation() { | 264 public void processAnimation() { |
275 boolean active = mCursorAnimationJob.processAnimation(); | 265 boolean active = mCursorAnimationJob.processAnimation(); |
276 active |= mScrollAnimationJob.processAnimation(); | 266 active |= mScrollAnimationJob.processAnimation(); |
277 | 267 |
278 if (!active) { | 268 if (!active) { |
279 mViewer.setAnimationEnabled(false); | 269 mViewer.setAnimationEnabled(false); |
280 } | 270 } |
281 } | 271 } |
282 | 272 |
283 @Override | 273 @Override |
284 public void setInputStrategy(InputStrategyInterface inputStrategy) { | 274 public void init(Desktop desktop, final Client client) { |
| 275 Preconditions.notNull(client); |
| 276 desktop.onInputModeChanged().add( |
| 277 new Event.ParameterRunnable<InputModeChangedEventParameter>() { |
| 278 @Override |
| 279 public void run(InputModeChangedEventParameter parameter) { |
| 280 handleInputModeChanged(parameter, client); |
| 281 } |
| 282 }); |
| 283 |
| 284 desktop.onSoftInputMethodVisibilityChanged().add( |
| 285 new Event.ParameterRunnable<SoftInputMethodVisibilityChangedEven
tParameter>() { |
| 286 @Override |
| 287 public void run(SoftInputMethodVisibilityChangedEventParamet
er parameter) { |
| 288 handleSoftInputMethodVisibilityChanged(parameter); |
| 289 } |
| 290 }); |
| 291 } |
| 292 |
| 293 private void handleInputModeChanged(InputModeChangedEventParameter parameter
, |
| 294 Client client) { |
| 295 final Desktop.InputMode inputMode = parameter.inputMode; |
| 296 final CapabilityManager.HostCapability hostTouchCapability = |
| 297 parameter.hostCapability; |
| 298 // We need both input mode and host input capabilities to select the inp
ut |
| 299 // strategy. |
| 300 if (!inputMode.isSet() || !hostTouchCapability.isSet()) { |
| 301 return; |
| 302 } |
| 303 |
| 304 switch (inputMode) { |
| 305 case TRACKPAD: |
| 306 setInputStrategy(new TrackpadInputStrategy(mRenderData, client))
; |
| 307 break; |
| 308 |
| 309 case TOUCH: |
| 310 if (hostTouchCapability.isSupported()) { |
| 311 setInputStrategy(new TouchInputStrategy(mRenderData, client)
); |
| 312 } else { |
| 313 setInputStrategy(new SimulatedTouchInputStrategy( |
| 314 mRenderData, client, mContext)); |
| 315 } |
| 316 break; |
| 317 |
| 318 default: |
| 319 // Unreachable, but required by Google Java style and findbugs. |
| 320 assert false : "Unreached"; |
| 321 } |
| 322 |
| 323 // Ensure the cursor state is updated appropriately. |
| 324 // TODO (zijiehe): Move repaint control out of DesktopView. |
| 325 if (mViewer instanceof DesktopView) { |
| 326 ((DesktopView) mViewer).requestRepaint(); |
| 327 } |
| 328 } |
| 329 |
| 330 private void handleSoftInputMethodVisibilityChanged( |
| 331 SoftInputMethodVisibilityChangedEventParameter parameter) { |
| 332 synchronized (mRenderData) { |
| 333 if (parameter.visible) { |
| 334 mDesktopCanvas.setInputMethodOffsetValues( |
| 335 mRenderData.screenWidth - parameter.right, |
| 336 mRenderData.screenHeight - parameter.bottom); |
| 337 } else { |
| 338 mDesktopCanvas.setInputMethodOffsetValues(0, 0); |
| 339 } |
| 340 } |
| 341 |
| 342 mDesktopCanvas.repositionImage(true); |
| 343 } |
| 344 |
| 345 private void setInputStrategy(InputStrategyInterface inputStrategy) { |
285 // Since the rules for flinging differ between input modes, we want to s
top running the | 346 // Since the rules for flinging differ between input modes, we want to s
top running the |
286 // current fling animation when the mode changes to prevent a wonky expe
rience. | 347 // current fling animation when the mode changes to prevent a wonky expe
rience. |
287 mCursorAnimationJob.abortAnimation(); | 348 mCursorAnimationJob.abortAnimation(); |
288 mScrollAnimationJob.abortAnimation(); | 349 mScrollAnimationJob.abortAnimation(); |
289 mInputStrategy = inputStrategy; | 350 mInputStrategy = inputStrategy; |
290 } | 351 } |
291 | 352 |
292 /** Moves the desired center of the viewport using the specified deltas. */ | 353 /** Moves the desired center of the viewport using the specified deltas. */ |
293 private void moveViewportWithOffset(float deltaX, float deltaY) { | 354 private void moveViewportWithOffset(float deltaX, float deltaY) { |
294 // If we are in an indirect mode or are in the middle of a drag operatio
n, then we want to | 355 // If we are in an indirect mode or are in the middle of a drag operatio
n, then we want to |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 case 2: | 628 case 2: |
568 return BUTTON_RIGHT; | 629 return BUTTON_RIGHT; |
569 case 3: | 630 case 3: |
570 return BUTTON_MIDDLE; | 631 return BUTTON_MIDDLE; |
571 default: | 632 default: |
572 return BUTTON_UNDEFINED; | 633 return BUTTON_UNDEFINED; |
573 } | 634 } |
574 } | 635 } |
575 } | 636 } |
576 } | 637 } |
OLD | NEW |