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);
|
||||
frame.mIsOpen = true;
|
||||
frame.snapToWidget(false);
|
||||
frame.post(() -> frame.snapToWidget(false));
|
||||
}
|
||||
|
||||
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
|
||||
|
|
|
@ -1391,22 +1391,7 @@ public class Launcher extends StatefulActivity<LauncherState> 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();
|
||||
} else {
|
||||
mStateManager.addStateListener(new StateManager.StateListener<LauncherState>() {
|
||||
@Override
|
||||
|
|
|
@ -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();
|
||||
WidgetResizeFrame resizeFrame =
|
||||
widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager()))
|
||||
.dragToWorkspace(true, false);
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* <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