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
This commit is contained in:
parent
20c05fbd4c
commit
7b1d25b251
|
@ -215,7 +215,7 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||||
|
|
||||||
dl.addView(frame);
|
dl.addView(frame);
|
||||||
frame.mIsOpen = true;
|
frame.mIsOpen = true;
|
||||||
frame.snapToWidget(false);
|
frame.post(() -> frame.snapToWidget(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
|
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
|
||||||
|
|
|
@ -1391,22 +1391,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||||
final LauncherAppWidgetHostView launcherHostView = (LauncherAppWidgetHostView) hostView;
|
final LauncherAppWidgetHostView launcherHostView = (LauncherAppWidgetHostView) hostView;
|
||||||
CellLayout cellLayout = getCellLayout(launcherInfo.container, launcherInfo.screenId);
|
CellLayout cellLayout = getCellLayout(launcherInfo.container, launcherInfo.screenId);
|
||||||
if (mStateManager.getState() == NORMAL) {
|
if (mStateManager.getState() == NORMAL) {
|
||||||
// Show resize frame once the widget layout is drawn.
|
AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout);
|
||||||
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();
|
|
||||||
} else {
|
} else {
|
||||||
mStateManager.addStateListener(new StateManager.StateListener<LauncherState>() {
|
mStateManager.addStateListener(new StateManager.StateListener<LauncherState>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,28 +15,24 @@
|
||||||
*/
|
*/
|
||||||
package com.android.launcher3.ui.widget;
|
package com.android.launcher3.ui.widget;
|
||||||
|
|
||||||
import static androidx.test.InstrumentationRegistry.getInstrumentation;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNotSame;
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
import android.appwidget.AppWidgetManager;
|
import android.appwidget.AppWidgetManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.test.filters.LargeTest;
|
import androidx.test.filters.LargeTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
|
||||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
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.tapl.Widgets;
|
||||||
import com.android.launcher3.testcomponent.WidgetConfigActivity;
|
import com.android.launcher3.testcomponent.WidgetConfigActivity;
|
||||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||||
import com.android.launcher3.ui.TestViewHelpers;
|
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.util.rule.ShellCommandRule;
|
||||||
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
||||||
|
|
||||||
|
@ -92,48 +88,26 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
|
||||||
|
|
||||||
// Drag widget to homescreen
|
// Drag widget to homescreen
|
||||||
WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor();
|
WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor();
|
||||||
widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager()))
|
WidgetResizeFrame resizeFrame =
|
||||||
.dragToWorkspace(true, false);
|
widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager()))
|
||||||
|
.dragConfigWidgetToWorkspace(acceptConfig);
|
||||||
// Widget id for which the config activity was opened
|
// Widget id for which the config activity was opened
|
||||||
mWidgetId = monitor.getWidgetId();
|
mWidgetId = monitor.getWidgetId();
|
||||||
|
|
||||||
// Verify that the widget id is valid and bound
|
// Verify that the widget id is valid and bound
|
||||||
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
|
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
|
||||||
|
|
||||||
setResult(acceptConfig);
|
|
||||||
if (acceptConfig) {
|
if (acceptConfig) {
|
||||||
// TODO(b/192655785) Assert widget resize frame is shown and then dismiss it.
|
assertNotNull("Widget resize frame not shown after widget added", resizeFrame);
|
||||||
Wait.atMost("", new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
|
resizeFrame.dismiss();
|
||||||
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
|
|
||||||
|
final Widget widget =
|
||||||
|
mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT);
|
||||||
|
assertNotNull("Widget not found on the workspace", widget);
|
||||||
} else {
|
} else {
|
||||||
// Verify that the widget id is deleted.
|
final Widget widget =
|
||||||
Wait.atMost("", () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
|
mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT);
|
||||||
DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
|
assertNull("Widget unexpectedly found on the workspace", widget);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||||
import com.android.launcher3.tapl.Widget;
|
import com.android.launcher3.tapl.Widget;
|
||||||
|
import com.android.launcher3.tapl.WidgetResizeFrame;
|
||||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||||
import com.android.launcher3.ui.TestViewHelpers;
|
import com.android.launcher3.ui.TestViewHelpers;
|
||||||
import com.android.launcher3.util.rule.ShellCommandRule;
|
import com.android.launcher3.util.rule.ShellCommandRule;
|
||||||
|
@ -53,19 +54,20 @@ public class AddWidgetTest extends AbstractLauncherUiTest {
|
||||||
final LauncherAppWidgetProviderInfo widgetInfo =
|
final LauncherAppWidgetProviderInfo widgetInfo =
|
||||||
TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */);
|
TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */);
|
||||||
|
|
||||||
mLauncher.
|
WidgetResizeFrame resizeFrame = mLauncher.
|
||||||
getWorkspace().
|
getWorkspace().
|
||||||
openAllWidgets().
|
openAllWidgets().
|
||||||
getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())).
|
getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())).
|
||||||
dragToWorkspace(false, false);
|
dragWidgetToWorkspace();
|
||||||
// Dismiss widget resize frame.
|
|
||||||
mDevice.pressHome();
|
|
||||||
|
|
||||||
assertTrue(mActivityMonitor.itemExists(
|
assertTrue(mActivityMonitor.itemExists(
|
||||||
(info, view) -> info instanceof LauncherAppWidgetInfo &&
|
(info, view) -> info instanceof LauncherAppWidgetInfo &&
|
||||||
((LauncherAppWidgetInfo) info).providerName.getClassName().equals(
|
((LauncherAppWidgetInfo) info).providerName.getClassName().equals(
|
||||||
widgetInfo.provider.getClassName())).call());
|
widgetInfo.provider.getClassName())).call());
|
||||||
|
|
||||||
|
assertNotNull("Widget resize frame not shown after widget add", resizeFrame);
|
||||||
|
resizeFrame.dismiss();
|
||||||
|
|
||||||
final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label,
|
final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label,
|
||||||
DEFAULT_UI_TIMEOUT);
|
DEFAULT_UI_TIMEOUT);
|
||||||
assertNotNull("Widget not found on the workspace", widget);
|
assertNotNull("Widget not found on the workspace", widget);
|
||||||
|
|
|
@ -16,7 +16,12 @@
|
||||||
|
|
||||||
package com.android.launcher3.tapl;
|
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.UiObject2;
|
||||||
|
import androidx.test.uiautomator.Until;
|
||||||
|
|
||||||
import com.android.launcher3.testing.TestProtocol;
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
|
|
||||||
|
@ -51,4 +56,55 @@ public final class Widget extends Launchable {
|
||||||
protected String launchableType() {
|
protected String launchableType() {
|
||||||
return "widget";
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue