• 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.Utilities;
34 import com.android.launcher3.Workspace.ItemOperator;
35 import com.android.launcher3.model.data.ItemInfo;
36 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
37 import com.android.launcher3.model.data.WorkspaceItemInfo;
38 import com.android.launcher3.shortcuts.ShortcutKey;
39 import com.android.launcher3.tapl.AddToHomeScreenPrompt;
40 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
41 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
42 import com.android.launcher3.testcomponent.RequestPinItemActivity;
43 import com.android.launcher3.ui.AbstractLauncherUiTest;
44 import com.android.launcher3.util.Wait;
45 import com.android.launcher3.util.Wait.Condition;
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
testPinWidgetNoConfig()81     public void testPinWidgetNoConfig() throws Throwable {
82         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
83                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
84                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
85                         .equals(AppWidgetNoConfig.class.getName()));
86     }
87 
88     @Test
testPinWidgetNoConfig_customPreview()89     public void testPinWidgetNoConfig_customPreview() throws Throwable {
90         // Command to set custom preview
91         Intent command = RequestPinItemActivity.getCommandIntent(
92                 RequestPinItemActivity.class, "setRemoteViewColor").putExtra(
93                 RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED);
94 
95         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
96                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
97                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
98                         .equals(AppWidgetNoConfig.class.getName()), command);
99     }
100 
101     @Test
testPinWidgetWithConfig()102     public void testPinWidgetWithConfig() throws Throwable {
103         runTest("pinWidgetWithConfig", true,
104                 (info, view) -> info instanceof LauncherAppWidgetInfo &&
105                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
106                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
107                                 .equals(AppWidgetWithConfig.class.getName()));
108     }
109 
110     @Test
testPinShortcut()111     public void testPinShortcut() throws Throwable {
112         // Command to set the shortcut id
113         Intent command = RequestPinItemActivity.getCommandIntent(
114                 RequestPinItemActivity.class, "setShortcutId").putExtra(
115                 RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId);
116 
117         runTest("pinShortcut", false, new ItemOperator() {
118             @Override
119             public boolean evaluate(ItemInfo info, View view) {
120                 return info instanceof WorkspaceItemInfo &&
121                         info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
122                         ShortcutKey.fromItemInfo(info).getId().equals(mShortcutId);
123             }
124         }, command);
125     }
126 
runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher, Intent... commandIntents)127     private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
128             Intent... commandIntents) throws Throwable {
129         if (!Utilities.ATLEAST_OREO) {
130             return;
131         }
132         clearHomescreen();
133         mDevice.pressHome();
134 
135         // Open Pin item activity
136         BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver(
137                 RequestPinItemActivity.class.getName());
138         mLauncher.
139                 getWorkspace().
140                 switchToAllApps().
141                 getAppIcon("Test Pin Item").
142                 launch(getAppPackageName());
143         assertNotNull(openMonitor.blockingGetExtraIntent());
144 
145         // Set callback
146         PendingIntent callback = PendingIntent.getBroadcast(mTargetContext, 0,
147                 new Intent(mCallbackAction), PendingIntent.FLAG_ONE_SHOT);
148         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
149                 RequestPinItemActivity.class, "setCallback").putExtra(
150                 RequestPinItemActivity.EXTRA_PARAM + "0", callback));
151 
152         for (Intent command : commandIntents) {
153             mTargetContext.sendBroadcast(command);
154         }
155 
156         // call the requested method to start the flow
157         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
158                 RequestPinItemActivity.class, activityMethod));
159         final AddToHomeScreenPrompt addToHomeScreenPrompt = mLauncher.getAddToHomeScreenPrompt();
160 
161         // Accept confirmation:
162         BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver(mCallbackAction);
163         addToHomeScreenPrompt.addAutomatically();
164         Intent result = resultReceiver.blockingGetIntent();
165         assertNotNull(result);
166         mAppWidgetId = result.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
167         if (isWidget) {
168             assertNotSame(-1, mAppWidgetId);
169         }
170 
171         // Go back to home
172         mLauncher.pressHome();
173         Wait.atMost("", new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT,
174                 mLauncher);
175     }
176 
177     /**
178      * Condition for for an item
179      */
180     private class ItemSearchCondition implements Condition {
181 
182         private final ItemOperator mOp;
183 
ItemSearchCondition(ItemOperator op)184         ItemSearchCondition(ItemOperator op) {
185             mOp = op;
186         }
187 
188         @Override
isTrue()189         public boolean isTrue() throws Throwable {
190             return mMainThreadExecutor.submit(mActivityMonitor.itemExists(mOp)).get();
191         }
192     }
193 }
194