Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5ab1e8f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "b135715570-test-memory-leaks" into qt-dev

* changes:
  Refactor BrightLineClassifier tests to use significantly less memory.
  Turn off BrightLineClassifier tests until memory leaks can be identified.
parents 65f73d6b f5d210eb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ public class FalsingManagerProxy implements FalsingManager {
            mInternalFalsingManager = new FalsingManagerImpl(context);
        } else {
            mInternalFalsingManager = new BrightLineFalsingManager(
                    new FalsingDataProvider(context),
                    new FalsingDataProvider(context.getResources().getDisplayMetrics()),
                    Dependency.get(AsyncSensorManager.class)
            );
        }
+22 −5
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.classifier.brightline;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
@@ -51,8 +50,7 @@ public class FalsingDataProvider {
    private MotionEvent mFirstRecentMotionEvent;
    private MotionEvent mLastMotionEvent;

    public FalsingDataProvider(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    public FalsingDataProvider(DisplayMetrics displayMetrics) {
        mXdpi = displayMetrics.xdpi;
        mYdpi = displayMetrics.ydpi;
        mWidthPixels = displayMetrics.widthPixels;
@@ -145,12 +143,20 @@ public class FalsingDataProvider {

    boolean isHorizontal() {
        recalculateData();
        if (mRecentMotionEvents.isEmpty()) {
            return false;
        }

        return Math.abs(mFirstRecentMotionEvent.getX() - mLastMotionEvent.getX()) > Math
                .abs(mFirstRecentMotionEvent.getY() - mLastMotionEvent.getY());
    }

    boolean isRight() {
        recalculateData();
        if (mRecentMotionEvents.isEmpty()) {
            return false;
        }

        return mLastMotionEvent.getX() > mFirstRecentMotionEvent.getX();
    }

@@ -160,6 +166,10 @@ public class FalsingDataProvider {

    boolean isUp() {
        recalculateData();
        if (mRecentMotionEvents.isEmpty()) {
            return false;
        }

        return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY();
    }

@@ -168,8 +178,13 @@ public class FalsingDataProvider {
            return;
        }

        if (mRecentMotionEvents.isEmpty()) {
            mFirstRecentMotionEvent = null;
            mLastMotionEvent = null;
        } else {
            mFirstRecentMotionEvent = mRecentMotionEvents.get(0);
            mLastMotionEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
        }

        calculateAngleInternal();

@@ -245,5 +260,7 @@ public class FalsingDataProvider {
        }

        mRecentMotionEvents.clear();

        mDirty = true;
    }
}
+118 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.classifier.brightline;

import android.util.DisplayMetrics;
import android.view.MotionEvent;

import com.android.systemui.SysuiTestCase;

import org.junit.After;
import org.junit.Before;

import java.util.ArrayList;
import java.util.List;

public class ClassifierTest extends SysuiTestCase {

    private FalsingDataProvider mDataProvider;
    private List<MotionEvent> mMotionEvents = new ArrayList<>();
    private float mOffsetX = 0;
    private float mOffsetY = 0;

    @Before
    public void setup() {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        displayMetrics.xdpi = 100;
        displayMetrics.ydpi = 100;
        displayMetrics.widthPixels = 1000;
        displayMetrics.heightPixels = 1000;
        mDataProvider = new FalsingDataProvider(displayMetrics);
    }

    @After
    public void tearDown() {
        resetDataProvider();
    }

    FalsingDataProvider getDataProvider() {
        return mDataProvider;
    }

    void setOffsetX(float offsetX) {
        mOffsetX = offsetX;
    }

    void setOffsetY(float offsetY) {
        mOffsetY = offsetY;
    }

    void resetDataProvider() {
        for (MotionEvent motionEvent : mMotionEvents) {
            motionEvent.recycle();
        }

        mMotionEvents.clear();

        mDataProvider.onSessionEnd();
    }

    MotionEvent appendDownEvent(float x, float y) {
        return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y);
    }

    MotionEvent appendDownEvent(float x, float y, long eventTime) {
        return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y, eventTime);
    }

    MotionEvent appendMoveEvent(float x, float y) {
        return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y);
    }

    MotionEvent appendMoveEvent(float x, float y, long eventTime) {
        return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y, eventTime);
    }


    MotionEvent appendUpEvent(float x, float y) {
        return appendMotionEvent(MotionEvent.ACTION_UP, x, y);
    }

    MotionEvent appendUpEvent(float x, float y, long eventTime) {
        return appendMotionEvent(MotionEvent.ACTION_UP, x, y, eventTime);
    }

    private MotionEvent appendMotionEvent(int actionType, float x, float y) {

        long eventTime = mMotionEvents.isEmpty() ? 1 : mMotionEvents.get(
                mMotionEvents.size() - 1).getEventTime() + 1;
        return appendMotionEvent(actionType, x, y, eventTime);
    }

    private MotionEvent appendMotionEvent(int actionType, float x, float y, long eventTime) {
        x += mOffsetX;
        y += mOffsetY;

        MotionEvent motionEvent = MotionEvent.obtain(1, eventTime, actionType, x, y,
                0);
        mMotionEvents.add(motionEvent);

        mDataProvider.onMotionEvent(motionEvent);

        return motionEvent;
    }
}
+8 −3
Original line number Diff line number Diff line
@@ -28,8 +28,7 @@ import android.testing.TestableLooper;

import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,7 +38,7 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DiagonalClassifierTest extends SysuiTestCase {
public class DiagonalClassifierTest extends ClassifierTest {

    // Next variable is not actually five, but is very close. 5 degrees is currently the value
    // used in the diagonal classifier, so we want slightly less than that to deal with
@@ -57,10 +56,16 @@ public class DiagonalClassifierTest extends SysuiTestCase {

    @Before
    public void setup() {
        super.setup();
        MockitoAnnotations.initMocks(this);
        mClassifier = new DiagonalClassifier(mDataProvider);
    }

    @After
    public void tearDown() {
        super.tearDown();
    }

    @Test
    public void testPass_UnknownAngle() {
        when(mDataProvider.getAngle()).thenReturn(Float.MAX_VALUE);
+25 −86
Original line number Diff line number Diff line
@@ -18,48 +18,37 @@ package com.android.systemui.classifier.brightline;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;

import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;

import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DistanceClassifierTest extends SysuiTestCase {
public class DistanceClassifierTest extends ClassifierTest {

    @Mock
    private FalsingDataProvider mDataProvider;
    private FalsingClassifier mClassifier;
    private List<MotionEvent> mMotionEvents = new ArrayList<>();

    private static final float DPI = 100;
    private static final int SCREEN_SIZE = (int) (DPI * 10);

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        when(mDataProvider.getHeightPixels()).thenReturn(SCREEN_SIZE);
        when(mDataProvider.getWidthPixels()).thenReturn(SCREEN_SIZE);
        when(mDataProvider.getXdpi()).thenReturn(DPI);
        when(mDataProvider.getYdpi()).thenReturn(DPI);
        super.setup();
        mDataProvider = getDataProvider();
        mClassifier = new DistanceClassifier(mDataProvider);
    }

    @After
    public void tearDown() {
        super.tearDown();
    }

    @Test
    public void testPass_noPointer() {
        assertThat(mClassifier.isFalseTouch(), is(true));
@@ -67,104 +56,54 @@ public class DistanceClassifierTest extends SysuiTestCase {

    @Test
    public void testPass_fling() {
        MotionEvent motionEventA = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 1, 1, 0);
        MotionEvent motionEventB = MotionEvent.obtain(1, 2, MotionEvent.ACTION_MOVE, 1, 2, 0);
        MotionEvent motionEventC = MotionEvent.obtain(1, 3, MotionEvent.ACTION_UP, 1, 40, 0);

        appendMotionEvent(motionEventA);
        mClassifier.onTouchEvent(appendDownEvent(1, 1));
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventB);
        mClassifier.onTouchEvent(appendMoveEvent(1, 2));
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventC);
        mClassifier.onTouchEvent(appendUpEvent(1, 40));
        assertThat(mClassifier.isFalseTouch(), is(false));

        motionEventA.recycle();
        motionEventB.recycle();
        motionEventC.recycle();
    }

    @Test
    public void testFail_flingShort() {
        MotionEvent motionEventA = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 1, 1, 0);
        MotionEvent motionEventB = MotionEvent.obtain(1, 2, MotionEvent.ACTION_MOVE, 1, 2, 0);
        MotionEvent motionEventC = MotionEvent.obtain(1, 3, MotionEvent.ACTION_UP, 1, 10, 0);

        appendMotionEvent(motionEventA);
        mClassifier.onTouchEvent(appendDownEvent(1, 1));
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventB);
        mClassifier.onTouchEvent(appendMoveEvent(1, 2));
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventC);
        mClassifier.onTouchEvent(appendUpEvent(1, 10));
        assertThat(mClassifier.isFalseTouch(), is(true));

        motionEventA.recycle();
        motionEventB.recycle();
        motionEventC.recycle();
    }

    @Test
    public void testFail_flingSlowly() {
        // These events, in testing, result in a fling that falls just short of the threshold.
        MotionEvent motionEventA = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 1, 1, 0);
        MotionEvent motionEventB = MotionEvent.obtain(1, 2, MotionEvent.ACTION_MOVE, 1, 15, 0);
        MotionEvent motionEventC = MotionEvent.obtain(1, 3, MotionEvent.ACTION_MOVE, 1, 16, 0);
        MotionEvent motionEventD = MotionEvent.obtain(1, 300, MotionEvent.ACTION_MOVE, 1, 17, 0);
        MotionEvent motionEventE = MotionEvent.obtain(1, 301, MotionEvent.ACTION_MOVE, 1, 18, 0);
        MotionEvent motionEventF = MotionEvent.obtain(1, 500, MotionEvent.ACTION_UP, 1, 19, 0);

        appendMotionEvent(motionEventA);
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventB);
        mClassifier.onTouchEvent(appendDownEvent(1, 1, 1));
        assertThat(mClassifier.isFalseTouch(), is(true));

        appendMotionEvent(motionEventC);
        appendMotionEvent(motionEventD);
        appendMotionEvent(motionEventE);
        appendMotionEvent(motionEventF);
        mClassifier.onTouchEvent(appendMoveEvent(1, 15, 2));
        assertThat(mClassifier.isFalseTouch(), is(true));

        motionEventA.recycle();
        motionEventB.recycle();
        motionEventC.recycle();
        motionEventD.recycle();
        motionEventE.recycle();
        motionEventF.recycle();
        mClassifier.onTouchEvent(appendMoveEvent(1, 16, 3));
        mClassifier.onTouchEvent(appendMoveEvent(1, 17, 300));
        mClassifier.onTouchEvent(appendMoveEvent(1, 18, 301));
        mClassifier.onTouchEvent(appendUpEvent(1, 19, 501));
        assertThat(mClassifier.isFalseTouch(), is(true));
    }

    @Test
    public void testPass_swipe() {
        MotionEvent motionEventA = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 1, 1, 0);
        MotionEvent motionEventB = MotionEvent.obtain(1, 3, MotionEvent.ACTION_MOVE, 1, DPI * 3, 0);
        MotionEvent motionEventC = MotionEvent.obtain(1, 1000, MotionEvent.ACTION_UP, 1, DPI * 3,
                0);

        appendMotionEvent(motionEventA);
        mClassifier.onTouchEvent(appendDownEvent(1, 1));
        assertThat(mClassifier.isFalseTouch(), is(true));


        appendMotionEvent(motionEventB);
        appendMotionEvent(motionEventC);
        mClassifier.onTouchEvent(appendMoveEvent(1, mDataProvider.getYdpi() * 3, 3));
        mClassifier.onTouchEvent(appendUpEvent(1, mDataProvider.getYdpi() * 3, 300));
        assertThat(mClassifier.isFalseTouch(), is(false));

        motionEventA.recycle();
        motionEventB.recycle();
        motionEventC.recycle();
    }

    private void appendMotionEvent(MotionEvent motionEvent) {
        if (mMotionEvents.isEmpty()) {
            when(mDataProvider.getFirstRecentMotionEvent()).thenReturn(motionEvent);
        }

        mMotionEvents.add(motionEvent);
        when(mDataProvider.getRecentMotionEvents()).thenReturn(mMotionEvents);

        when(mDataProvider.getLastMotionEvent()).thenReturn(motionEvent);

        mClassifier.onTouchEvent(motionEvent);
    }
}
Loading