• 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.ItemInfo;
33 import com.android.launcher3.LauncherAppWidgetInfo;
34 import com.android.launcher3.LauncherSettings.Favorites;
35 import com.android.launcher3.Utilities;
36 import com.android.launcher3.Workspace.ItemOperator;
37 import com.android.launcher3.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.Condition;
45 import com.android.launcher3.util.Wait;
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 public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
63 
64     private String mCallbackAction;
65     private String mShortcutId;
66     private int mAppWidgetId;
67 
68     @Override
69     @Before
setUp()70     public void setUp() throws Exception {
71         super.setUp();
72         mCallbackAction = UUID.randomUUID().toString();
73         mShortcutId = UUID.randomUUID().toString();
74     }
75 
76     @Test
testEmpty()77     public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
78 
79     @Test
testPinWidgetNoConfig()80     public void testPinWidgetNoConfig() throws Throwable {
81         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
82                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
83                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
84                         .equals(AppWidgetNoConfig.class.getName()));
85     }
86 
87         @Test
testPinWidgetNoConfig_customPreview()88     public void testPinWidgetNoConfig_customPreview() throws Throwable {
89         // Command to set custom preview
90         Intent command =  RequestPinItemActivity.getCommandIntent(
91                 RequestPinItemActivity.class, "setRemoteViewColor").putExtra(
92                 RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED);
93 
94         runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
95                 ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
96                 ((LauncherAppWidgetInfo) info).providerName.getClassName()
97                         .equals(AppWidgetNoConfig.class.getName()), command);
98     }
99 
100     @Test
testPinWidgetWithConfig()101     public void testPinWidgetWithConfig() throws Throwable {
102         runTest("pinWidgetWithConfig", true,
103                 (info, view) -> info instanceof LauncherAppWidgetInfo &&
104                         ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
105                         ((LauncherAppWidgetInfo) info).providerName.getClassName()
106                                 .equals(AppWidgetWithConfig.class.getName()));
107     }
108 
109     @Test
testPinShortcut()110     public void testPinShortcut() throws Throwable {
111         // Command to set the shortcut id
112         Intent command = RequestPinItemActivity.getCommandIntent(
113                 RequestPinItemActivity.class, "setShortcutId").putExtra(
114                 RequestPinItemActivity.EXTRA_PARAM + "0", mShortcutId);
115 
116         runTest("pinShortcut", false, new ItemOperator() {
117             @Override
118             public boolean evaluate(ItemInfo info, View view) {
119                 return info instanceof WorkspaceItemInfo &&
120                         info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
121                         ShortcutKey.fromItemInfo(info).getId().equals(mShortcutId);
122             }
123         }, command);
124     }
125 
runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher, Intent... commandIntents)126     private void runTest(String activityMethod, boolean isWidget, ItemOperator itemMatcher,
127             Intent... commandIntents) throws Throwable {
128         if (!Utilities.ATLEAST_OREO) {
129             return;
130         }
131         lockRotation(true);
132 
133         clearHomescreen();
134         mActivityMonitor.startLauncher();
135 
136         // Open Pin item activity
137         BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver(
138                 RequestPinItemActivity.class.getName());
139         mLauncher.
140                 getWorkspace().
141                 switchToAllApps().
142                 getAppIcon("Test Pin Item").
143                 launch(getAppPackageName());
144         assertNotNull(openMonitor.blockingGetExtraIntent());
145 
146         // Set callback
147         PendingIntent callback = PendingIntent.getBroadcast(mTargetContext, 0,
148                 new Intent(mCallbackAction), PendingIntent.FLAG_ONE_SHOT);
149         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
150                 RequestPinItemActivity.class, "setCallback").putExtra(
151                 RequestPinItemActivity.EXTRA_PARAM + "0", callback));
152 
153         for (Intent command : commandIntents) {
154             mTargetContext.sendBroadcast(command);
155         }
156 
157         // call the requested method to start the flow
158         mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
159                 RequestPinItemActivity.class, activityMethod));
160         final AddToHomeScreenPrompt addToHomeScreenPrompt = mLauncher.getAddToHomeScreenPrompt();
161 
162         // Accept confirmation:
163         BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver(mCallbackAction);
164         addToHomeScreenPrompt.addAutomatically();
165         Intent result = resultReceiver.blockingGetIntent();
166         assertNotNull(result);
167         mAppWidgetId = result.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
168         if (isWidget) {
169             assertNotSame(-1, mAppWidgetId);
170         }
171 
172         // Go back to home
173         mLauncher.pressHome();
174         Wait.atMost(null, new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT);
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