From 7b1d25b2519c86b62eb23d44d69e0c984868c1fb Mon Sep 17 00:00:00 2001 From: Yogisha Dixit Date: Thu, 14 Oct 2021 13:06:40 +0100 Subject: [PATCH] Fix bug with resize frame in Launcher3. Also updated the tests to check that the resize frame is shown. Bug: 192655785 Test: AddWidgetTest, AddConfigWidgetTest, manual Change-Id: Id348f39cec1bebc8ec9ea9f3068f4bda2159eac4 --- .../launcher3/AppWidgetResizeFrame.java | 2 +- src/com/android/launcher3/Launcher.java | 17 +----- .../ui/widget/AddConfigWidgetTest.java | 56 +++++-------------- .../launcher3/ui/widget/AddWidgetTest.java | 10 ++-- .../com/android/launcher3/tapl/Widget.java | 56 +++++++++++++++++++ .../launcher3/tapl/WidgetResizeFrame.java | 37 ++++++++++++ 6 files changed, 116 insertions(+), 62 deletions(-) create mode 100644 tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java index ebfd28169c..1bfd7b5cab 100644 --- a/src/com/android/launcher3/AppWidgetResizeFrame.java +++ b/src/com/android/launcher3/AppWidgetResizeFrame.java @@ -215,7 +215,7 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O dl.addView(frame); frame.mIsOpen = true; - frame.snapToWidget(false); + frame.post(() -> frame.snapToWidget(false)); } private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout, diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index f429d7698d..8d92bf2d2e 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1391,22 +1391,7 @@ public class Launcher extends StatefulActivity implements Launche final LauncherAppWidgetHostView launcherHostView = (LauncherAppWidgetHostView) hostView; CellLayout cellLayout = getCellLayout(launcherInfo.container, launcherInfo.screenId); if (mStateManager.getState() == NORMAL) { - // Show resize frame once the widget layout is drawn. - View.OnLayoutChangeListener onLayoutChangeListener = - new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View view, int left, int top, int right, - int bottom, int oldLeft, int oldTop, int oldRight, - int oldBottom) { - AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout); - launcherHostView.removeOnLayoutChangeListener(this); - } - }; - launcherHostView.addOnLayoutChangeListener(onLayoutChangeListener); - // There is a small chance that the layout was already drawn before the layout - // change listener was registered, which means that the resize frame wouldn't be - // shown. Directly call requestLayout to force a layout change. - launcherHostView.requestLayout(); + AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout); } else { mStateManager.addStateListener(new StateManager.StateListener() { @Override diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index 34dddf5c11..807b87bd25 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -15,28 +15,24 @@ */ package com.android.launcher3.ui.widget; -import static androidx.test.InstrumentationRegistry.getInstrumentation; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; import android.appwidget.AppWidgetManager; import android.content.Intent; -import android.view.View; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; +import com.android.launcher3.tapl.Widget; +import com.android.launcher3.tapl.WidgetResizeFrame; import com.android.launcher3.tapl.Widgets; import com.android.launcher3.testcomponent.WidgetConfigActivity; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; -import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator; -import com.android.launcher3.util.Wait; -import com.android.launcher3.util.Wait.Condition; import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; @@ -92,48 +88,26 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { // Drag widget to homescreen WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor(); - widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager())) - .dragToWorkspace(true, false); + WidgetResizeFrame resizeFrame = + widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager())) + .dragConfigWidgetToWorkspace(acceptConfig); // Widget id for which the config activity was opened mWidgetId = monitor.getWidgetId(); // Verify that the widget id is valid and bound assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId)); - setResult(acceptConfig); if (acceptConfig) { - // TODO(b/192655785) Assert widget resize frame is shown and then dismiss it. - Wait.atMost("", new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT, mLauncher); - assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId)); + assertNotNull("Widget resize frame not shown after widget added", resizeFrame); + resizeFrame.dismiss(); + + final Widget widget = + mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT); + assertNotNull("Widget not found on the workspace", widget); } else { - // Verify that the widget id is deleted. - Wait.atMost("", () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null, - DEFAULT_ACTIVITY_TIMEOUT, mLauncher); - } - } - - private void setResult(boolean success) { - getInstrumentation().getTargetContext().sendBroadcast( - WidgetConfigActivity.getCommandIntent(WidgetConfigActivity.class, - success ? "clickOK" : "clickCancel")); - } - - /** - * Condition for searching widget id - */ - private class WidgetSearchCondition implements Condition, ItemOperator { - - @Override - public boolean isTrue() throws Throwable { - return mMainThreadExecutor.submit(mActivityMonitor.itemExists(this)).get(); - } - - @Override - public boolean evaluate(ItemInfo info, View view) { - return info instanceof LauncherAppWidgetInfo && - ((LauncherAppWidgetInfo) info).providerName.getClassName().equals( - mWidgetInfo.provider.getClassName()) && - ((LauncherAppWidgetInfo) info).appWidgetId == mWidgetId; + final Widget widget = + mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT); + assertNull("Widget unexpectedly found on the workspace", widget); } } diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 3696755eb4..73b95112d7 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -25,6 +25,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.tapl.Widget; +import com.android.launcher3.tapl.WidgetResizeFrame; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.util.rule.ShellCommandRule; @@ -53,19 +54,20 @@ public class AddWidgetTest extends AbstractLauncherUiTest { final LauncherAppWidgetProviderInfo widgetInfo = TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */); - mLauncher. + WidgetResizeFrame resizeFrame = mLauncher. getWorkspace(). openAllWidgets(). getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())). - dragToWorkspace(false, false); - // Dismiss widget resize frame. - mDevice.pressHome(); + dragWidgetToWorkspace(); assertTrue(mActivityMonitor.itemExists( (info, view) -> info instanceof LauncherAppWidgetInfo && ((LauncherAppWidgetInfo) info).providerName.getClassName().equals( widgetInfo.provider.getClassName())).call()); + assertNotNull("Widget resize frame not shown after widget add", resizeFrame); + resizeFrame.dismiss(); + final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label, DEFAULT_UI_TIMEOUT); assertNotNull("Widget not found on the workspace", widget); diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java index 35203185ed..f569ef4547 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widget.java +++ b/tests/tapl/com/android/launcher3/tapl/Widget.java @@ -16,7 +16,12 @@ package com.android.launcher3.tapl; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; import com.android.launcher3.testing.TestProtocol; @@ -51,4 +56,55 @@ public final class Widget extends Launchable { protected String launchableType() { return "widget"; } + + /** + * Drags a non-configurable widget from the widgets container to the workspace and returns the + * resize frame that is shown after the widget is added. + */ + @NonNull + public WidgetResizeFrame dragWidgetToWorkspace() { + return dragWidgetToWorkspace(/* configurable= */ false, /* acceptsConfig= */ false); + } + + /** + * Drags a configurable widget from the widgets container to the workspace, either accepts or + * cancels the configuration based on {@code acceptsConfig}, and returns the resize frame that + * is shown if the widget is added. + */ + @Nullable + public WidgetResizeFrame dragConfigWidgetToWorkspace(boolean acceptsConfig) { + return dragWidgetToWorkspace(/* configurable= */ true, acceptsConfig); + } + + /** + * Drags a widget from the widgets container to the workspace and returns the resize frame that + * is shown after the widget is added. + * + *

If {@code configurable} is true, then either accepts or cancels the configuration based + * on {@code acceptsConfig}. + */ + @Nullable + private WidgetResizeFrame dragWidgetToWorkspace( + boolean configurable, boolean acceptsConfig) { + dragToWorkspace(/* startsActivity= */ configurable, /* isWidgetShortcut= */ false); + + if (configurable) { + // Configure the widget. + BySelector selector = By.text(acceptsConfig ? "OK" : "Cancel"); + mLauncher.getDevice() + .wait(Until.findObject(selector), LauncherInstrumentation.WAIT_TIME_MS) + .click(); + + // If the widget configuration was cancelled, then the widget wasn't added to the home + // screen. In that case, we cannot return a resize frame. + if (!acceptsConfig) { + return null; + } + } + + try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "want to get widget resize frame")) { + return new WidgetResizeFrame(mLauncher); + } + } } diff --git a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java new file mode 100644 index 0000000000..8f51d04c3d --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 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.tapl; + +/** The resize frame that is shown for a widget on the workspace. */ +public class WidgetResizeFrame { + + private final LauncherInstrumentation mLauncher; + + WidgetResizeFrame(LauncherInstrumentation launcher) { + mLauncher = launcher; + launcher.waitForLauncherObject("widget_resize_frame"); + } + + /** Dismisses the resize frame. */ + public void dismiss() { + try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); + LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "want to dismiss widget resize frame")) { + // Dismiss the resize frame by pressing the home button. + mLauncher.getDevice().pressHome(); + } + } +}