• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.appwidget.cts;
18 
19 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
20 import static android.server.wm.UiDeviceUtils.pressHomeButton;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 
27 import android.app.ActivityManager;
28 import android.app.PendingIntent;
29 import android.appwidget.AppWidgetManager;
30 import android.appwidget.cts.activity.EmptyActivity;
31 import android.appwidget.cts.common.Constants;
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.pm.LauncherApps;
36 import android.os.Bundle;
37 import android.platform.test.annotations.AppModeFull;
38 import android.server.wm.WindowManagerStateHelper;
39 import android.util.Log;
40 
41 import com.android.compatibility.common.util.CddTest;
42 import com.android.compatibility.common.util.SystemUtil;
43 
44 import org.junit.After;
45 import org.junit.Before;
46 import org.junit.Ignore;
47 import org.junit.Test;
48 
49 import java.util.Arrays;
50 
51 @AppModeFull(reason = "Instant apps cannot provide or host app widgets")
52 public class RequestPinAppWidgetTest extends AppWidgetTestCase {
53 
54     private static final String LAUNCHER_CLASS = "android.appwidget.cts.packages.Launcher";
55     private static final String ACTION_PIN_RESULT = "android.appwidget.cts.ACTION_PIN_RESULT";
56 
57     private String mDefaultLauncher;
58 
59     protected WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
60 
61     @Before
setUpLauncher()62     public void setUpLauncher() throws Exception {
63         mDefaultLauncher = getDefaultLauncher();
64     }
65 
66     @After
tearDownLauncher()67     public void tearDownLauncher() throws Exception {
68         // Set the launcher back
69         setLauncher(mDefaultLauncher);
70     }
71 
72     @CddTest(requirement = "3.8.2/C-2-2")
runPinWidgetTest(final String launcherPkg)73     private void runPinWidgetTest(final String launcherPkg) throws Exception {
74         setLauncher(launcherPkg + "/" + LAUNCHER_CLASS);
75 
76         Context context = getInstrumentation().getContext();
77 
78         // Request to pin widget
79         BlockingBroadcastReceiver setupReceiver = new BlockingBroadcastReceiver()
80                 .register(Constants.ACTION_SETUP_REPLY);
81 
82         Bundle extras = new Bundle();
83         extras.putString("dummy", launcherPkg + "-dummy");
84 
85         PendingIntent pinResult = PendingIntent.getBroadcast(context, 0,
86                 new Intent(ACTION_PIN_RESULT).setPackage(context.getPackageName()),
87                 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_MUTABLE);
88         AppWidgetManager.getInstance(context).requestPinAppWidget(
89                 getFirstWidgetComponent(), extras, pinResult);
90 
91         setupReceiver.await();
92         // Verify that the confirmation dialog was opened
93         assertTrue(setupReceiver.result.getBooleanExtra(Constants.EXTRA_SUCCESS, false));
94         assertEquals(launcherPkg, setupReceiver.result.getStringExtra(Constants.EXTRA_PACKAGE));
95 
96         LauncherApps.PinItemRequest req =
97                 setupReceiver.result.getParcelableExtra(Constants.EXTRA_REQUEST);
98         assertNotNull(req);
99         // Verify that multiple calls to getAppWidgetProviderInfo have proper dimension.
100         boolean[] providerInfo = verifyInstalledProviders(Arrays.asList(
101                 req.getAppWidgetProviderInfo(context), req.getAppWidgetProviderInfo(context)));
102         assertTrue(providerInfo[0]);
103         assertNotNull(req.getExtras());
104         assertEquals(launcherPkg + "-dummy", req.getExtras().getString("dummy"));
105 
106         // Accept the request
107         BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver()
108                 .register(ACTION_PIN_RESULT);
109         context.sendBroadcast(new Intent(Constants.ACTION_CONFIRM_PIN)
110                 .setPackage(launcherPkg)
111                 .putExtra("dummy", "dummy-2"));
112         resultReceiver.await();
113 
114         // Verify that the result contain the extras
115         assertEquals("dummy-2", resultReceiver.result.getStringExtra("dummy"));
116     }
117 
118     //@Ignore("b/265187199")
119     @Test
testPinWidget_launcher1()120     public void testPinWidget_launcher1() throws Exception {
121         runPinWidgetTest("android.appwidget.cts.packages.launcher1");
122     }
123 
124     @Ignore("b/265187199")
125     @Test
testPinWidget_launcher2()126     public void testPinWidget_launcher2() throws Exception {
127         runPinWidgetTest("android.appwidget.cts.packages.launcher2");
128     }
129 
130     @CddTest(requirement = "3.8.2/C-2-1")
verifyIsRequestPinAppWidgetSupported(String launcherPkg, boolean expectedSupport)131     public void verifyIsRequestPinAppWidgetSupported(String launcherPkg, boolean expectedSupport)
132             throws Exception {
133         setLauncher(launcherPkg + "/" + LAUNCHER_CLASS);
134 
135         Context context = getInstrumentation().getContext();
136         assertEquals(expectedSupport,
137                 AppWidgetManager.getInstance(context).isRequestPinAppWidgetSupported());
138     }
139 
140     @Ignore("b/265187199")
141     @Test
testIsRequestPinAppWidgetSupported_launcher1()142     public void testIsRequestPinAppWidgetSupported_launcher1() throws Exception {
143         verifyIsRequestPinAppWidgetSupported("android.appwidget.cts.packages.launcher1", true);
144     }
145 
146     @Ignore("b/265187199")
147     @Test
testIsRequestPinAppWidgetSupported_launcher2()148     public void testIsRequestPinAppWidgetSupported_launcher2() throws Exception {
149         verifyIsRequestPinAppWidgetSupported("android.appwidget.cts.packages.launcher2", true);
150     }
151 
152     @Ignore("b/265187199")
153     @Test
testIsRequestPinAppWidgetSupported_launcher3()154     public void testIsRequestPinAppWidgetSupported_launcher3() throws Exception {
155         verifyIsRequestPinAppWidgetSupported("android.appwidget.cts.packages.launcher3", false);
156     }
157 
getDefaultLauncher()158     private String getDefaultLauncher() throws Exception {
159         final String PREFIX = "Launcher: ComponentInfo{";
160         final String POSTFIX = "}";
161         for (String s : runShellCommand("cmd shortcut get-default-launcher")) {
162             if (s.startsWith(PREFIX) && s.endsWith(POSTFIX)) {
163                 return s.substring(PREFIX.length(), s.length() - POSTFIX.length());
164             }
165         }
166         throw new Exception("Default launcher not found");
167     }
168 
setLauncher(String component)169     private void setLauncher(String component) throws Exception {
170         Log.i("BalActivity", "cmd package set-home-activity --user "
171                 + getInstrumentation().getContext().getUserId() + " " + component);
172         /*runShellCommand("cmd package set-home-activity --user "
173                 + getInstrumentation().getContext().getUserId() + " " + component);*/
174         runShellCommand("cmd package set-home-activity "
175                  + component);
176     }
177 
178     @Test
testRequestPinAppWidgetNotAllBal()179     public void testRequestPinAppWidgetNotAllBal() throws Exception {
180         String launcherPkg = "android.appwidget.cts.packages.launcher1";
181         setLauncher(launcherPkg + "/" + LAUNCHER_CLASS);
182         Context context = getInstrumentation().getContext();
183         // Request to pin widget
184         BlockingBroadcastReceiver setupReceiver = new BlockingBroadcastReceiver()
185                 .register(Constants.ACTION_SETUP_REPLY);
186 
187         // starts the BalActivity in the test app AppBal.
188         context.startActivity(new Intent(Intent.ACTION_MAIN)
189                 .setPackage("android.appwidget.cts.appbal")
190                 .addFlags(FLAG_ACTIVITY_NEW_TASK));
191 
192         setupReceiver.await();
193         // Verify that the confirmation dialog was opened
194         assertTrue(setupReceiver.result.getBooleanExtra(Constants.EXTRA_SUCCESS, false));
195 
196         // Accept the request
197         context.sendBroadcast(new Intent(Constants.ACTION_CONFIRM_PIN)
198                 .setPackage(launcherPkg));
199 
200         // Press home key to ensure stopAppSwitches is called because the last-stop-app-switch-time
201         // is a criteria of allowing background start.
202         pressHomeButton();
203         SystemUtil.runWithShellPermissionIdentity(ActivityManager::resumeAppSwitches);
204         mWmState.waitForHomeActivityVisible();
205         SystemUtil.runWithShellPermissionIdentity(ActivityManager::resumeAppSwitches);
206 
207         boolean result = false;
208         // The background activity will be launched 30s after the BalService starts. The
209         // waitForFocusedActivity only waits for 5s. So put it in a for loop.
210         for (int i = 0; i < 10; i++) {
211             result = mWmState.waitForFocusedActivity(
212                     "Empty Activity is launched", new ComponentName(context, EmptyActivity.class));
213             if (result) break;
214         }
215         assertFalse("Should not able to launch background activity", result);
216     }
217 
218 }
219