Merging ub-launcher3-qt-r1-dev, build 5749827

am: 3fc9a1cf69

Change-Id: Id05a484ba74b5ef29c22992e7997eabf3c523011
This commit is contained in:
Winson Chung
2019-07-24 12:27:16 -07:00
committed by android-build-merger
22 changed files with 223 additions and 85 deletions
@@ -186,7 +186,7 @@ public class TouchInteractionService extends Service {
return mMyBinder;
}
public static boolean isInputMonitorInitialized() {
public static boolean isInitialized() {
return true;
}
}
@@ -22,6 +22,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import androidx.annotation.NonNull;
/**
* This class will be moved to androidx library. There shouldn't be any dependency outside
@@ -154,7 +155,7 @@ public class BaseIconFactory implements AutoCloseable {
* @param scale returns the scale result from normalization
* @return a bitmap suitable for disaplaying as an icon at various system UIs.
*/
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
public BitmapInfo createBadgedIconBitmap(@NonNull Drawable icon, UserHandle user,
boolean shrinkNonAdaptiveIcons, boolean isInstantApp, float[] scale) {
if (scale == null) {
scale = new float[1];
@@ -204,8 +205,11 @@ public class BaseIconFactory implements AutoCloseable {
mDisableColorExtractor = true;
}
private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, boolean shrinkNonAdaptiveIcons,
RectF outIconBounds, float[] outScale) {
private Drawable normalizeAndWrapToAdaptiveIcon(@NonNull Drawable icon,
boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) {
if (icon == null) {
return null;
}
float scale = 1f;
if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
@@ -261,7 +265,7 @@ public class BaseIconFactory implements AutoCloseable {
* @param icon drawable that should be flattened to a bitmap
* @param scale the scale to apply before drawing {@param icon} on the canvas
*/
public Bitmap createIconBitmap(Drawable icon, float scale, int size) {
public Bitmap createIconBitmap(@NonNull Drawable icon, float scale, int size) {
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
if (icon == null) {
return bitmap;
@@ -38,7 +38,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: {
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
TouchInteractionService.isInputMonitorInitialized());
TouchInteractionService.isInitialized());
return response;
}
@@ -19,12 +19,12 @@ import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Utilities.FLAG_NO_GESTURES;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.annotation.UiThread;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.util.SwipeAnimationTargetSet;
@@ -33,8 +33,6 @@ import com.android.systemui.shared.system.InputConsumerController;
import java.util.ArrayList;
import java.util.function.Supplier;
import androidx.annotation.UiThread;
/**
* Wrapper around RecentsAnimationController to help with some synchronization
*/
@@ -184,10 +182,7 @@ public class RecentsAnimationWrapper {
}
}
if (mInputConsumer != null) {
int flags = ev.getEdgeFlags();
ev.setEdgeFlags(flags | FLAG_NO_GESTURES);
mInputConsumer.onMotionEvent(ev);
ev.setEdgeFlags(flags);
}
return true;
@@ -33,11 +33,13 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.app.TaskInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -103,6 +105,7 @@ import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import com.android.systemui.shared.system.TaskInfoCompat;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -154,6 +157,7 @@ public class TouchInteractionService extends Service implements
MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
sIsInitialized = true;
}
@Override
@@ -227,15 +231,15 @@ public class TouchInteractionService extends Service implements
};
private static boolean sConnected = false;
private static boolean sInputMonitorInitialized = false;
private static boolean sIsInitialized = false;
private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
public static boolean isConnected() {
return sConnected;
}
public static boolean isInputMonitorInitialized() {
return sInputMonitorInitialized;
public static boolean isInitialized() {
return sIsInitialized;
}
public static SwipeSharedState getSwipeSharedState() {
@@ -336,25 +340,32 @@ public class TouchInteractionService extends Service implements
mInputMonitorCompat.dispose();
mInputMonitorCompat = null;
}
sInputMonitorInitialized = false;
}
private void initInputMonitor() {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1");
}
if (!mMode.hasGestures || mISystemUiProxy == null) {
return;
}
disposeEventHandlers();
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2");
}
try {
mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy
.monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR);
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 3");
}
} catch (RemoteException e) {
Log.e(TAG, "Unable to create input monitor", e);
}
initTouchBounds();
sInputMonitorInitialized = true;
}
private int getNavbarSize(String resName) {
@@ -408,6 +419,9 @@ public class TouchInteractionService extends Service implements
@Override
public void onNavigationModeChanged(Mode newMode) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode);
}
if (mMode.hasGestures != newMode.hasGestures) {
if (newMode.hasGestures) {
getSystemService(DisplayManager.class).registerDisplayListener(
@@ -492,6 +506,7 @@ public class TouchInteractionService extends Service implements
@Override
public void onDestroy() {
sIsInitialized = false;
if (mIsUserUnlocked) {
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.onDestroy();
@@ -516,6 +531,9 @@ public class TouchInteractionService extends Service implements
}
private void onInputEvent(InputEvent ev) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev);
}
if (!(ev instanceof MotionEvent)) {
Log.e(TAG, "Unknown event " + ev);
return;
@@ -567,7 +585,7 @@ public class TouchInteractionService extends Service implements
if (isInValidSystemUiState) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps
// launched while device is locked even after exiting direct boot mode (e.g. camera).
return createDeviceLockedInputConsumer(mAM.getRunningTask(0));
return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT));
} else {
return mResetGestureInputConsumer;
}
@@ -605,7 +623,7 @@ public class TouchInteractionService extends Service implements
}
private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) {
final RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
if (!useSharedState) {
sSwipeSharedState.clearAllState(false /* finishAnimation */);
}
@@ -617,6 +635,17 @@ public class TouchInteractionService extends Service implements
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
boolean forceOverviewInputConsumer = false;
if (isExcludedAssistant(runningTaskInfo)) {
// In the case where we are in the excluded assistant state, ignore it and treat the
// running activity as the task behind the assistant
runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT);
final ComponentName homeComponent =
mOverviewComponentObserver.getHomeIntent().getComponent();
forceOverviewInputConsumer =
runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
}
if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher
&& !sSwipeSharedState.recentsAnimationFinishInterrupted) {
return mResetGestureInputConsumer;
@@ -626,7 +655,8 @@ public class TouchInteractionService extends Service implements
RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
info.id = sSwipeSharedState.nextRunningTaskId;
return createOtherActivityInputConsumer(event, info);
} else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
} else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()
|| forceOverviewInputConsumer) {
return createOverviewInputConsumer(event);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
return createOverviewInputConsumer(event);
@@ -638,6 +668,12 @@ public class TouchInteractionService extends Service implements
}
}
private boolean isExcludedAssistant(TaskInfo info) {
return info != null
&& TaskInfoCompat.getActivityType(info) == ACTIVITY_TYPE_ASSISTANT
&& (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
}
private boolean disableHorizontalSwipe(MotionEvent event) {
// mExclusionRegion can change on binder thread, use a local instance here.
Region exclusionRegion = mExclusionRegion;
@@ -56,6 +56,9 @@ import android.view.ViewTreeObserver.OnDrawListener;
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
@@ -88,9 +91,6 @@ import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.WindowCallbacksCompat;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
@TargetApi(Build.VERSION_CODES.O)
public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
extends BaseSwipeUpHandler<T, RecentsView>
@@ -677,7 +677,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@Override
protected InputConsumer createNewInputProxyHandler() {
endRunningWindowAnim(true /* cancel */);
endRunningWindowAnim(mGestureEndTarget == HOME /* cancel */);
endLauncherTransitionController();
if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// Hide the task view, if not already hidden
@@ -473,11 +473,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
}
@Override
protected boolean shouldBlockGestures(MotionEvent ev) {
return Utilities.shouldDisableGestures(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
@@ -1697,6 +1692,9 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
* @return How many pixels the running task is offset on the x-axis due to the current scrollX.
*/
public float getScrollOffset() {
if (getRunningTaskIndex() == -1) {
return 0;
}
int startScroll = getScrollForPage(getRunningTaskIndex());
int offsetX = startScroll - getScrollX();
offsetX *= getScaleX();
@@ -410,4 +410,11 @@ public class TaskThumbnailView extends View {
return new ColorMatrixColorFilter(COLOR_MATRIX);
}
public Bitmap getThumbnail() {
if (mThumbnailData == null) {
return null;
}
return mThumbnailData.thumbnail;
}
}
@@ -80,6 +80,7 @@ public class NavigationModeSwitchRule implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
mLauncher.enableDebugTracing();
final Context context = getInstrumentation().getContext();
final int currentInteractionMode =
LauncherInstrumentation.getCurrentInteractionMode(context);
@@ -104,6 +105,7 @@ public class NavigationModeSwitchRule implements TestRule {
} finally {
setActiveOverlay(prevOverlayPkg, originalMode);
}
mLauncher.disableDebugTracing();
}
public void evaluateWithoutChangingSetting(Statement base) throws Throwable {
+2 -6
View File
@@ -848,7 +848,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
*/
// Skip touch handling if there are no pages to swipe
if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false;
if (getChildCount() <= 0) return false;
acquireVelocityTrackerAndAddMovement(ev);
@@ -1093,14 +1093,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mAllowOverScroll = enable;
}
protected boolean shouldBlockGestures(MotionEvent ev) {
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Skip touch handling if there are no pages to swipe
if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false;
if (getChildCount() <= 0) return false;
acquireVelocityTrackerAndAddMovement(ev);
+2 -12
View File
@@ -16,6 +16,8 @@
package com.android.launcher3;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -92,8 +94,6 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
/**
* Various utilities shared amongst the Launcher's classes.
*/
@@ -127,16 +127,6 @@ public final class Utilities {
*/
public static final int EDGE_NAV_BAR = 1 << 8;
/**
* Set on a motion event do disallow any gestures and only handle touch.
* See {@link MotionEvent#setEdgeFlags(int)}.
*/
public static final int FLAG_NO_GESTURES = 1 << 9;
public static boolean shouldDisableGestures(MotionEvent ev) {
return (ev.getEdgeFlags() & FLAG_NO_GESTURES) == FLAG_NO_GESTURES;
}
/**
* Indicates if the device has a debug build. Should only be used to store additional info or
* add extra logging and not for changing the app behavior.
@@ -105,7 +105,7 @@ abstract class BaseFlags {
"ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview");
public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag(
"ENABLE_HINTS_IN_OVERVIEW", false,
"ENABLE_HINTS_IN_OVERVIEW", true,
"Show chip hints and gleams on the overview screen");
public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag(
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.view.View;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
@@ -87,6 +88,9 @@ public class DragPreviewProvider {
Rect bounds = getDrawableBounds(d);
destCanvas.translate(blurSizeOutline / 2 - bounds.left,
blurSizeOutline / 2 - bounds.top);
if (d instanceof FastBitmapDrawable) {
((FastBitmapDrawable) d).setScale(1);
}
d.draw(destCanvas);
} else {
final Rect clipRect = mTempRect;
@@ -77,4 +77,6 @@ public final class TestProtocol {
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing";
public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824";
}
@@ -21,7 +21,6 @@ import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.Utilities.shouldDisableGestures;
import android.annotation.TargetApi;
import android.content.Context;
@@ -30,7 +29,6 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
@@ -152,8 +150,6 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
}
private TouchController findControllerToHandleTouch(MotionEvent ev) {
if (shouldDisableGestures(ev)) return null;
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
if (topView != null && topView.onControllerInterceptTouchEvent(ev)) {
return topView;
@@ -17,6 +17,7 @@ package com.android.launcher3.ui;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static org.junit.Assert.assertTrue;
@@ -45,6 +46,7 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -52,6 +54,7 @@ import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -103,6 +106,10 @@ public abstract class AbstractLauncherUiTest {
Utilities.enableRunningInTestHarnessForTests();
mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand(
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result"));
mLauncher.setOnSettledStateAction(
containerType -> executeOnLauncher(
launcher ->
checkLauncherIntegrity(launcher, containerType)));
}
}
@@ -379,4 +386,68 @@ public abstract class AbstractLauncherUiTest {
protected int getAllAppsScroll(Launcher launcher) {
return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
}
private static void checkLauncherIntegrity(
Launcher launcher, ContainerType expectedContainerType) {
if (launcher != null) {
final LauncherStateManager stateManager = launcher.getStateManager();
final LauncherState stableState = stateManager.getCurrentStableState();
assertTrue("Stable state != state: " + stableState.getClass().getSimpleName() + ", "
+ stateManager.getState().getClass().getSimpleName(),
stableState == stateManager.getState());
final boolean isResumed = launcher.hasBeenResumed();
assertTrue("hasBeenResumed() != isStarted(), hasBeenResumed(): " + isResumed,
isResumed == launcher.isStarted());
assertTrue("hasBeenResumed() != isUserActive(), hasBeenResumed(): " + isResumed,
isResumed == launcher.isUserActive());
final int ordinal = stableState.ordinal;
switch (expectedContainerType) {
case WORKSPACE:
case WIDGETS: {
assertTrue(
"Launcher is not resumed in state: " + expectedContainerType,
isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
break;
}
case ALL_APPS: {
assertTrue(
"Launcher is not resumed in state: " + expectedContainerType,
isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
ordinal == TestProtocol.ALL_APPS_STATE_ORDINAL);
break;
}
case OVERVIEW: {
assertTrue(
"Launcher is not resumed in state: " + expectedContainerType,
isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
ordinal == TestProtocol.OVERVIEW_STATE_ORDINAL);
break;
}
case BACKGROUND: {
assertTrue("Launcher is resumed in state: " + expectedContainerType,
!isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
break;
}
default:
throw new IllegalArgumentException(
"Illegal container: " + expectedContainerType);
}
} else {
assertTrue(
"Container type is not BACKGROUND or FALLBACK_OVERVIEW: "
+ expectedContainerType,
expectedContainerType == ContainerType.BACKGROUND ||
expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
}
}
}
@@ -1,5 +1,6 @@
package com.android.launcher3.ui;
import android.util.Log;
import android.view.Surface;
import com.android.launcher3.tapl.TestHelpers;
@@ -9,6 +10,7 @@ import org.junit.runner.Description;
import org.junit.runners.model.Statement;
class PortraitLandscapeRunner implements TestRule {
private static final String TAG = "PortraitLandscapeRunner";
private AbstractLauncherUiTest mTest;
public PortraitLandscapeRunner(AbstractLauncherUiTest test) {
@@ -36,6 +38,9 @@ class PortraitLandscapeRunner implements TestRule {
evaluateInPortrait();
evaluateInLandscape();
} catch (Exception e) {
Log.e(TAG, "Exception", e);
throw e;
} finally {
mTest.mDevice.setOrientationNatural();
mTest.executeOnLauncher(launcher ->
@@ -16,10 +16,16 @@
package com.android.launcher3.tapl;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiObject2;
import java.util.regex.Pattern;
public class AddToHomeScreenPrompt {
private static final Pattern ADD_AUTOMATICALLY =
Pattern.compile("^Add automatically$", CASE_INSENSITIVE);
private final LauncherInstrumentation mLauncher;
private final UiObject2 mWidgetCell;
@@ -33,9 +39,6 @@ public class AddToHomeScreenPrompt {
public void addAutomatically() {
mLauncher.waitForObjectInContainer(
mWidgetCell.getParent().getParent().getParent().getParent(),
By.text(LauncherInstrumentation.isAvd()
? "ADD AUTOMATICALLY"
: "Add automatically")).
click();
By.text(ADD_AUTOMATICALLY)).click();
}
}
@@ -54,7 +54,8 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
"want to switch from background to overview")) {
verifyActiveContainer();
goToOverviewUnchecked(BACKGROUND_APP_STATE_ORDINAL);
return new BaseOverview(mLauncher);
return mLauncher.isFallbackOverview() ?
new BaseOverview(mLauncher) : new Overview(mLauncher);
}
}
@@ -41,7 +41,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
@Override
protected LauncherInstrumentation.ContainerType getContainerType() {
return LauncherInstrumentation.ContainerType.BASE_OVERVIEW;
return LauncherInstrumentation.ContainerType.FALLBACK_OVERVIEW;
}
/**
@@ -72,6 +72,7 @@ import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -86,8 +87,8 @@ public final class LauncherInstrumentation {
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
enum ContainerType {
WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, BASE_OVERVIEW
public enum ContainerType {
WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW
}
public enum NavigationModel {ZERO_BUTTON, TWO_BUTTON, THREE_BUTTON}
@@ -135,6 +136,8 @@ public final class LauncherInstrumentation {
private final Deque<String> mDiagnosticContext = new LinkedList<>();
private Supplier<String> mSystemHealthSupplier;
private Consumer<ContainerType> mOnSettledStateAction;
/**
* Constructs the root of TAPL hierarchy. You get all other objects from it.
*/
@@ -296,6 +299,10 @@ public final class LauncherInstrumentation {
this.mSystemHealthSupplier = supplier;
}
public void setOnSettledStateAction(Consumer<ContainerType> onSettledStateAction) {
mOnSettledStateAction = onSettledStateAction;
}
private String getSystemHealthMessage() {
final String testPackage = getContext().getPackageName();
try {
@@ -396,7 +403,7 @@ public final class LauncherInstrumentation {
}
private UiObject2 verifyContainerType(ContainerType containerType) {
//waitForTouchInteractionService();
waitForLauncherInitialized();
assertEquals("Unexpected display rotation",
mExpectedRotation, mDevice.getDisplayRotation());
@@ -415,6 +422,14 @@ public final class LauncherInstrumentation {
assertTrue(error, error == null);
log("verifyContainerType: " + containerType);
final UiObject2 container = verifyVisibleObjects(containerType);
if (mOnSettledStateAction != null) mOnSettledStateAction.accept(containerType);
return container;
}
private UiObject2 verifyVisibleObjects(ContainerType containerType) {
try (Closable c = addContextLayer(
"but the current state is not " + containerType.name())) {
switch (containerType) {
@@ -451,7 +466,7 @@ public final class LauncherInstrumentation {
return waitForLauncherObject(OVERVIEW_RES_ID);
}
case BASE_OVERVIEW: {
case FALLBACK_OVERVIEW: {
return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
}
case BACKGROUND: {
@@ -468,7 +483,7 @@ public final class LauncherInstrumentation {
}
}
private void waitForTouchInteractionService() {
private void waitForLauncherInitialized() {
for (int i = 0; i < 100; ++i) {
if (getTestInfo(
TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED).
@@ -477,7 +492,7 @@ public final class LauncherInstrumentation {
}
SystemClock.sleep(100);
}
fail("TouchInteractionService didn't connect");
fail("Launcher didn't initialize");
}
Parcelable executeAndWaitForEvent(Runnable command,
@@ -739,6 +754,10 @@ public final class LauncherInstrumentation {
return mDevice.getLauncherPackageName();
}
boolean isFallbackOverview() {
return !getOverviewPackageName().equals(getLauncherPackageName());
}
@NonNull
public UiDevice getDevice() {
return mDevice;
@@ -774,7 +793,7 @@ public final class LauncherInstrumentation {
startX = endX = rect.centerX();
final int vertCenter = rect.centerY();
final float halfGestureHeight = rect.height() * percent / 2.0f;
startY = (int) (vertCenter - halfGestureHeight);
startY = (int) (vertCenter - halfGestureHeight) + 1;
endY = (int) (vertCenter + halfGestureHeight);
}
break;
@@ -790,7 +809,7 @@ public final class LauncherInstrumentation {
startY = endY = rect.centerY();
final int horizCenter = rect.centerX();
final float halfGestureWidth = rect.width() * percent / 2.0f;
startX = (int) (horizCenter - halfGestureWidth);
startX = (int) (horizCenter - halfGestureWidth) + 1;
endX = (int) (horizCenter + halfGestureWidth);
}
break;
@@ -817,6 +836,7 @@ public final class LauncherInstrumentation {
// Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a
// fixed interval each time.
void linearGesture(int startX, int startY, int endX, int endY, int steps) {
log("linearGesture: " + startX + ", " + startY + " -> " + endX + ", " + endY);
final long downTime = SystemClock.uptimeMillis();
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
@@ -932,4 +952,12 @@ public final class LauncherInstrumentation {
getContext().getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(size);
return size;
}
public void enableDebugTracing() {
getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
}
public void disableDebugTracing() {
getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
}
}
@@ -30,6 +30,7 @@ import android.os.DropBoxManager;
import org.junit.Assert;
import java.util.Date;
import java.util.List;
public class TestHelpers {
@@ -104,28 +105,21 @@ public class TestHelpers {
DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE);
Assert.assertNotNull("Unable access the DropBoxManager service", dropbox);
long timestamp = 0;
long timestamp = System.currentTimeMillis() - 5 * 60000;
DropBoxManager.Entry entry;
int crashCount = 0;
StringBuilder errorDetails = new StringBuilder();
while (null != (entry = dropbox.getNextEntry(label, timestamp))) {
String dropboxSnippet;
try {
dropboxSnippet = entry.getText(4096);
} finally {
entry.close();
}
crashCount++;
errorDetails.append(label);
errorDetails.append(": ");
errorDetails.append(truncateCrash(dropboxSnippet, 40));
errorDetails.append(" ...\n");
timestamp = entry.getTimeMillis();
errorDetails.append(new Date(timestamp));
errorDetails.append(": ");
errorDetails.append(entry.getTag());
errorDetails.append(": ");
final String dropboxSnippet = entry.getText(4096);
if (dropboxSnippet != null) errorDetails.append(truncateCrash(dropboxSnippet, 40));
errorDetails.append(" ...\n");
entry.close();
}
Assert.assertEquals(errorDetails.toString(), 0, crashCount);
return crashCount > 0 ? errorDetails.toString() : null;
return errorDetails.length() != 0 ? errorDetails.toString() : null;
}
public static String getSystemHealthMessage(Context context) {
@@ -133,9 +127,15 @@ public class TestHelpers {
StringBuilder errors = new StringBuilder();
final String[] labels = {
"system_app_anr",
"system_app_crash",
"system_app_native_crash",
"system_app_wtf",
"system_server_anr",
"system_server_crash",
"system_server_native_crash",
"system_server_anr",
"system_server_watchdog",
"system_server_wtf",
};
for (String label : labels) {