Merge "Adding tests that would reliably reproduce shifted search." into ub-launcher3-master
This commit is contained in:
commit
57e98b8006
|
@ -22,6 +22,8 @@ import static android.view.MotionEvent.ACTION_POINTER_UP;
|
|||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static android.view.MotionEvent.INVALID_POINTER_ID;
|
||||
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper
|
||||
.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
|
@ -47,6 +49,7 @@ import android.view.ViewConfiguration;
|
|||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.MainThreadExecutor;
|
||||
import com.android.launcher3.util.RaceConditionTracker;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
@ -70,6 +73,7 @@ import java.util.concurrent.TimeUnit;
|
|||
public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
|
||||
|
||||
private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
|
||||
public static final String DOWN_EVT = "OtherActivityTouchConsumer.DOWN";
|
||||
|
||||
private final SparseArray<RecentsAnimationState> mAnimationStates = new SparseArray<>();
|
||||
private final RunningTaskInfo mRunningTask;
|
||||
|
@ -135,6 +139,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
mTouchInteractionLog.addMotionEvent(ev);
|
||||
switch (ev.getActionMasked()) {
|
||||
case ACTION_DOWN: {
|
||||
RaceConditionTracker.onEvent(DOWN_EVT, ENTER);
|
||||
TraceHelper.beginSection("TouchInt");
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
mDownPos.set(ev.getX(), ev.getY());
|
||||
|
@ -151,6 +156,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
|
|||
Display display = getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
mDisplayRotation = display.getRotation();
|
||||
WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
|
||||
RaceConditionTracker.onEvent(DOWN_EVT, EXIT);
|
||||
break;
|
||||
}
|
||||
case ACTION_POINTER_UP: {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.RaceConditionTracker.enterEvt;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.exitEvt;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.util.RaceConditionReproducer;
|
||||
import com.android.quickstep.QuickStepOnOffRule.Mode;
|
||||
import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RaceConditionsTests extends AbstractQuickStepTest {
|
||||
private void runTest(String... eventSequence) {
|
||||
final RaceConditionReproducer eventProcessor = new RaceConditionReproducer(eventSequence);
|
||||
|
||||
// Destroy Launcher activity.
|
||||
executeOnLauncher(launcher -> {
|
||||
if (launcher != null) {
|
||||
launcher.finish();
|
||||
}
|
||||
});
|
||||
waitForLauncherCondition(
|
||||
"Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
|
||||
|
||||
// Start an activity where we'll press home.
|
||||
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
|
||||
|
||||
// The test action.
|
||||
eventProcessor.startIteration();
|
||||
mLauncher.pressHome();
|
||||
eventProcessor.finishIteration();
|
||||
}
|
||||
|
||||
@Test
|
||||
@QuickstepOnOff(mode = Mode.ON)
|
||||
public void testPressHomeToStartLauncher() {
|
||||
runTest(enterEvt(Launcher.ON_CREATE_EVT),
|
||||
exitEvt(Launcher.ON_CREATE_EVT),
|
||||
enterEvt(OtherActivityTouchConsumer.DOWN_EVT),
|
||||
exitEvt(OtherActivityTouchConsumer.DOWN_EVT));
|
||||
|
||||
runTest(enterEvt(OtherActivityTouchConsumer.DOWN_EVT),
|
||||
exitEvt(OtherActivityTouchConsumer.DOWN_EVT),
|
||||
enterEvt(Launcher.ON_CREATE_EVT),
|
||||
exitEvt(Launcher.ON_CREATE_EVT));
|
||||
}
|
||||
}
|
|
@ -24,9 +24,7 @@ import static org.junit.Assert.assertNotNull;
|
|||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -66,7 +64,6 @@ import java.io.IOException;
|
|||
@LargeTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TaplTests extends AbstractQuickStepTest {
|
||||
private static final int WAIT_TIME_MS = 60000;
|
||||
private static final String TAG = "TaplTests";
|
||||
|
||||
private static int sScreenshotCount = 0;
|
||||
|
@ -112,13 +109,6 @@ public class TaplTests extends AbstractQuickStepTest {
|
|||
waitForResumed("Launcher internal state is still Background");
|
||||
}
|
||||
|
||||
private String resolveSystemApp(String category) {
|
||||
return getInstrumentation().getContext().getPackageManager().resolveActivity(
|
||||
new Intent(Intent.ACTION_MAIN).addCategory(category),
|
||||
PackageManager.MATCH_SYSTEM_ONLY).
|
||||
activityInfo.packageName;
|
||||
}
|
||||
|
||||
private boolean isInState(LauncherState state) {
|
||||
if (!TestHelpers.isInLauncherProcess()) return true;
|
||||
return getFromLauncher(launcher -> launcher.getStateManager().getState() == state);
|
||||
|
@ -143,17 +133,6 @@ public class TaplTests extends AbstractQuickStepTest {
|
|||
return !launcher.hasBeenResumed();
|
||||
}
|
||||
|
||||
private void startAppFast(String packageName) {
|
||||
final Instrumentation instrumentation = getInstrumentation();
|
||||
final Intent intent = instrumentation.getContext().getPackageManager().
|
||||
getLaunchIntentForPackage(packageName);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
instrumentation.getTargetContext().startActivity(intent);
|
||||
assertTrue(packageName + " didn't start",
|
||||
mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), WAIT_TIME_MS));
|
||||
}
|
||||
|
||||
private void startTestApps() throws Exception {
|
||||
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_MESSAGING));
|
||||
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
|
||||
|
@ -338,7 +317,8 @@ public class TaplTests extends AbstractQuickStepTest {
|
|||
assertNotNull("overview.getCurrentTask() returned null (1)", task);
|
||||
assertNotNull("OverviewTask.open returned null", task.open());
|
||||
assertTrue("Contacts app didn't open from Overview", mDevice.wait(Until.hasObject(
|
||||
By.pkg(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS)).depth(0)), WAIT_TIME_MS));
|
||||
By.pkg(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS)).depth(0)),
|
||||
LONG_WAIT_TIME_MS));
|
||||
executeOnLauncher(launcher -> assertTrue(
|
||||
"Launcher activity is the top activity; expecting another activity to be the top "
|
||||
+ "one",
|
||||
|
|
|
@ -19,6 +19,7 @@ package com.android.launcher3;
|
|||
import static android.content.pm.ActivityInfo.CONFIG_LOCALE;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
|
||||
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
|
@ -26,6 +27,8 @@ import static com.android.launcher3.LauncherState.NORMAL;
|
|||
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
|
||||
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
||||
import static com.android.launcher3.logging.LoggerUtils.newTarget;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
|
@ -71,16 +74,18 @@ import android.view.accessibility.AccessibilityEvent;
|
|||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DropTarget.DragObject;
|
||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.PropertyListBuilder;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.compat.AppWidgetManagerCompat;
|
||||
import com.android.launcher3.compat.LauncherAppsCompatVO;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
|
@ -116,6 +121,7 @@ import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
|||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
import com.android.launcher3.util.PendingRequestArgs;
|
||||
import com.android.launcher3.util.RaceConditionTracker;
|
||||
import com.android.launcher3.util.SystemUiController;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
@ -143,8 +149,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
*/
|
||||
|
@ -184,6 +188,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||
private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
|
||||
// Type: SparseArray<Parcelable>
|
||||
private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
|
||||
public static final String ON_CREATE_EVT = "Launcher.onCreate";
|
||||
|
||||
private LauncherStateManager mStateManager;
|
||||
|
||||
|
@ -255,6 +260,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
RaceConditionTracker.onEvent(ON_CREATE_EVT, ENTER);
|
||||
if (DEBUG_STRICT_MODE) {
|
||||
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||
.detectDiskReads()
|
||||
|
@ -349,6 +355,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
|||
mRotationHelper.initialize();
|
||||
|
||||
TraceHelper.endSection("Launcher-onCreate");
|
||||
RaceConditionTracker.onEvent(ON_CREATE_EVT, EXIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,9 @@ package com.android.launcher3.util;
|
|||
* orders.
|
||||
*/
|
||||
public class RaceConditionTracker {
|
||||
public final static boolean ENTER = true;
|
||||
public final static boolean EXIT = false;
|
||||
|
||||
public interface EventProcessor {
|
||||
void onEvent(String eventName);
|
||||
}
|
||||
|
@ -35,4 +38,22 @@ public class RaceConditionTracker {
|
|||
public static void onEvent(String eventName) {
|
||||
if (sEventProcessor != null) sEventProcessor.onEvent(eventName);
|
||||
}
|
||||
|
||||
public static void onEvent(String eventName, boolean isEnter) {
|
||||
if (sEventProcessor != null) {
|
||||
sEventProcessor.onEvent(enterExitEvt(eventName, isEnter));
|
||||
}
|
||||
}
|
||||
|
||||
public static String enterExitEvt(String eventName, boolean isEnter) {
|
||||
return eventName + ":" + (isEnter ? "enter" : "exit");
|
||||
}
|
||||
|
||||
public static String enterEvt(String eventName) {
|
||||
return enterExitEvt(eventName, ENTER);
|
||||
}
|
||||
|
||||
public static String exitEvt(String eventName) {
|
||||
return enterExitEvt(eventName, EXIT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package com.android.launcher3.ui;
|
|||
|
||||
import static androidx.test.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
|
@ -25,11 +26,13 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.uiautomator.By;
|
||||
import androidx.test.uiautomator.BySelector;
|
||||
import androidx.test.uiautomator.Direction;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
|
@ -77,6 +80,7 @@ public abstract class AbstractLauncherUiTest {
|
|||
|
||||
public static final long SHORT_UI_TIMEOUT= 300;
|
||||
public static final long DEFAULT_UI_TIMEOUT = 10000;
|
||||
protected static final int LONG_WAIT_TIME_MS = 60000;
|
||||
|
||||
protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
|
||||
protected final UiDevice mDevice;
|
||||
|
@ -325,4 +329,22 @@ public abstract class AbstractLauncherUiTest {
|
|||
return intent == null ? null : (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
|
||||
}
|
||||
}
|
||||
|
||||
protected void startAppFast(String packageName) {
|
||||
final Instrumentation instrumentation = getInstrumentation();
|
||||
final Intent intent = instrumentation.getContext().getPackageManager().
|
||||
getLaunchIntentForPackage(packageName);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
instrumentation.getTargetContext().startActivity(intent);
|
||||
assertTrue(packageName + " didn't start",
|
||||
mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), LONG_WAIT_TIME_MS));
|
||||
}
|
||||
|
||||
protected String resolveSystemApp(String category) {
|
||||
return getInstrumentation().getContext().getPackageManager().resolveActivity(
|
||||
new Intent(Intent.ACTION_MAIN).addCategory(category),
|
||||
PackageManager.MATCH_SYSTEM_ONLY).
|
||||
activityInfo.packageName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,11 @@ import java.util.concurrent.TimeUnit;
|
|||
* executing events in previously unseen order. It does it by postponing execution of threads that
|
||||
* would lead to an already seen sequence.
|
||||
*
|
||||
* If an event A occurs before event B in the sequence, this is how execution order looks like:
|
||||
* Events: ... A ... B ...
|
||||
* Events and instructions, guaranteed order:
|
||||
* (instructions executed prior to A) A ... B (instructions executed after B)
|
||||
*
|
||||
* Each iteration has 3 parts (phases).
|
||||
* Phase 1. Picking a previously seen event subsequence that we believe can have previously unseen
|
||||
* continuations. Reproducing this sequence by pausing threads that would lead to other sequences.
|
||||
|
@ -178,6 +183,10 @@ public class RaceConditionReproducer implements RaceConditionTracker.EventProces
|
|||
mReproString = reproString;
|
||||
}
|
||||
|
||||
public RaceConditionReproducer(String... reproSequence) {
|
||||
this(String.join("|", reproSequence));
|
||||
}
|
||||
|
||||
public synchronized String getCurrentSequenceString() {
|
||||
return mCurrentSequence.toString();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue