Merge "Move TestResources class to the outside of MtpDocumentProviderTest."
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index de509b2..8470798 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -238,6 +238,7 @@
             initialScrollY = Touch.getInitialScrollY(widget, buffer);
         }
 
+        boolean wasTouchSelecting = isTouchSelecting(isMouse, buffer);
         boolean handled = Touch.onTouchEvent(widget, buffer, event);
 
         if (widget.didTouchFocusSelect() && !isMouse) {
@@ -301,7 +302,7 @@
                 }
 
                 int offset = widget.getOffsetForPosition(event.getX(), event.getY());
-                if (isTouchSelecting(isMouse, buffer)) {
+                if (wasTouchSelecting) {
                     buffer.removeSpan(LAST_TAP_DOWN);
                     Selection.extendSelection(buffer, offset);
                 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
new file mode 100644
index 0000000..2c2d393
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.widget;
+
+import static android.widget.espresso.TextViewActions.mouseDragOnText;
+import static android.widget.espresso.TextViewAssertions.hasSelection;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import com.android.frameworks.coretests.R;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Tests mouse interaction of the TextView widget from an Activity
+ */
+public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2<TextViewActivity>{
+
+    public TextViewActivityMouseTest() {
+        super(TextViewActivity.class);
+    }
+
+    @SmallTest
+    public void testSelectTextByDrag() throws Exception {
+        getActivity();
+
+        final String helloWorld = "Hello world!";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
+        onView(withId(R.id.textview)).perform(
+                mouseDragOnText(helloWorld.indexOf("llo"), helloWorld.indexOf("ld!")));
+
+        onView(withId(R.id.textview)).check(hasSelection("llo wor"));
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java b/core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java
index a0cd848..9ff8e82 100644
--- a/core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java
@@ -20,25 +20,22 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static org.hamcrest.Matchers.allOf;
-
 import android.annotation.Nullable;
 import android.os.SystemClock;
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.PerformException;
 import android.support.test.espresso.ViewAction;
 import android.support.test.espresso.action.CoordinatesProvider;
-import android.support.test.espresso.action.GeneralClickAction;
 import android.support.test.espresso.action.MotionEvents;
 import android.support.test.espresso.action.PrecisionDescriber;
-import android.support.test.espresso.action.Press;
 import android.support.test.espresso.action.Swiper;
-import android.support.test.espresso.action.Tap;
 import android.support.test.espresso.util.HumanReadables;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.widget.TextView;
+
 import org.hamcrest.Matcher;
 
 
@@ -51,11 +48,48 @@
  * <ul>
  */
 public final class DragOnTextViewActions implements ViewAction {
+    public interface Dragger extends Swiper {
+        UiController wrapUiController(UiController uiController);
+    }
 
     /**
      * Executes different "drag on text" types to given positions.
      */
-    public enum Drag implements Swiper {
+    public enum Drag implements Dragger {
+
+        /**
+         * Starts a drag with a mouse down.
+         */
+        MOUSE_DOWN {
+            private DownMotionPerformer downMotion = new DownMotionPerformer() {
+                @Override
+                public MotionEvent perform(
+                        UiController uiController, float[] coordinates, float[] precision) {
+                    MotionEvent downEvent = MotionEvents.sendDown(
+                            uiController, coordinates, precision)
+                            .down;
+                    return downEvent;
+                }
+            };
+
+            @Override
+            public Status sendSwipe(
+                    UiController uiController,
+                    float[] startCoordinates, float[] endCoordinates, float[] precision) {
+                return sendLinearDrag(
+                        uiController, downMotion, startCoordinates, endCoordinates, precision);
+            }
+
+            @Override
+            public String toString() {
+                return "mouse down and drag to select";
+            }
+
+            @Override
+            public UiController wrapUiController(UiController uiController) {
+                return new MouseUiController(uiController);
+            }
+        },
 
         /**
          * Starts a drag with a long-press.
@@ -197,6 +231,11 @@
 
             return res;
         }
+
+        @Override
+        public UiController wrapUiController(UiController uiController) {
+            return uiController;
+        }
     }
 
     /**
@@ -215,13 +254,13 @@
         MotionEvent perform(UiController uiController, float[] coordinates, float[] precision);
     }
 
-    private final Swiper mDragger;
+    private final Dragger mDragger;
     private final CoordinatesProvider mStartCoordinatesProvider;
     private final CoordinatesProvider mEndCoordinatesProvider;
     private final PrecisionDescriber mPrecisionDescriber;
 
     public DragOnTextViewActions(
-            Swiper dragger,
+            Dragger dragger,
             CoordinatesProvider startCoordinatesProvider,
             CoordinatesProvider endCoordinatesProvider,
             PrecisionDescriber precisionDescriber) {
@@ -242,6 +281,8 @@
         checkNotNull(uiController);
         checkNotNull(view);
 
+        uiController = mDragger.wrapUiController(uiController);
+
         float[] startCoordinates = mStartCoordinatesProvider.calculateCoordinates(view);
         float[] endCoordinates = mEndCoordinatesProvider.calculateCoordinates(view);
         float[] precision = mPrecisionDescriber.describePrecision();
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseUiController.java b/core/tests/coretests/src/android/widget/espresso/MouseUiController.java
new file mode 100644
index 0000000..f1387f8
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/espresso/MouseUiController.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.widget.espresso;
+
+import android.support.test.espresso.InjectEventSecurityException;
+import android.support.test.espresso.UiController;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+/**
+ * Class to wrap an UiController to overwrite source of motion events to SOURCE_MOUSE.
+ * Note that this doesn't change the tool type.
+ */
+public class MouseUiController implements UiController {
+    private final UiController mUiController;
+
+    public MouseUiController(UiController uiController) {
+        mUiController = uiController;
+    }
+
+    @Override
+    public boolean injectKeyEvent(KeyEvent event) throws InjectEventSecurityException {
+        return mUiController.injectKeyEvent(event);
+    }
+
+    @Override
+    public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException {
+        // Modify the event to mimic mouse primary button event.
+        event.setSource(InputDevice.SOURCE_MOUSE);
+        event.setButtonState(MotionEvent.BUTTON_PRIMARY);
+        return mUiController.injectMotionEvent(event);
+    }
+
+    @Override
+    public boolean injectString(String str) throws InjectEventSecurityException {
+        return mUiController.injectString(str);
+    }
+
+    @Override
+    public void loopMainThreadForAtLeast(long millisDelay) {
+        mUiController.loopMainThreadForAtLeast(millisDelay);
+    }
+
+    @Override
+    public void loopMainThreadUntilIdle() {
+        mUiController.loopMainThreadUntilIdle();
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 835b1b9..4f5a72b 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -124,6 +124,27 @@
     }
 
     /**
+     * Returns an action that click then drags by mouse on text from startIndex to endIndex on the
+     * TextView.<br>
+     * <br>
+     * View constraints:
+     * <ul>
+     * <li>must be a TextView displayed on screen
+     * <ul>
+     *
+     * @param startIndex The index of the TextView's text to start a drag from
+     * @param endIndex The index of the TextView's text to end the drag at
+     */
+    public static ViewAction mouseDragOnText(int startIndex, int endIndex) {
+        return actionWithAssertions(
+                new DragOnTextViewActions(
+                        DragOnTextViewActions.Drag.MOUSE_DOWN,
+                        new TextCoordinates(startIndex),
+                        new TextCoordinates(endIndex),
+                        Press.PINPOINT));
+    }
+
+    /**
      * A provider of the x, y coordinates of the text at the specified index in a text view.
      */
     private static final class TextCoordinates implements CoordinatesProvider {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 496e4df..927b995 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1500,7 +1500,7 @@
                 mState = STATE_SENSING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING.");
                 EventLogTags.writeDeviceIdle(mState, "step");
-                cancelAlarmLocked();
+                scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false);
                 cancelLocatingLocked();
                 mAnyMotionDetector.checkForAnyMotion();
                 mNotMoving = false;