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