Loading quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +12 −9 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.view.ViewConfiguration; import android.view.Window; import android.view.WindowManager; import androidx.annotation.VisibleForTesting; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; Loading @@ -50,12 +52,13 @@ public class StatusBarTouchController implements TouchController { private final Launcher mLauncher; private final SystemUiProxy mSystemUiProxy; private final float mTouchSlop; @VisibleForTesting final float mTouchSlop; private int mLastAction; private final SparseArray<PointF> mDownEvents; /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/ private boolean mCanIntercept; @VisibleForTesting boolean mCanIntercept; public StatusBarTouchController(Launcher l) { mLauncher = l; Loading @@ -82,9 +85,9 @@ public class StatusBarTouchController implements TouchController { @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); int idx = ev.getActionIndex(); int pid = ev.getPointerId(idx); final int action = ev.getActionMasked(); final int idx = ev.getActionIndex(); final int pid = ev.getPointerId(idx); if (action == ACTION_DOWN) { mCanIntercept = canInterceptTouch(ev); if (!mCanIntercept) { Loading @@ -92,14 +95,14 @@ public class StatusBarTouchController implements TouchController { } mDownEvents.clear(); mDownEvents.put(pid, new PointF(ev.getX(), ev.getY())); } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { } else if (action == MotionEvent.ACTION_POINTER_DOWN) { // Check!! should only set it only when threshold is not entered. mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); } if (!mCanIntercept) { return false; } if (action == ACTION_MOVE) { if (action == ACTION_MOVE && mDownEvents.contains(pid)) { float dy = ev.getY(idx) - mDownEvents.get(pid).y; float dx = ev.getX(idx) - mDownEvents.get(pid).x; // Currently input dispatcher will not do touch transfer if there are more than Loading @@ -126,7 +129,6 @@ public class StatusBarTouchController implements TouchController { mLauncher.getStatsLogManager().logger() .log(LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN); setWindowSlippery(false); return true; } return true; } Loading @@ -140,7 +142,8 @@ public class StatusBarTouchController implements TouchController { * Touches can slide out of the window but they cannot necessarily slide * back in (unless the other window with touch focus permits it). */ private void setWindowSlippery(boolean enable) { @VisibleForTesting void setWindowSlippery(boolean enable) { Window w = mLauncher.getWindow(); WindowManager.LayoutParams wlp = w.getAttributes(); if (enable) { Loading quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * Copyright (C) 202 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.launcher3.uioverrides.touchcontrollers import android.view.MotionEvent import android.view.WindowManager import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.launcher3.Launcher import com.android.launcher3.ui.AbstractLauncherUiTest import com.android.launcher3.ui.TaplTestsLauncher3 import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class StatusBarTouchControllerTest : AbstractLauncherUiTest() { @Before @Throws(Exception::class) fun setup() { TaplTestsLauncher3.initialize(this) } @Test fun interceptActionDown_canIntercept() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) assertFalse(underTest.mCanIntercept) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) assertTrue(underTest.mCanIntercept) } } @Test fun interceptActionMove_handledAndSetSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) val w = launcher.window assertEquals(0, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY) val moveEvent = MotionEvent.obtain( 2, 2, MotionEvent.ACTION_MOVE, underTest.mTouchSlop, underTest.mTouchSlop + 10, 0 ) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertTrue(handled) assertEquals( WindowManager.LayoutParams.FLAG_SLIPPERY, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } @Test fun interceptActionMove_not_handled() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) val moveEvent = MotionEvent.obtain( 2, 2, MotionEvent.ACTION_MOVE, underTest.mTouchSlop + 10, underTest.mTouchSlop, 0 ) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertFalse(handled) } } @Test fun interceptActionMoveAsFirstGestureEvent_notCrashedNorHandled() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_MOVE, 10f, 10f, 0) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertFalse(handled) } } @Test fun handleActionUp_setNotSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true underTest.setWindowSlippery(true) val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_UP, 10f, 10f, 0) val handled = underTest.onControllerTouchEvent(moveEvent) assertTrue(handled) assertEquals( 0, launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } @Test fun handleActionCancel_setNotSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true underTest.setWindowSlippery(true) val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_CANCEL, 10f, 10f, 0) val handled = underTest.onControllerTouchEvent(moveEvent) assertTrue(handled) assertEquals( 0, launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } } Loading
quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +12 −9 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.view.ViewConfiguration; import android.view.Window; import android.view.WindowManager; import androidx.annotation.VisibleForTesting; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; Loading @@ -50,12 +52,13 @@ public class StatusBarTouchController implements TouchController { private final Launcher mLauncher; private final SystemUiProxy mSystemUiProxy; private final float mTouchSlop; @VisibleForTesting final float mTouchSlop; private int mLastAction; private final SparseArray<PointF> mDownEvents; /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/ private boolean mCanIntercept; @VisibleForTesting boolean mCanIntercept; public StatusBarTouchController(Launcher l) { mLauncher = l; Loading @@ -82,9 +85,9 @@ public class StatusBarTouchController implements TouchController { @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); int idx = ev.getActionIndex(); int pid = ev.getPointerId(idx); final int action = ev.getActionMasked(); final int idx = ev.getActionIndex(); final int pid = ev.getPointerId(idx); if (action == ACTION_DOWN) { mCanIntercept = canInterceptTouch(ev); if (!mCanIntercept) { Loading @@ -92,14 +95,14 @@ public class StatusBarTouchController implements TouchController { } mDownEvents.clear(); mDownEvents.put(pid, new PointF(ev.getX(), ev.getY())); } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { } else if (action == MotionEvent.ACTION_POINTER_DOWN) { // Check!! should only set it only when threshold is not entered. mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); } if (!mCanIntercept) { return false; } if (action == ACTION_MOVE) { if (action == ACTION_MOVE && mDownEvents.contains(pid)) { float dy = ev.getY(idx) - mDownEvents.get(pid).y; float dx = ev.getX(idx) - mDownEvents.get(pid).x; // Currently input dispatcher will not do touch transfer if there are more than Loading @@ -126,7 +129,6 @@ public class StatusBarTouchController implements TouchController { mLauncher.getStatsLogManager().logger() .log(LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN); setWindowSlippery(false); return true; } return true; } Loading @@ -140,7 +142,8 @@ public class StatusBarTouchController implements TouchController { * Touches can slide out of the window but they cannot necessarily slide * back in (unless the other window with touch focus permits it). */ private void setWindowSlippery(boolean enable) { @VisibleForTesting void setWindowSlippery(boolean enable) { Window w = mLauncher.getWindow(); WindowManager.LayoutParams wlp = w.getAttributes(); if (enable) { Loading
quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * Copyright (C) 202 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.launcher3.uioverrides.touchcontrollers import android.view.MotionEvent import android.view.WindowManager import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.launcher3.Launcher import com.android.launcher3.ui.AbstractLauncherUiTest import com.android.launcher3.ui.TaplTestsLauncher3 import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class StatusBarTouchControllerTest : AbstractLauncherUiTest() { @Before @Throws(Exception::class) fun setup() { TaplTestsLauncher3.initialize(this) } @Test fun interceptActionDown_canIntercept() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) assertFalse(underTest.mCanIntercept) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) assertTrue(underTest.mCanIntercept) } } @Test fun interceptActionMove_handledAndSetSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) val w = launcher.window assertEquals(0, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY) val moveEvent = MotionEvent.obtain( 2, 2, MotionEvent.ACTION_MOVE, underTest.mTouchSlop, underTest.mTouchSlop + 10, 0 ) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertTrue(handled) assertEquals( WindowManager.LayoutParams.FLAG_SLIPPERY, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } @Test fun interceptActionMove_not_handled() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0) underTest.onControllerInterceptTouchEvent(downEvent) val moveEvent = MotionEvent.obtain( 2, 2, MotionEvent.ACTION_MOVE, underTest.mTouchSlop + 10, underTest.mTouchSlop, 0 ) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertFalse(handled) } } @Test fun interceptActionMoveAsFirstGestureEvent_notCrashedNorHandled() { executeOnLauncher { launcher: Launcher? -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_MOVE, 10f, 10f, 0) val handled = underTest.onControllerInterceptTouchEvent(moveEvent) assertFalse(handled) } } @Test fun handleActionUp_setNotSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true underTest.setWindowSlippery(true) val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_UP, 10f, 10f, 0) val handled = underTest.onControllerTouchEvent(moveEvent) assertTrue(handled) assertEquals( 0, launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } @Test fun handleActionCancel_setNotSlippery() { executeOnLauncher { launcher: Launcher -> val underTest = StatusBarTouchController(launcher) underTest.mCanIntercept = true underTest.setWindowSlippery(true) val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_CANCEL, 10f, 10f, 0) val handled = underTest.onControllerTouchEvent(moveEvent) assertTrue(handled) assertEquals( 0, launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY ) } } }