Merge "Fix typo in MR2ProviderServiceProxy"
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java
new file mode 100644
index 0000000..2a64185
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.plugins;
+
+import android.view.MotionEvent;
+
+/** Handles both trackpad and touch events and report displacements in both axis's. */
+public interface MotionEventsHandlerBase {
+
+ void onMotionEvent(MotionEvent ev);
+
+ float getDisplacementX(MotionEvent ev);
+
+ float getDisplacementY(MotionEvent ev);
+
+ String dump();
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
index 5f6f11c..054e300 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
@@ -48,6 +48,9 @@
/** Sets the base LayoutParams for the UI. */
void setLayoutParams(WindowManager.LayoutParams layoutParams);
+ /** Sets the motion events handler for the plugin. */
+ default void setMotionEventsHandler(MotionEventsHandlerBase motionEventsHandler) {}
+
/** Updates the UI based on the motion events passed in device coordinates. */
void onMotionEvent(MotionEvent motionEvent);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 6e927b0..1950c69 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -38,6 +38,7 @@
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.MotionEventsHandlerBase
import com.android.systemui.plugins.NavigationEdgeBackPlugin
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -498,6 +499,10 @@
windowManager.addView(mView, layoutParams)
}
+ override fun setMotionEventsHandler(motionEventsHandler: MotionEventsHandlerBase?) {
+ TODO("Not yet implemented")
+ }
+
private fun isFlung() = velocityTracker!!.run {
computeCurrentVelocity(1000)
abs(xVelocity) > MIN_FLING_VELOCITY
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 6c99b67..e32c301 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -18,6 +18,8 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
+import static com.android.systemui.navigationbar.gestural.Utilities.getTrackpadScale;
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -241,6 +243,7 @@
private boolean mIsBackGestureAllowed;
private boolean mGestureBlockingActivityRunning;
private boolean mIsNewBackAffordanceEnabled;
+ private boolean mIsTrackpadGestureBackEnabled;
private boolean mIsButtonForceVisible;
private InputMonitor mInputMonitor;
@@ -269,6 +272,7 @@
private LogArray mGestureLogOutsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
+ private final MotionEventsHandler mMotionEventsHandler;
private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
new NavigationEdgeBackPlugin.BackCallback() {
@@ -401,6 +405,7 @@
mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
mContext.getMainThreadHandler(), mContext, this::onNavigationSettingsChanged);
+ mMotionEventsHandler = new MotionEventsHandler(featureFlags, getTrackpadScale(context));
updateCurrentUserResources();
}
@@ -578,6 +583,7 @@
// Add a nav bar panel window
mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
+ mIsTrackpadGestureBackEnabled = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
resetEdgeBackPlugin();
mPluginManager.addPluginListener(
this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
@@ -611,6 +617,7 @@
}
mEdgeBackPlugin = edgeBackPlugin;
mEdgeBackPlugin.setBackCallback(mBackCallback);
+ mEdgeBackPlugin.setMotionEventsHandler(mMotionEventsHandler);
mEdgeBackPlugin.setLayoutParams(createLayoutParams());
updateDisplaySize();
}
@@ -854,6 +861,7 @@
}
private void onMotionEvent(MotionEvent ev) {
+ mMotionEventsHandler.onMotionEvent(ev);
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG_MISSING_GESTURE) {
@@ -863,15 +871,24 @@
// Verify if this is in within the touch region and we aren't in immersive mode, and
// either the bouncer is showing or the notification panel is hidden
mInputEventReceiver.setBatchingEnabled(false);
- mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset;
+ boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
+ if (isTrackpadEvent) {
+ // TODO: show the back arrow based on the direction of the swipe.
+ mIsOnLeftEdge = false;
+ } else {
+ mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset;
+ }
mMLResults = 0;
mLogGesture = false;
mInRejectedExclusion = false;
boolean isWithinInsets = isWithinInsets((int) ev.getX(), (int) ev.getY());
- mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed && isWithinInsets
+ // Trackpad back gestures don't have zones, so we don't need to check if the down event
+ // is within insets.
+ mAllowGesture = !mDisabledForQuickstep && mIsBackGestureAllowed
+ && (isTrackpadEvent || isWithinInsets)
&& !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
- && isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
+ && (isTrackpadEvent || isWithinTouchRegion((int) ev.getX(), (int) ev.getY()));
if (mAllowGesture) {
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
mEdgeBackPlugin.onMotionEvent(ev);
@@ -885,8 +902,8 @@
// For debugging purposes, only log edge points
(isWithinInsets ? mGestureLogInsideInsets : mGestureLogOutsideInsets).log(String.format(
- "Gesture [%d,alw=%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
- System.currentTimeMillis(), mAllowGesture, mIsOnLeftEdge,
+ "Gesture [%d,alw=%B,%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
+ System.currentTimeMillis(), isTrackpadEvent, mAllowGesture, mIsOnLeftEdge,
mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisplaySize,
mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
@@ -920,8 +937,8 @@
mLogGesture = false;
return;
}
- float dx = Math.abs(ev.getX() - mDownPoint.x);
- float dy = Math.abs(ev.getY() - mDownPoint.y);
+ float dx = Math.abs(mMotionEventsHandler.getDisplacementX(ev));
+ float dy = Math.abs(mMotionEventsHandler.getDisplacementY(ev));
if (dy > dx && dy > mTouchSlop) {
if (mAllowGesture) {
logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE);
@@ -1055,6 +1072,7 @@
pw.println(" mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
pw.println(" mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
pw.println(" mEdgeBackPlugin=" + mEdgeBackPlugin);
+ pw.println(" mMotionEventsHandler=" + mMotionEventsHandler);
if (mEdgeBackPlugin != null) {
mEdgeBackPlugin.dump(pw);
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java
new file mode 100644
index 0000000..e9b5453
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.navigationbar.gestural;
+
+import static android.view.MotionEvent.AXIS_GESTURE_X_OFFSET;
+import static android.view.MotionEvent.AXIS_GESTURE_Y_OFFSET;
+
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;
+
+import android.graphics.PointF;
+import android.view.MotionEvent;
+
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
+import com.android.systemui.plugins.MotionEventsHandlerBase;
+
+/** Handles both trackpad and touch events and report displacements in both axis's. */
+public class MotionEventsHandler implements MotionEventsHandlerBase {
+
+ private final boolean mIsTrackpadGestureBackEnabled;
+ private final int mScale;
+
+ private final PointF mDownPos = new PointF();
+ private final PointF mLastPos = new PointF();
+ private float mCurrentTrackpadOffsetX = 0;
+ private float mCurrentTrackpadOffsetY = 0;
+
+ public MotionEventsHandler(FeatureFlags featureFlags, int scale) {
+ mIsTrackpadGestureBackEnabled = featureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
+ mScale = scale;
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent ev) {
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ onActionDown(ev);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ onActionMove(ev);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ onActionUp(ev);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void onActionDown(MotionEvent ev) {
+ reset();
+ if (!isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
+ mDownPos.set(ev.getX(), ev.getY());
+ mLastPos.set(mDownPos);
+ }
+ }
+
+ private void onActionMove(MotionEvent ev) {
+ updateMovements(ev);
+ }
+
+ private void onActionUp(MotionEvent ev) {
+ updateMovements(ev);
+ }
+
+ private void updateMovements(MotionEvent ev) {
+ if (isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
+ mCurrentTrackpadOffsetX += ev.getAxisValue(AXIS_GESTURE_X_OFFSET) * mScale;
+ mCurrentTrackpadOffsetY += ev.getAxisValue(AXIS_GESTURE_Y_OFFSET) * mScale;
+ } else {
+ mLastPos.set(ev.getX(), ev.getY());
+ }
+ }
+
+ private void reset() {
+ mDownPos.set(0, 0);
+ mLastPos.set(0, 0);
+ mCurrentTrackpadOffsetX = 0;
+ mCurrentTrackpadOffsetY = 0;
+ }
+
+ @Override
+ public float getDisplacementX(MotionEvent ev) {
+ return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetX
+ : mLastPos.x - mDownPos.x;
+ }
+
+ @Override
+ public float getDisplacementY(MotionEvent ev) {
+ return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetY
+ : mLastPos.y - mDownPos.y;
+ }
+
+ @Override
+ public String dump() {
+ return "mDownPos: " + mDownPos + ", mLastPos: " + mLastPos + ", mCurrentTrackpadOffsetX: "
+ + mCurrentTrackpadOffsetX + ", mCurrentTrackpadOffsetY: " + mCurrentTrackpadOffsetY;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index 1230708..4a07159 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -55,6 +55,8 @@
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.plugins.MotionEventsHandlerBase;
import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.systemui.statusbar.VibratorHelper;
@@ -200,8 +202,6 @@
*/
private boolean mIsLeftPanel;
- private float mStartX;
- private float mStartY;
private float mCurrentAngle;
/**
* The current translation of the arrow
@@ -232,6 +232,8 @@
private final Handler mHandler = new Handler();
private final Runnable mFailsafeRunnable = this::onFailsafe;
+ private MotionEventsHandlerBase mMotionEventsHandler;
+
private DynamicAnimation.OnAnimationEndListener mSetGoneEndListener
= new DynamicAnimation.OnAnimationEndListener() {
@Override
@@ -437,6 +439,11 @@
mWindowManager.addView(this, mLayoutParams);
}
+ @Override
+ public void setMotionEventsHandler(MotionEventsHandlerBase motionEventsHandler) {
+ mMotionEventsHandler = motionEventsHandler;
+ }
+
/**
* Adjusts the sampling rect to conform to the actual visible bounding box of the arrow.
*/
@@ -481,8 +488,6 @@
case MotionEvent.ACTION_DOWN:
mDragSlopPassed = false;
resetOnDown();
- mStartX = event.getX();
- mStartY = event.getY();
setVisibility(VISIBLE);
updatePosition(event.getY());
mRegionSamplingHelper.start(mSamplingRect);
@@ -726,10 +731,9 @@
}
private void handleMoveEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- float touchTranslation = MathUtils.abs(x - mStartX);
- float yOffset = y - mStartY;
+ float xOffset = mMotionEventsHandler.getDisplacementX(event);
+ float touchTranslation = MathUtils.abs(xOffset);
+ float yOffset = mMotionEventsHandler.getDisplacementY(event);
float delta = touchTranslation - mPreviousTouchTranslation;
if (Math.abs(delta) > 0) {
if (Math.signum(delta) == Math.signum(mTotalTouchDelta)) {
@@ -790,16 +794,14 @@
}
// Last if the direction in Y is bigger than X * 2 we also abort
- if (Math.abs(yOffset) > Math.abs(x - mStartX) * 2) {
+ if (Math.abs(yOffset) > Math.abs(xOffset) * 2) {
triggerBack = false;
}
if (DEBUG_MISSING_GESTURE && mTriggerBack != triggerBack) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "set mTriggerBack=" + triggerBack
+ ", mTotalTouchDelta=" + mTotalTouchDelta
+ ", mMinDeltaForSwitch=" + mMinDeltaForSwitch
- + ", yOffset=" + yOffset
- + ", x=" + x
- + ", mStartX=" + mStartX);
+ + ", yOffset=" + yOffset + mMotionEventsHandler.dump());
}
setTriggerBack(triggerBack, true /* animated */);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
new file mode 100644
index 0000000..335172e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.navigationbar.gestural;
+
+import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+public final class Utilities {
+
+ private static final int TRACKPAD_GESTURE_SCALE = 60;
+
+ public static boolean isTrackpadMotionEvent(boolean isTrackpadGestureBackEnabled,
+ MotionEvent event) {
+ // TODO: ideally should use event.getClassification(), but currently only the move
+ // events get assigned the correct classification.
+ return isTrackpadGestureBackEnabled
+ && (event.getSource() & SOURCE_TOUCHSCREEN) != SOURCE_TOUCHSCREEN;
+ }
+
+ public static int getTrackpadScale(Context context) {
+ return ViewConfiguration.get(context).getScaledTouchSlop() * TRACKPAD_GESTURE_SCALE;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java
new file mode 100644
index 0000000..509d5f0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 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 com.android.systemui.navigationbar.gestural;
+
+import static android.view.InputDevice.SOURCE_TOUCHPAD;
+import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
+import static android.view.MotionEvent.AXIS_GESTURE_X_OFFSET;
+import static android.view.MotionEvent.AXIS_GESTURE_Y_OFFSET;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link MotionEventsHandler}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MotionEventsHandlerTest extends SysuiTestCase {
+
+ private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
+ private static int SCALE = 100;
+
+ private MotionEventsHandler mMotionEventsHandler;
+
+ @Before
+ public void setUp() {
+ mFeatureFlags.set(Flags.TRACKPAD_GESTURE_BACK, true);
+ mMotionEventsHandler = new MotionEventsHandler(mFeatureFlags, SCALE);
+ }
+
+ @Test
+ public void onTouchEvent_touchScreen_hasCorrectDisplacements() {
+ MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 100, 100, 0);
+ // TODO: change to use classification after gesture library is ported.
+ down.setSource(SOURCE_TOUCHSCREEN);
+ MotionEvent move1 = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 150, 125, 0);
+ move1.setSource(SOURCE_TOUCHSCREEN);
+ MotionEvent move2 = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 200, 150, 0);
+ move2.setSource(SOURCE_TOUCHSCREEN);
+ MotionEvent up = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 250, 175, 0);
+ up.setSource(SOURCE_TOUCHSCREEN);
+
+ mMotionEventsHandler.onMotionEvent(down);
+ mMotionEventsHandler.onMotionEvent(move1);
+ assertThat(mMotionEventsHandler.getDisplacementX(move1)).isEqualTo(50);
+ assertThat(mMotionEventsHandler.getDisplacementY(move1)).isEqualTo(25);
+ mMotionEventsHandler.onMotionEvent(move2);
+ assertThat(mMotionEventsHandler.getDisplacementX(move2)).isEqualTo(100);
+ assertThat(mMotionEventsHandler.getDisplacementY(move2)).isEqualTo(50);
+ mMotionEventsHandler.onMotionEvent(up);
+ assertThat(mMotionEventsHandler.getDisplacementX(up)).isEqualTo(150);
+ assertThat(mMotionEventsHandler.getDisplacementY(up)).isEqualTo(75);
+ }
+
+ @Test
+ public void onTouchEvent_trackpad_hasCorrectDisplacements() {
+ MotionEvent.PointerCoords[] downPointerCoords = new MotionEvent.PointerCoords[1];
+ downPointerCoords[0] = new MotionEvent.PointerCoords();
+ downPointerCoords[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
+ downPointerCoords[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
+ MotionEvent.PointerProperties[] downPointerProperties =
+ new MotionEvent.PointerProperties[1];
+ downPointerProperties[0] = new MotionEvent.PointerProperties();
+ downPointerProperties[0].id = 1;
+ downPointerProperties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1,
+ downPointerProperties, downPointerCoords, 0, 0, 1.0f, 1.0f, 0, 0,
+ SOURCE_TOUCHPAD, 0);
+
+ MotionEvent.PointerCoords[] movePointerCoords1 = new MotionEvent.PointerCoords[1];
+ movePointerCoords1[0] = new MotionEvent.PointerCoords();
+ movePointerCoords1[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.2f);
+ movePointerCoords1[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
+ MotionEvent.PointerProperties[] movePointerProperties1 =
+ new MotionEvent.PointerProperties[1];
+ movePointerProperties1[0] = new MotionEvent.PointerProperties();
+ movePointerProperties1[0].id = 1;
+ movePointerProperties1[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent move1 = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 1,
+ movePointerProperties1, movePointerCoords1, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD,
+ 0);
+
+ MotionEvent.PointerCoords[] movePointerCoords2 = new MotionEvent.PointerCoords[1];
+ movePointerCoords2[0] = new MotionEvent.PointerCoords();
+ movePointerCoords2[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
+ movePointerCoords2[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.4f);
+ MotionEvent.PointerProperties[] movePointerProperties2 =
+ new MotionEvent.PointerProperties[1];
+ movePointerProperties2[0] = new MotionEvent.PointerProperties();
+ movePointerProperties2[0].id = 1;
+ movePointerProperties2[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent move2 = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 1,
+ movePointerProperties2, movePointerCoords2, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD,
+ 0);
+
+ MotionEvent.PointerCoords[] upPointerCoords = new MotionEvent.PointerCoords[1];
+ upPointerCoords[0] = new MotionEvent.PointerCoords();
+ upPointerCoords[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
+ upPointerCoords[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
+ MotionEvent.PointerProperties[] upPointerProperties2 =
+ new MotionEvent.PointerProperties[1];
+ upPointerProperties2[0] = new MotionEvent.PointerProperties();
+ upPointerProperties2[0].id = 1;
+ upPointerProperties2[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent up = MotionEvent.obtain(0, 2, MotionEvent.ACTION_UP, 1,
+ upPointerProperties2, upPointerCoords, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD, 0);
+
+ mMotionEventsHandler.onMotionEvent(down);
+ mMotionEventsHandler.onMotionEvent(move1);
+ assertThat(mMotionEventsHandler.getDisplacementX(move1)).isEqualTo(20f);
+ assertThat(mMotionEventsHandler.getDisplacementY(move1)).isEqualTo(10f);
+ mMotionEventsHandler.onMotionEvent(move2);
+ assertThat(mMotionEventsHandler.getDisplacementX(move2)).isEqualTo(30f);
+ assertThat(mMotionEventsHandler.getDisplacementY(move2)).isEqualTo(50f);
+ mMotionEventsHandler.onMotionEvent(up);
+ assertThat(mMotionEventsHandler.getDisplacementX(up)).isEqualTo(40f);
+ assertThat(mMotionEventsHandler.getDisplacementY(up)).isEqualTo(60f);
+ }
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 159285a..2878743 100644
--- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -67,6 +67,7 @@
import com.android.server.testing.shadows.ShadowKeyValueBackupJob;
import com.android.server.testing.shadows.ShadowKeyValueBackupTask;
import com.android.server.testing.shadows.ShadowSystemServiceRegistry;
+import com.android.server.testing.shadows.ShadowUserManager;
import org.junit.After;
import org.junit.Before;
@@ -101,7 +102,8 @@
shadows = {
ShadowBackupEligibilityRules.class,
ShadowApplicationPackageManager.class,
- ShadowSystemServiceRegistry.class
+ ShadowSystemServiceRegistry.class,
+ ShadowUserManager.class
})
@Presubmit
public class UserBackupManagerServiceTest {
diff --git a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
index e49425b..ed7bc74 100644
--- a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
@@ -33,6 +33,7 @@
import com.android.server.backup.testing.BackupManagerServiceTestUtils;
import com.android.server.testing.shadows.ShadowApplicationPackageManager;
import com.android.server.testing.shadows.ShadowSystemServiceRegistry;
+import com.android.server.testing.shadows.ShadowUserManager;
import org.junit.Before;
import org.junit.Test;
@@ -56,7 +57,8 @@
shadows = {
ShadowApplicationPackageManager.class,
ShadowJobScheduler.class,
- ShadowSystemServiceRegistry.class
+ ShadowSystemServiceRegistry.class,
+ ShadowUserManager.class
})
@Presubmit
public class SetupObserverTest {
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 6af7269..1abcf38 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -128,6 +128,7 @@
import com.android.server.testing.shadows.ShadowBackupDataOutput;
import com.android.server.testing.shadows.ShadowEventLog;
import com.android.server.testing.shadows.ShadowSystemServiceRegistry;
+import com.android.server.testing.shadows.ShadowUserManager;
import com.google.common.base.Charsets;
import com.google.common.truth.IterableSubject;
@@ -175,7 +176,8 @@
ShadowBackupDataOutput.class,
ShadowEventLog.class,
ShadowQueuedWork.class,
- ShadowSystemServiceRegistry.class
+ ShadowSystemServiceRegistry.class,
+ ShadowUserManager.class
})
@Presubmit
public class KeyValueBackupTaskTest {
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java b/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
index a9e4ee5..16ba210 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowUserManager.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
+import android.os.UserHandle;
import android.os.UserManager;
import org.robolectric.annotation.Implementation;
@@ -50,6 +51,12 @@
return profileIds.get(userId).stream().mapToInt(Number::intValue).toArray();
}
+ /** @see UserManager#getMainUser() */
+ @Implementation
+ public UserHandle getMainUser() {
+ return null;
+ }
+
/** Add a collection of profile IDs, all within the same profile group. */
public void addProfileIds(@UserIdInt int... userIds) {
final Set<Integer> profileGroup = new HashSet<>();