• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.android.launcher3.ui.widget;
17 
18 import android.app.PendingIntent;
19 import android.appwidget.AppWidgetManager;
20 import android.content.Intent;
21 import android.graphics.Color;
22 import android.support.test.filters.LargeTest;
23 import android.support.test.runner.AndroidJUnit4;
24 import android.support.test.uiautomator.By;
25 import android.support.test.uiautomator.UiObject2;
26 import android.support.test.uiautomator.Until;
27 import android.view.View;
28 
29 import com.android.launcher3.ItemInfo;
30 import com.android.launcher3.LauncherAppWidgetInfo;
31 import com.android.launcher3.LauncherSettings.Favorites;
32 import com.android.launcher3.R;
33 import com.android.launcher3.ShortcutInfo;
34 import com.android.launcher3.Utilities;
35 import com.android.launcher3.Workspace.ItemOperator;
36 import com.android.launcher3.shortcuts.ShortcutKey;
37 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
38 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
39 import com.android.launcher3.testcomponent.RequestPinItemActivity;
40 import com.android.launcher3.ui.AbstractLauncherUiTest;
41 import com.android.launcher3.util.Condition;
42 import com.android.launcher3.util.Wait;
43 import com.android.launcher3.util.rule.LauncherActivityRule;
44 import com.android.launcher3.util.rule.ShellCommandRule;
45 import com.android.launcher3.widget.WidgetCell;
46 
47 import org.junit.Before;
48 import org.junit.Rule;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 
52 import java.util.UUID;
53 
54 import static org.junit.Assert.assertNotNull;
55 import static org.junit.Assert.assertNotSame;
56 import static org.junit.Assert.assertTrue;
57 
58 /**
59  * Test to verify pin item request flow.
60  */
61 @LargeTest
62 @RunWith(AndroidJUnit4.class)
63 public class RequestPinItemTest  extends AbstractLauncherUiTest {
64 
65     @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
66     @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
67     @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
68 
69     private String mCallbackAction;
70     private String mShortcutId;
71     private int mAppWidgetId;
72 
73     @Override
74     @Before
setUp()75     public void setUp() throws Exception {
76         super.setUp();
77         mCallbackAction = UUID.randomUUID().toString();
78         mShortcutId = UUID.randomUUID().toString();
79     }
80 
81     @Test
testPinWidgetNoConfig()82     public void testPinWidgetNoConfig() throws Throwable {
83         runTest("pinWidgetNoConfig", true, new ItemOperator() {
84             @Override
85             public boolean evaluate(ItemInfo info, View view) {
86                 return info instanceof LauncherAppWidgetInfo &&
87                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
88                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
89                                 .equals(AppWidgetNoConfig.class.getName());
90             }
91         });
92     }
93 
94     @Test
testPinWidgetNoConfig_customPreview()95     public void testPinWidgetNoConfig_customPreview() throws Throwable {
96         // Command to set custom preview
97         Intent command =  RequestPinItemActivity.getCommandIntent(
98                 RequestPinItemActivity.class, "setRemoteViewColor").putExtra(
99                 RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED);
100 
101         runTest("pinWidgetNoConfig", true, new ItemOperator() {
102             @Override
103             public boolean evaluate(ItemInfo info, View view) {
104                 return info instanceof LauncherAppWidgetInfo &&
105                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
106                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
107                                 .equals(AppWidgetNoConfig.class.getName());
108             }
109         }, command);
110     }
111 
112     @Test
testPinWidgetWithConfig()113     public void testPinWidgetWithConfig() throws Throwable {
114         runTest("pinWidgetWithConfig", true, new ItemOperator() {
115             @Override
116             public boolean evaluate(ItemInfo info, View view) {
117                 return info instanceof LauncherAppWidgetInfo &&
118                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
119                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
120                                 .equals(AppWidgetWithConfig.class.getName());
121             }
122         });
123     }
124 
125     @Test
testPinShortcut()126     public void testPinShortcut() throws Throwable {
127         // Command to set the shortcut id
128         Intent command = RequestPinItemActivity.getCommandIntent(
129                 RequestPinItemActivity.class, "setShortcutId").putExtra(
130                 RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId);
131 
132         runTest("pinShortcut", false, new ItemOperator() {
133             @Override
134             public boolean evaluate(ItemInfo info, View view) {
135                 return info instanceof ShortcutInfo &&
136                         info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
137                         ShortcutKey.fromItemInfo(info).getId().equals(mShortcutId);
138             }
139         }, command);
140     }
141 
runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher, Intent... commandIntents)142     private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
143             Intent... commandIntents) throws Throwable {
144         if (!Utilities.ATLEAST_OREO) {
145             return;
146         }
147         lockRotation(true);
148 
149         clearHomescreen();
150         mActivityMonitor.startLauncher();
151 
152         // Open all apps and wait for load complete
153         final UiObject2 appsContainer = openAllApps();
154         assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
155 
156         // Open Pin item activity
157         BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver(
158                 RequestPinItemActivity.class.getName());
159         scrollAndFind(appsContainer, By.text("Test Pin Item")).click();
160         assertNotNull(openMonitor.blockingGetExtraIntent());
161 
162         // Set callback
163         PendingIntent callback = PendingIntent.getBroadcast(mTargetContext, 0,
164                 new Intent(mCallbackAction), PendingIntent.FLAG_ONE_SHOT);
165         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
166                 RequestPinItemActivity.class, "setCallback").putExtra(
167                 RequestPinItemActivity.EXTRA_PARAM + "0", callback));
168 
169         for (Intent command : commandIntents) {
170             mTargetContext.sendBroadcast(command);
171         }
172 
173         // call the requested method to start the flow
174         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
175                 RequestPinItemActivity.class, activityMethod));
176         UiObject2 widgetCell = mDevice.wait(
177                 Until.findObject(By.clazz(WidgetCell.class)), DEFAULT_ACTIVITY_TIMEOUT);
178         assertNotNull(widgetCell);
179 
180         // Accept confirmation:
181         BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver(mCallbackAction);
182         mDevice.wait(Until.findObject(By.text(mTargetContext.getString(
183                 R.string.place_automatically).toUpperCase())), DEFAULT_UI_TIMEOUT).click();
184         Intent result = resultReceiver.blockingGetIntent();
185         assertNotNull(result);
186         mAppWidgetId = result.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
187         if (isWidget) {
188             assertNotSame(-1, mAppWidgetId);
189         }
190 
191         // Go back to home
192         mActivityMonitor.returnToHome();
193         assertTrue(Wait.atMost(new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT));
194     }
195 
196     /**
197      * Condition for for an item
198      */
199     private class ItemSearchCondition extends Condition {
200 
201         private final ItemOperator mOp;
202 
ItemSearchCondition(ItemOperator op)203         ItemSearchCondition(ItemOperator op) {
204             mOp = op;
205         }
206 
207         @Override
isTrue()208         public boolean isTrue() throws Throwable {
209             return mMainThreadExecutor.submit(mActivityMonitor.itemExists(mOp)).get();
210         }
211     }
212 }
213