Merge "Fix touch on QQS tiles" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-04-25 17:23:35 +00:00
committed by Android (Google) Code Review
3 changed files with 71 additions and 5 deletions

View File

@@ -85,8 +85,8 @@ import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
@@ -3615,7 +3615,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.INPUT)
protected boolean isInsideQsHeader(MotionEvent ev) {
mQsHeader.getBoundsOnScreen(mQsHeaderBound);
return mQsHeaderBound.contains((int) ev.getX(), (int) ev.getY());
return mQsHeaderBound.contains((int) ev.getRawX(), (int) ev.getRawY());
}
@ShadeViewRefactor(RefactorComponent.INPUT)

View File

@@ -2816,12 +2816,12 @@ public class NotificationPanelViewController extends PanelViewController {
return false;
}
View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
int frameTop = mKeyguardShowing || mQs == null ? 0 : mQsFrame.getTop();
mQsInterceptRegion.set(
/* left= */ (int) mQsFrame.getX(),
/* top= */ header.getTop(),
/* top= */ header.getTop() + frameTop,
/* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
/* bottom= */ header.getBottom());
/* bottom= */ header.getBottom() + frameTop);
// Also allow QS to intercept if the touch is near the notch.
mStatusBarTouchableRegionManager.updateRegionForNotch(mQsInterceptRegion);
final boolean onHeader = mQsInterceptRegion.contains((int) x, (int) y);

View File

@@ -34,15 +34,20 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
@@ -572,9 +577,70 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
assertEquals(0, mStackScroller.getSpeedBumpIndex());
}
@Test
public void testInsideQSHeader_noOffset() {
ViewGroup qsHeader = mock(ViewGroup.class);
Rect boundsOnScreen = new Rect(0, 0, 1000, 1000);
mockBoundsOnScreen(qsHeader, boundsOnScreen);
mStackScroller.setQsHeader(qsHeader);
mStackScroller.setLeftTopRightBottom(0, 0, 2000, 2000);
MotionEvent event1 = transformEventForView(createMotionEvent(100f, 100f), mStackScroller);
assertTrue(mStackScroller.isInsideQsHeader(event1));
MotionEvent event2 = transformEventForView(createMotionEvent(1100f, 100f), mStackScroller);
assertFalse(mStackScroller.isInsideQsHeader(event2));
}
@Test
public void testInsideQSHeader_Offset() {
ViewGroup qsHeader = mock(ViewGroup.class);
Rect boundsOnScreen = new Rect(100, 100, 1000, 1000);
mockBoundsOnScreen(qsHeader, boundsOnScreen);
mStackScroller.setQsHeader(qsHeader);
mStackScroller.setLeftTopRightBottom(200, 200, 2000, 2000);
MotionEvent event1 = transformEventForView(createMotionEvent(50f, 50f), mStackScroller);
assertFalse(mStackScroller.isInsideQsHeader(event1));
MotionEvent event2 = transformEventForView(createMotionEvent(150f, 150f), mStackScroller);
assertTrue(mStackScroller.isInsideQsHeader(event2));
MotionEvent event3 = transformEventForView(createMotionEvent(250f, 250f), mStackScroller);
assertTrue(mStackScroller.isInsideQsHeader(event2));
}
private void setBarStateForTest(int state) {
// Can't inject this through the listener or we end up on the actual implementation
// rather than the mock because the spy just coppied the anonymous inner /shruggie.
mStackScroller.setStatusBarState(state);
}
private static void mockBoundsOnScreen(View view, Rect bounds) {
doAnswer(invocation -> {
Rect out = invocation.getArgument(0);
out.set(bounds);
return null;
}).when(view).getBoundsOnScreen(any());
}
private static MotionEvent transformEventForView(MotionEvent event, View view) {
// From `ViewGroup#dispatchTransformedTouchEvent`
MotionEvent transformed = event.copy();
transformed.offsetLocation(-view.getTop(), -view.getLeft());
return transformed;
}
private static MotionEvent createMotionEvent(float x, float y) {
return MotionEvent.obtain(
/* downTime= */0,
/* eventTime= */0,
MotionEvent.ACTION_DOWN,
x,
y,
/* metaState= */0
);
}
}