1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.chrome.browser; 6 7import android.content.Intent; 8import android.test.FlakyTest; 9 10import org.chromium.base.test.util.UrlUtils; 11import org.chromium.chrome.shell.ChromeShellActivity; 12import org.chromium.chrome.shell.ChromeShellApplication; 13import org.chromium.chrome.shell.ChromeShellApplicationObserver; 14import org.chromium.chrome.shell.ChromeShellTestBase; 15import org.chromium.content.browser.test.util.Criteria; 16import org.chromium.content.browser.test.util.CriteriaHelper; 17 18/** 19 * Tests org.chromium.chrome.browser.ShortcutHelper and it's C++ counterpart. 20 */ 21public class ShortcutHelperTest extends ChromeShellTestBase { 22 private static final String WEBAPP_ACTION_NAME = "WEBAPP_ACTION"; 23 24 private static final String WEBAPP_TITLE = "Webapp shortcut"; 25 private static final String WEBAPP_HTML = UrlUtils.encodeHtmlDataUri( 26 "<html><head>" 27 + "<meta name=\"mobile-web-app-capable\" content=\"yes\" />" 28 + "<title>" + WEBAPP_TITLE + "</title>" 29 + "</head><body>Webapp capable</body></html>"); 30 private static final String EDITED_WEBAPP_TITLE = "Webapp shortcut edited"; 31 32 private static final String SECOND_WEBAPP_TITLE = "Webapp shortcut #2"; 33 private static final String SECOND_WEBAPP_HTML = UrlUtils.encodeHtmlDataUri( 34 "<html><head>" 35 + "<meta name=\"mobile-web-app-capable\" content=\"yes\" />" 36 + "<title>" + SECOND_WEBAPP_TITLE + "</title>" 37 + "</head><body>Webapp capable again</body></html>"); 38 39 private static final String NORMAL_TITLE = "Plain shortcut"; 40 private static final String NORMAL_HTML = UrlUtils.encodeHtmlDataUri( 41 "<html>" 42 + "<head><title>" + NORMAL_TITLE + "</title></head>" 43 + "<body>Not Webapp capable</body></html>"); 44 45 private static final String META_APP_NAME_TITLE = "Web application-name"; 46 private static final String META_APP_NAME_HTML = UrlUtils.encodeHtmlDataUri( 47 "<html><head>" 48 + "<meta name=\"mobile-web-app-capable\" content=\"yes\" />" 49 + "<meta name=\"application-name\" content=\"" + META_APP_NAME_TITLE + "\">" 50 + "<title>Not the right title</title>" 51 + "</head><body>Webapp capable</body></html>"); 52 53 private static class TestObserver implements ChromeShellApplicationObserver { 54 Intent mFiredIntent; 55 56 @Override 57 public boolean onSendBroadcast(Intent intent) { 58 if (intent.hasExtra(Intent.EXTRA_SHORTCUT_NAME)) { 59 // Stop a shortcut from really being added. 60 mFiredIntent = intent; 61 return false; 62 } 63 64 return true; 65 } 66 67 public void reset() { 68 mFiredIntent = null; 69 } 70 } 71 72 private ChromeShellActivity mActivity; 73 private TestObserver mTestObserver; 74 75 @Override 76 public void setUp() throws Exception { 77 ShortcutHelper.setFullScreenAction(WEBAPP_ACTION_NAME); 78 mActivity = launchChromeShellWithBlankPage(); 79 80 // Set up the observer. 81 mTestObserver = new TestObserver(); 82 ChromeShellApplication application = 83 (ChromeShellApplication) mActivity.getApplication(); 84 application.addObserver(mTestObserver); 85 86 super.setUp(); 87 } 88 89 /** 90 * @MediumTest 91 * @Feature("{Webapp}") 92 * crbug.com/303486 93 */ 94 @FlakyTest 95 public void testAddWebappShortcuts() throws InterruptedException { 96 // Add a webapp shortcut and make sure the intent's parameters make sense. 97 addShortcutToURL(WEBAPP_HTML, ""); 98 Intent firedIntent = mTestObserver.mFiredIntent; 99 assertEquals(WEBAPP_TITLE, firedIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 100 101 Intent launchIntent = firedIntent.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 102 assertEquals(WEBAPP_HTML, launchIntent.getStringExtra(ShortcutHelper.EXTRA_URL)); 103 assertEquals(WEBAPP_ACTION_NAME, launchIntent.getAction()); 104 assertEquals(mActivity.getPackageName(), launchIntent.getPackage()); 105 106 // Add a second shortcut and make sure it matches the second webapp's parameters. 107 mTestObserver.reset(); 108 addShortcutToURL(SECOND_WEBAPP_HTML, ""); 109 Intent newFiredIntent = mTestObserver.mFiredIntent; 110 assertEquals(SECOND_WEBAPP_TITLE, 111 newFiredIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 112 113 Intent newLaunchIntent = newFiredIntent.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 114 assertEquals(SECOND_WEBAPP_HTML, newLaunchIntent.getStringExtra(ShortcutHelper.EXTRA_URL)); 115 assertEquals(WEBAPP_ACTION_NAME, newLaunchIntent.getAction()); 116 assertEquals(mActivity.getPackageName(), newLaunchIntent.getPackage()); 117 } 118 119 /** 120 * @MediumTest 121 * @Feature("{Webapp}") 122 * crbug.com/303486 123 */ 124 @FlakyTest 125 public void testAddBookmarkShortcut() throws InterruptedException { 126 addShortcutToURL(NORMAL_HTML, ""); 127 128 // Make sure the intent's parameters make sense. 129 Intent firedIntent = mTestObserver.mFiredIntent; 130 assertEquals(NORMAL_TITLE, firedIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 131 132 Intent launchIntent = firedIntent.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 133 assertEquals(mActivity.getPackageName(), launchIntent.getPackage()); 134 assertEquals(Intent.ACTION_VIEW, launchIntent.getAction()); 135 assertEquals(NORMAL_HTML, launchIntent.getDataString()); 136 } 137 138 /** 139 * @MediumTest 140 * @Feature("{Webapp}") 141 * crbug.com/303486 142 */ 143 @FlakyTest 144 public void testAddWebappShortcutsWithoutTitleEdit() throws InterruptedException { 145 // Add a webapp shortcut to check unedited title. 146 addShortcutToURL(WEBAPP_HTML, ""); 147 Intent firedIntent = mTestObserver.mFiredIntent; 148 assertEquals(WEBAPP_TITLE, firedIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 149 } 150 151 /** 152 * @MediumTest 153 * @Feature("{Webapp}") 154 * crbug.com/303486 155 */ 156 @FlakyTest 157 public void testAddWebappShortcutsWithTitleEdit() throws InterruptedException { 158 // Add a webapp shortcut to check edited title. 159 addShortcutToURL(WEBAPP_HTML, EDITED_WEBAPP_TITLE); 160 Intent firedIntent = mTestObserver.mFiredIntent; 161 assertEquals(EDITED_WEBAPP_TITLE , firedIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 162 } 163 164 /** 165 * @MediumTest 166 * @Feature("{Webapp}") 167 * crbug.com/303486 168 */ 169 @FlakyTest 170 public void testAddWebappShortcutsWithApplicationName() throws InterruptedException { 171 // Add a webapp shortcut to check edited title. 172 addShortcutToURL(META_APP_NAME_HTML, ""); 173 Intent firedIntent = mTestObserver.mFiredIntent; 174 assertEquals(META_APP_NAME_TITLE , firedIntent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)); 175 } 176 177 private void addShortcutToURL(String url, final String title) throws InterruptedException { 178 loadUrlWithSanitization(url); 179 assertTrue(waitForActiveShellToBeDoneLoading()); 180 181 // Add the shortcut. 182 getInstrumentation().runOnMainSync(new Runnable() { 183 @Override 184 public void run() { 185 final ShortcutHelper shortcutHelper = new ShortcutHelper( 186 mActivity.getApplicationContext(), mActivity.getActiveTab()); 187 // Calling initialize() isn't strictly required but it is 188 // testing this code path. 189 shortcutHelper.initialize(new ShortcutHelper.OnInitialized() { 190 @Override 191 public void onInitialized(String t) { 192 shortcutHelper.addShortcut(title); 193 } 194 }); 195 } 196 }); 197 198 // Make sure that the shortcut was added. 199 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { 200 @Override 201 public boolean isSatisfied() { 202 return mTestObserver.mFiredIntent != null; 203 } 204 })); 205 } 206} 207