Add support for drag and drop in input command

Test: Built and flashed for ryu-eng, tested input effects
Change-Id: I4430debc405862c71af7ffc8ebaa1790f5e01073
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index 754d3f5..9ee11f8 100644
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -23,6 +23,7 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.ViewConfiguration;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -118,6 +119,19 @@
                                 duration);
                         return;
                 }
+            } else if (command.equals("draganddrop")) {
+                int duration = -1;
+                inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
+                switch (length) {
+                    case 6:
+                        duration = Integer.parseInt(args[index+5]);
+                    case 5:
+                        sendDragAndDrop(inputSource,
+                                Float.parseFloat(args[index+1]), Float.parseFloat(args[index+2]),
+                                Float.parseFloat(args[index+3]), Float.parseFloat(args[index+4]),
+                                duration);
+                        return;
+                }
             } else if (command.equals("press")) {
                 inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
                 if (length == 1) {
@@ -216,6 +230,31 @@
         injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x2, y2, 0.0f);
     }
 
+    private void sendDragAndDrop(int inputSource, float x1, float y1, float x2, float y2,
+            int dragDuration) {
+        if (dragDuration < 0) {
+            dragDuration = 300;
+        }
+        long now = SystemClock.uptimeMillis();
+        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x1, y1, 1.0f);
+        try {
+            Thread.sleep(ViewConfiguration.getLongPressTimeout());
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        now = SystemClock.uptimeMillis();
+        long startTime = now;
+        long endTime = startTime + dragDuration;
+        while (now < endTime) {
+            long elapsedTime = now - startTime;
+            float alpha = (float) elapsedTime / dragDuration;
+            injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, lerp(x1, x2, alpha),
+                    lerp(y1, y2, alpha), 1.0f);
+            now = SystemClock.uptimeMillis();
+        }
+        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x2, y2, 0.0f);
+    }
+
     /**
      * Sends a simple zero-pressure move event.
      *
@@ -294,6 +333,8 @@
         System.err.println("      tap <x> <y> (Default: touchscreen)");
         System.err.println("      swipe <x1> <y1> <x2> <y2> [duration(ms)]"
                 + " (Default: touchscreen)");
+        System.err.println("      draganddrop <x1> <y1> <x2> <y2> [duration(ms)]"
+                + " (Default: touchscreen)");
         System.err.println("      press (Default: trackball)");
         System.err.println("      roll <dx> <dy> (Default: trackball)");
     }