Commit b3fc4f4d authored by Theresa Wellington's avatar Theresa Wellington Committed by Commit Bot

Add tests for Android launcher shortcuts

Add a suite of tests verifying Android NMR1+ launcher shorcut behavior.

BUG=632541

Change-Id: I4603610989fe145bbe410ad51c0900036bcb468d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2121083
Commit-Queue: Theresa  <twellington@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753475}
parent 398018f2
...@@ -21,6 +21,7 @@ chrome_test_java_sources = [ ...@@ -21,6 +21,7 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/InstantStartTest.java", "javatests/src/org/chromium/chrome/browser/InstantStartTest.java",
"javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java", "javatests/src/org/chromium/chrome/browser/IntentHandlerTest.java",
"javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java", "javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java",
"javatests/src/org/chromium/chrome/browser/LauncherShortcutTest.java",
"javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java", "javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java",
"javatests/src/org/chromium/chrome/browser/MockSafeBrowsingApiHandler.java", "javatests/src/org/chromium/chrome/browser/MockSafeBrowsingApiHandler.java",
"javatests/src/org/chromium/chrome/browser/NavigateTest.java", "javatests/src/org/chromium/chrome/browser/NavigateTest.java",
......
...@@ -33,8 +33,8 @@ public class LauncherShortcutActivity extends Activity { ...@@ -33,8 +33,8 @@ public class LauncherShortcutActivity extends Activity {
public static final String ACTION_OPEN_NEW_TAB = "chromium.shortcut.action.OPEN_NEW_TAB"; public static final String ACTION_OPEN_NEW_TAB = "chromium.shortcut.action.OPEN_NEW_TAB";
public static final String ACTION_OPEN_NEW_INCOGNITO_TAB = public static final String ACTION_OPEN_NEW_INCOGNITO_TAB =
"chromium.shortcut.action.OPEN_NEW_INCOGNITO_TAB"; "chromium.shortcut.action.OPEN_NEW_INCOGNITO_TAB";
private static final String DYNAMIC_OPEN_NEW_INCOGNITO_TAB_ID = @VisibleForTesting
"dynamic-new-incognito-tab-shortcut"; static final String DYNAMIC_OPEN_NEW_INCOGNITO_TAB_ID = "dynamic-new-incognito-tab-shortcut";
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
...@@ -71,15 +71,18 @@ public class LauncherShortcutActivity extends Activity { ...@@ -71,15 +71,18 @@ public class LauncherShortcutActivity extends Activity {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return;
SharedPreferencesManager preferences = SharedPreferencesManager.getInstance(); SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
if (IncognitoUtils.isIncognitoModeEnabled()) { boolean incognitoEnabled = IncognitoUtils.isIncognitoModeEnabled();
boolean incognitoShortcutAdded =
preferences.readBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, false);
if (incognitoEnabled && !incognitoShortcutAdded) {
boolean success = LauncherShortcutActivity.addIncognitoLauncherShortcut(context); boolean success = LauncherShortcutActivity.addIncognitoLauncherShortcut(context);
// Save a shared preference indicating the incognito shortcut has been added. // Save a shared preference indicating the incognito shortcut has been added.
if (success) { if (success) {
preferences.writeBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, true); preferences.writeBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, true);
} }
} else if (preferences.readBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, false) } else if (!incognitoEnabled && incognitoShortcutAdded) {
&& !IncognitoUtils.isIncognitoModeEnabled()) {
LauncherShortcutActivity.removeIncognitoLauncherShortcut(context); LauncherShortcutActivity.removeIncognitoLauncherShortcut(context);
preferences.writeBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, false); preferences.writeBoolean(ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, false);
} }
...@@ -88,7 +91,7 @@ public class LauncherShortcutActivity extends Activity { ...@@ -88,7 +91,7 @@ public class LauncherShortcutActivity extends Activity {
/** /**
* Adds a "New incognito tab" dynamic launcher shortcut. * Adds a "New incognito tab" dynamic launcher shortcut.
* @param context The context used to retrieve the system {@link ShortcutManager}. * @param context The context used to retrieve the system {@link ShortcutManager}.
* @return True if addint the shortcut has succeeded. False if the call fails due to rate * @return True if adding the shortcut has succeeded. False if the call fails due to rate
* limiting. See {@link ShortcutManager#addDynamicShortcuts}. * limiting. See {@link ShortcutManager#addDynamicShortcuts}.
*/ */
@TargetApi(Build.VERSION_CODES.N_MR1) @TargetApi(Build.VERSION_CODES.N_MR1)
...@@ -131,8 +134,7 @@ public class LauncherShortcutActivity extends Activity { ...@@ -131,8 +134,7 @@ public class LauncherShortcutActivity extends Activity {
* LauncherShortcutActivity. * LauncherShortcutActivity.
* @return An intent for ChromeLauncherActivity that will open a new regular or incognito tab. * @return An intent for ChromeLauncherActivity that will open a new regular or incognito tab.
*/ */
@VisibleForTesting private static Intent getChromeLauncherActivityIntent(
public static Intent getChromeLauncherActivityIntent(
Context context, String launcherShortcutIntentAction) { Context context, String launcherShortcutIntentAction) {
Intent newIntent = IntentHandler.createTrustedOpenNewTabIntent(context, Intent newIntent = IntentHandler.createTrustedOpenNewTabIntent(context,
launcherShortcutIntentAction.equals(ACTION_OPEN_NEW_INCOGNITO_TAB)); launcherShortcutIntentAction.equals(ACTION_OPEN_NEW_INCOGNITO_TAB));
......
...@@ -158,6 +158,15 @@ public class NewTabPage implements NativePage, InvalidationAwareThumbnailProvide ...@@ -158,6 +158,15 @@ public class NewTabPage implements NativePage, InvalidationAwareThumbnailProvide
void onNtpScrollChanged(float scrollPercentage); void onNtpScrollChanged(float scrollPercentage);
} }
/**
* @param gurl The GURL to check whether it is for the NTP.
* @return Whether the passed in URL is used to render the NTP.
*/
public static boolean isNTPUrl(GURL gurl) {
if (!gurl.isValid() || !UrlUtilities.isInternalScheme(gurl)) return false;
return UrlConstants.NTP_HOST.equals(gurl.getHost());
}
/** /**
* @param url The URL to check whether it is for the NTP. * @param url The URL to check whether it is for the NTP.
* @return Whether the passed in URL is used to render the NTP. * @return Whether the passed in URL is used to render the NTP.
...@@ -169,8 +178,7 @@ public class NewTabPage implements NativePage, InvalidationAwareThumbnailProvide ...@@ -169,8 +178,7 @@ public class NewTabPage implements NativePage, InvalidationAwareThumbnailProvide
// We need to fixup the URL to handle about: schemes and transform them into the equivalent // We need to fixup the URL to handle about: schemes and transform them into the equivalent
// chrome:// scheme so that GURL parses the host correctly. // chrome:// scheme so that GURL parses the host correctly.
GURL gurl = UrlFormatter.fixupUrl(url); GURL gurl = UrlFormatter.fixupUrl(url);
if (!gurl.isValid() || !UrlUtilities.isInternalScheme(gurl)) return false; return isNTPUrl(gurl);
return UrlConstants.NTP_HOST.equals(gurl.getHost());
} }
protected class NewTabPageManagerImpl protected class NewTabPageManagerImpl
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.params.ParameterAnnotations;
import org.chromium.base.test.params.ParameterProvider;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.incognito.IncognitoUtils;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabCreationState;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeoutException;
/**
* Tests for Android NMR1 launcher shortcuts.
*/
// clang-format off
@RunWith(ParameterizedRunner.class)
@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@TargetApi(VERSION_CODES.N_MR1)
@MinAndroidSdkLevel(Build.VERSION_CODES.N_MR1)
public class LauncherShortcutTest {
// clang-format on
/**
* Used for parameterized tests to toggle whether an incognito or regular tab is created.
*/
public static class IncognitoParams implements ParameterProvider {
@Override
public Iterable<ParameterSet> getParameters() {
return Arrays.asList(new ParameterSet().value(false).name("RegularTab"),
new ParameterSet().value(true).name("IncognitoTab"));
}
}
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
private TabModelSelector mTabModelSelector;
private CallbackHelper mTabAddedCallback = new CallbackHelper();
@Before
public void setUp() {
mActivityTestRule.startMainActivityOnBlankPage();
mTabModelSelector = mActivityTestRule.getActivity().getTabModelSelector();
TabModelSelectorObserver tabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
@Override
public void onNewTabCreated(Tab tab, @TabCreationState int creationState) {
mTabAddedCallback.notifyCalled();
}
};
mTabModelSelector.addObserver(tabModelSelectorObserver);
}
@Test
@MediumTest
@ParameterAnnotations.UseMethodParameter(IncognitoParams.class)
public void testLauncherShortcut(boolean incognito) throws Exception {
int initialTabCount = mTabModelSelector.getTotalTabCount();
Intent intent =
new Intent(incognito ? LauncherShortcutActivity.ACTION_OPEN_NEW_INCOGNITO_TAB
: LauncherShortcutActivity.ACTION_OPEN_NEW_TAB);
intent.setClass(mActivityTestRule.getActivity(), LauncherShortcutActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
mTabAddedCallback.waitForCallback(0);
// Verify NTP was created.
Tab activityTab = TestThreadUtils.runOnUiThreadBlocking(
() -> mActivityTestRule.getActivity().getActivityTab());
Assert.assertEquals("Incorrect tab launch type.", TabLaunchType.FROM_LAUNCHER_SHORTCUT,
activityTab.getLaunchType());
Assert.assertTrue("Tab should be an NTP. Tab url: " + activityTab.getUrl(),
NewTabPage.isNTPUrl(activityTab.getUrl()));
// Verify tab model.
Assert.assertEquals("Incorrect tab model selected.", incognito,
mTabModelSelector.isIncognitoSelected());
Assert.assertEquals("Incorrect total tab count.", initialTabCount + 1,
mTabModelSelector.getTotalTabCount());
Assert.assertEquals("Incorrect normal tab count.",
incognito ? initialTabCount : initialTabCount + 1,
mTabModelSelector.getModel(false).getCount());
Assert.assertEquals("Incorrect incognito tab count.", incognito ? 1 : 0,
mTabModelSelector.getModel(true).getCount());
}
@Test(expected = TimeoutException.class)
@MediumTest
public void testInvalidIntent() throws TimeoutException {
Intent intent = new Intent("fooAction");
intent.setClass(mActivityTestRule.getActivity(), LauncherShortcutActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
mTabAddedCallback.waitForCallback(0);
}
@Test
@MediumTest
public void testManifestShortcuts() {
ShortcutManager shortcutManager =
mActivityTestRule.getActivity().getSystemService(ShortcutManager.class);
List<ShortcutInfo> shortcuts = shortcutManager.getManifestShortcuts();
Assert.assertEquals("Incorrect number of manifest shortcuts.", 1, shortcuts.size());
Assert.assertEquals(
"Incorrect manifest shortcut id.", "new-tab-shortcut", shortcuts.get(0).getId());
}
@Test
@SmallTest
public void testDynamicShortcuts() {
IncognitoUtils.setEnabledForTesting(true);
LauncherShortcutActivity.updateIncognitoShortcut(mActivityTestRule.getActivity());
ShortcutManager shortcutManager =
mActivityTestRule.getActivity().getSystemService(ShortcutManager.class);
List<ShortcutInfo> shortcuts = shortcutManager.getDynamicShortcuts();
Assert.assertEquals("Incorrect number of dynamic shortcuts.", 1, shortcuts.size());
Assert.assertEquals("Incorrect dynamic shortcut id.",
LauncherShortcutActivity.DYNAMIC_OPEN_NEW_INCOGNITO_TAB_ID,
shortcuts.get(0).getId());
IncognitoUtils.setEnabledForTesting(false);
LauncherShortcutActivity.updateIncognitoShortcut(mActivityTestRule.getActivity());
shortcuts = shortcutManager.getDynamicShortcuts();
Assert.assertEquals("Incorrect number of dynamic shortcuts.", 0, shortcuts.size());
IncognitoUtils.setEnabledForTesting(true);
LauncherShortcutActivity.updateIncognitoShortcut(mActivityTestRule.getActivity());
shortcuts = shortcutManager.getDynamicShortcuts();
Assert.assertEquals("Incorrect number of dynamic shortcuts after re-enabling incognito.", 1,
shortcuts.size());
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment