| /* |
| * Copyright (C) 2017 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.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 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.Workspace; |
| import com.android.launcher3.model.data.ItemInfo; |
| import com.android.launcher3.model.data.LauncherAppWidgetInfo; |
| 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.Wait; |
| import com.android.launcher3.util.Wait.Condition; |
| import com.android.launcher3.util.rule.ShellCommandRule; |
| import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; |
| |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| /** |
| * Test to verify widget configuration is properly shown. |
| */ |
| @LargeTest |
| @RunWith(AndroidJUnit4.class) |
| public class AddConfigWidgetTest extends AbstractLauncherUiTest { |
| |
| @Rule |
| public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind(); |
| |
| private LauncherAppWidgetProviderInfo mWidgetInfo; |
| private AppWidgetManager mAppWidgetManager; |
| |
| private int mWidgetId; |
| |
| @Override |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| mWidgetInfo = TestViewHelpers.findWidgetProvider(this, true /* hasConfigureScreen */); |
| mAppWidgetManager = AppWidgetManager.getInstance(mTargetContext); |
| } |
| |
| @Test |
| @PortraitLandscape |
| public void testWidgetConfig() throws Throwable { |
| runTest(true); |
| } |
| |
| @Test |
| @PortraitLandscape |
| public void testConfigCancelled() throws Throwable { |
| runTest(false); |
| } |
| |
| |
| /** |
| * @param acceptConfig accept the config activity |
| */ |
| private void runTest(boolean acceptConfig) throws Throwable { |
| clearHomescreen(); |
| mDevice.pressHome(); |
| |
| final Widgets widgets = mLauncher.getWorkspace().openAllWidgets(); |
| |
| // Drag widget to homescreen |
| WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor(); |
| widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager())) |
| .dragToWorkspace(true, false); |
| // 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)); |
| } 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, Workspace.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; |
| } |
| } |
| |
| /** |
| * Broadcast receiver for receiving widget config activity status. |
| */ |
| private class WidgetConfigStartupMonitor extends BlockingBroadcastReceiver { |
| |
| public WidgetConfigStartupMonitor() { |
| super(WidgetConfigActivity.class.getName()); |
| } |
| |
| public int getWidgetId() throws InterruptedException { |
| Intent intent = blockingGetExtraIntent(); |
| assertNotNull(intent); |
| assertEquals(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE, intent.getAction()); |
| int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, |
| LauncherAppWidgetInfo.NO_ID); |
| assertNotSame(widgetId, LauncherAppWidgetInfo.NO_ID); |
| return widgetId; |
| } |
| } |
| } |