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
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index ebfd281..1bfd7b5 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -215,7 +215,7 @@
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 f429d76..8d92bf2 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1391,22 +1391,7 @@
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<LauncherState>() {
@Override
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 34dddf5..807b87b 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 @@
// 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 3696755..73b9511 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 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 @@
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 3520318..f569ef4 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 @@
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.
+ *
+ * <p> 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 0000000..8f51d04
--- /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();
+ }
+ }
+}