• 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 static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
19 
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNotSame;
22 
23 import android.app.PendingIntent;
24 import android.appwidget.AppWidgetManager;
25 import android.content.Intent;
26 import android.graphics.Color;
27 import android.view.View;
28 
29 import androidx.test.filters.LargeTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import com.android.launcher3.LauncherSettings.Favorites;
33 import com.android.launcher3.Workspace.ItemOperator;
34 import com.android.launcher3.model.data.ItemInfo;
35 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
36 import com.android.launcher3.model.data.WorkspaceItemInfo;
37 import com.android.launcher3.shortcuts.ShortcutKey;
38 import com.android.launcher3.tapl.AddToHomeScreenPrompt;
39 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
40 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
41 import com.android.launcher3.testcomponent.RequestPinItemActivity;
42 import com.android.launcher3.ui.AbstractLauncherUiTest;
43 import com.android.launcher3.util.Wait;
44 import com.android.launcher3.util.Wait.Condition;
45 import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
46 import com.android.launcher3.util.rule.ShellCommandRule;
47 
48 import org.junit.Before;
49 import org.junit.Rule;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 
53 import java.util.UUID;
54 
55 /**
56  * Test to verify pin item request flow.
57  */
58 @LargeTest
59 @RunWith(AndroidJUnit4.class)
60 public class RequestPinItemTest extends AbstractLauncherUiTest {
61 
62     @Rule
63     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
64 
65     private String mCallbackAction;
66     private String mShortcutId;
67     private int mAppWidgetId;
68 
69     @Override
70     @Before
setUp()71     public void setUp() throws Exception {
72         super.setUp();
73         mCallbackAction = UUID.randomUUID().toString();
74         mShortcutId = UUID.randomUUID().toString();
75     }
76 
77     @Test
testEmpty()78     public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
79 
80     @Test
81     @ScreenRecord  //b/192010616
testPinWidgetNoConfig()82     public void testPinWidgetNoConfig() throws Throwable {
83         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
84                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
85                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
86                         .equals(AppWidgetNoConfig.class.getName()));
87     }
88 
89     @Test
90     @ScreenRecord  //b/192005114
testPinWidgetNoConfig_customPreview()91     public void testPinWidgetNoConfig_customPreview() throws Throwable {
92         // Command to set custom preview
93         Intent command = RequestPinItemActivity.getCommandIntent(
94                 RequestPinItemActivity.class, "setRemoteViewColor").putExtra(
95                 RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED);
96 
97         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
98                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
99                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
100                         .equals(AppWidgetNoConfig.class.getName()), command);
101     }
102 
103     @Test
testPinWidgetWithConfig()104     public void testPinWidgetWithConfig() throws Throwable {
105         runTest("pinWidgetWithConfig", true,
106                 (info, view) -> info instanceof LauncherAppWidgetInfo &&
107                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
108                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
109                                 .equals(AppWidgetWithConfig.class.getName()));
110     }
111 
112     @Test
testPinShortcut()113     public void testPinShortcut() throws Throwable {
114         // Command to set the shortcut id
115         Intent command = RequestPinItemActivity.getCommandIntent(
116                 RequestPinItemActivity.class, "setShortcutId").putExtra(
117                 RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId);
118 
119         runTest("pinShortcut", false, new ItemOperator() {
120             @Override
121             public boolean evaluate(ItemInfo info, View view) {
122                 return info instanceof WorkspaceItemInfo &&
123                         info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
124                         ShortcutKey.fromItemInfo(info).getId().equals(mShortcutId);
125             }
126         }, command);
127     }
128 
runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher, Intent... commandIntents)129     private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
130             Intent... commandIntents) throws Throwable {
131         clearHomescreen();
132         mDevice.pressHome();
133 
134         // Open Pin item activity
135         BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver(
136                 RequestPinItemActivity.class.getName());
137         mLauncher.
138                 getWorkspace().
139                 switchToAllApps().
140                 getAppIcon("Test Pin Item").
141                 launch(getAppPackageName());
142         assertNotNull(openMonitor.blockingGetExtraIntent());
143 
144         // Set callback
145         PendingIntent callback = PendingIntent.getBroadcast(mTargetContext, 0,
146                 new Intent(mCallbackAction), PendingIntent.FLAG_ONE_SHOT);
147         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
148                 RequestPinItemActivity.class, "setCallback").putExtra(
149                 RequestPinItemActivity.EXTRA_PARAM + "0", callback));
150 
151         for (Intent command : commandIntents) {
152             mTargetContext.sendBroadcast(command);
153         }
154 
155         // call the requested method to start the flow
156         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
157                 RequestPinItemActivity.class, activityMethod));
158         final AddToHomeScreenPrompt addToHomeScreenPrompt = mLauncher.getAddToHomeScreenPrompt();
159 
160         // Accept confirmation:
161         BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver(mCallbackAction);
162         addToHomeScreenPrompt.addAutomatically();
163         Intent result = resultReceiver.blockingGetIntent();
164         assertNotNull(result);
165         mAppWidgetId = result.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
166         if (isWidget) {
167             assertNotSame(-1, mAppWidgetId);
168         }
169 
170         // Go back to home
171         mLauncher.pressHome();
172         Wait.atMost("", new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT,
173                 mLauncher);
174     }
175 
176     /**
177      * Condition for for an item
178      */
179     private class ItemSearchCondition implements Condition {
180 
181         private final ItemOperator mOp;
182 
ItemSearchCondition(ItemOperator op)183         ItemSearchCondition(ItemOperator op) {
184             mOp = op;
185         }
186 
187         @Override
isTrue()188         public boolean isTrue() throws Throwable {
189             return mMainThreadExecutor.submit(mActivityMonitor.itemExists(mOp)).get();
190         }
191     }
192 }
193