Commit f0976807 authored by Scott Violet's avatar Scott Violet Committed by Chromium LUCI CQ

cct: make it possible to hide 'open in chrome' menu items

Specifically from the context menu and app menu. There are separate
options for each one. This is only allowed if a service connection
is available as well as the right package.

BUG=1154709
TEST=covered by tests

Change-Id: If9b67cbb1ffbb629af3ae207b0aec85378e65ca8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2570238
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833412}
parent a411dd26
...@@ -526,4 +526,18 @@ public abstract class BrowserServicesIntentDataProvider { ...@@ -526,4 +526,18 @@ public abstract class BrowserServicesIntentDataProvider {
public boolean shouldBlockNewNotificationRequests() { public boolean shouldBlockNewNotificationRequests() {
return false; return false;
} }
/**
* Returns true if 'open in chrome' should be shown in the tab context menu.
*/
public boolean shouldShowOpenInChromeMenuItemInContextMenu() {
return true;
}
/**
* Returns true if 'open in chrome' should be shown in the app menu.
*/
public boolean shouldShowOpenInChromeMenuItem() {
return true;
}
} }
...@@ -540,7 +540,8 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { ...@@ -540,7 +540,8 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
.second; .second;
if (mMode == ContextMenuMode.WEB_APP) { if (mMode == ContextMenuMode.WEB_APP) {
items.add(createListItem(Item.OPEN_IN_CHROME)); items.add(createListItem(Item.OPEN_IN_CHROME));
} else if (mMode == ContextMenuMode.CUSTOM_TAB) { } else if (mMode == ContextMenuMode.CUSTOM_TAB
&& mItemDelegate.supportsOpenInChromeFromCct()) {
boolean addNewEntries = false; boolean addNewEntries = false;
try { try {
URI uri = new URI(mParams.getUrl()); URI uri = new URI(mParams.getUrl());
......
...@@ -327,7 +327,7 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab ...@@ -327,7 +327,7 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab
mIntentDataProvider.shouldShowShareMenuItem(), mIntentDataProvider.shouldShowShareMenuItem(),
mIntentDataProvider.shouldShowStarButton(), mIntentDataProvider.shouldShowStarButton(),
mIntentDataProvider.shouldShowDownloadButton(), mIntentDataProvider.isIncognito(), mIntentDataProvider.shouldShowDownloadButton(), mIntentDataProvider.isIncognito(),
getModalDialogManager()); getModalDialogManager(), mIntentDataProvider.shouldShowOpenInChromeMenuItem());
} }
@Override @Override
......
...@@ -55,6 +55,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat ...@@ -55,6 +55,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
private final boolean mShowDownload; private final boolean mShowDownload;
private final boolean mIsOpenedByChrome; private final boolean mIsOpenedByChrome;
private final boolean mIsIncognito; private final boolean mIsIncognito;
private final boolean mShowOpenInChrome;
private final List<String> mMenuEntries; private final List<String> mMenuEntries;
private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>(); private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>();
...@@ -63,6 +64,8 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat ...@@ -63,6 +64,8 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
/** /**
* Creates an {@link CustomTabAppMenuPropertiesDelegate} instance. * Creates an {@link CustomTabAppMenuPropertiesDelegate} instance.
*
* @param showOpenInChrome Whether 'open in chrome' is shown, depending upon other state.
*/ */
public CustomTabAppMenuPropertiesDelegate(Context context, public CustomTabAppMenuPropertiesDelegate(Context context,
ActivityTabProvider activityTabProvider, ActivityTabProvider activityTabProvider,
...@@ -71,7 +74,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat ...@@ -71,7 +74,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
ObservableSupplier<BookmarkBridge> bookmarkBridgeSupplier, Verifier verifier, ObservableSupplier<BookmarkBridge> bookmarkBridgeSupplier, Verifier verifier,
@CustomTabsUiType final int uiType, List<String> menuEntries, boolean isOpenedByChrome, @CustomTabsUiType final int uiType, List<String> menuEntries, boolean isOpenedByChrome,
boolean showShare, boolean showStar, boolean showDownload, boolean isIncognito, boolean showShare, boolean showStar, boolean showDownload, boolean isIncognito,
ModalDialogManager modalDialogManager) { ModalDialogManager modalDialogManager, boolean showOpenInChrome) {
super(context, activityTabProvider, multiWindowModeStateDispatcher, tabModelSelector, super(context, activityTabProvider, multiWindowModeStateDispatcher, tabModelSelector,
toolbarManager, decorView, null, bookmarkBridgeSupplier, modalDialogManager); toolbarManager, decorView, null, bookmarkBridgeSupplier, modalDialogManager);
mVerifier = verifier; mVerifier = verifier;
...@@ -82,6 +85,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat ...@@ -82,6 +85,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
mShowStar = showStar; mShowStar = showStar;
mShowDownload = showDownload; mShowDownload = showDownload;
mIsIncognito = isIncognito; mIsIncognito = isIncognito;
mShowOpenInChrome = showOpenInChrome;
} }
@Override @Override
...@@ -202,6 +206,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat ...@@ -202,6 +206,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
prepareTranslateMenuItem(menu, currentTab); prepareTranslateMenuItem(menu, currentTab);
if (!mShowOpenInChrome) {
openInChromeItemVisible = false;
}
MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id); MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id);
if (openInChromeItemVisible) { if (openInChromeItemVisible) {
String title = mIsIncognito ? String title = mIsIncognito ?
......
...@@ -356,6 +356,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -356,6 +356,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
private final MultiWindowUtils mMultiWindowUtils; private final MultiWindowUtils mMultiWindowUtils;
private final PendingIntent mFocusIntent; private final PendingIntent mFocusIntent;
private final Verifier mVerifier; private final Verifier mVerifier;
private final boolean mShouldShowOpenInChromeMenuItemInContextMenu;
private TabWebContentsDelegateAndroid mWebContentsDelegateAndroid; private TabWebContentsDelegateAndroid mWebContentsDelegateAndroid;
private ExternalNavigationDelegateImpl mNavigationDelegate; private ExternalNavigationDelegateImpl mNavigationDelegate;
...@@ -377,13 +378,15 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -377,13 +378,15 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
* @param verifier Decides how to handle navigation to a new URL. * @param verifier Decides how to handle navigation to a new URL.
* @param ephemeralTabCoordinatorSupplier A provider of {@link EphemeralTabCoordinator} that * @param ephemeralTabCoordinatorSupplier A provider of {@link EphemeralTabCoordinator} that
* shows preview tab. * shows preview tab.
* @param shouldShowOpenInChromeMenuItemInContextMenu Whether 'open in chrome' is shown.
*/ */
private CustomTabDelegateFactory(ChromeActivity<?> activity, boolean shouldHideBrowserControls, private CustomTabDelegateFactory(ChromeActivity<?> activity, boolean shouldHideBrowserControls,
boolean isOpenedByChrome, @Nullable String webApkScopeUrl, boolean isOpenedByChrome, @Nullable String webApkScopeUrl,
@WebDisplayMode int displayMode, boolean shouldEnableEmbeddedMediaExperience, @WebDisplayMode int displayMode, boolean shouldEnableEmbeddedMediaExperience,
BrowserControlsVisibilityDelegate visibilityDelegate, ExternalAuthUtils authUtils, BrowserControlsVisibilityDelegate visibilityDelegate, ExternalAuthUtils authUtils,
MultiWindowUtils multiWindowUtils, @Nullable PendingIntent focusIntent, MultiWindowUtils multiWindowUtils, @Nullable PendingIntent focusIntent,
Verifier verifier, Lazy<EphemeralTabCoordinator> ephemeralTabCoordinator) { Verifier verifier, Lazy<EphemeralTabCoordinator> ephemeralTabCoordinator,
boolean shouldShowOpenInChromeMenuItemInContextMenu) {
mActivity = activity; mActivity = activity;
mShouldHideBrowserControls = shouldHideBrowserControls; mShouldHideBrowserControls = shouldHideBrowserControls;
mIsOpenedByChrome = isOpenedByChrome; mIsOpenedByChrome = isOpenedByChrome;
...@@ -397,6 +400,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -397,6 +400,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
mFocusIntent = focusIntent; mFocusIntent = focusIntent;
mVerifier = verifier; mVerifier = verifier;
mEphemeralTabCoordinator = ephemeralTabCoordinator; mEphemeralTabCoordinator = ephemeralTabCoordinator;
mShouldShowOpenInChromeMenuItemInContextMenu = shouldShowOpenInChromeMenuItemInContextMenu;
} }
@Inject @Inject
...@@ -410,7 +414,8 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -410,7 +414,8 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
getDisplayMode(intentDataProvider), getDisplayMode(intentDataProvider),
intentDataProvider.shouldEnableEmbeddedMediaExperience(), visibilityDelegate, intentDataProvider.shouldEnableEmbeddedMediaExperience(), visibilityDelegate,
authUtils, multiWindowUtils, intentDataProvider.getFocusIntent(), verifier, authUtils, multiWindowUtils, intentDataProvider.getFocusIntent(), verifier,
ephemeralTabCoordinator); ephemeralTabCoordinator,
intentDataProvider.shouldShowOpenInChromeMenuItemInContextMenu());
} }
/** /**
...@@ -419,7 +424,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -419,7 +424,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
*/ */
static CustomTabDelegateFactory createDummy() { static CustomTabDelegateFactory createDummy() {
return new CustomTabDelegateFactory(null, false, false, null, WebDisplayMode.BROWSER, false, return new CustomTabDelegateFactory(null, false, false, null, WebDisplayMode.BROWSER, false,
null, null, null, null, null, () -> null); null, null, null, null, null, () -> null, true);
} }
@Override @Override
...@@ -465,19 +470,28 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { ...@@ -465,19 +470,28 @@ public class CustomTabDelegateFactory implements TabDelegateFactory {
return new ExternalNavigationHandler(mNavigationDelegate); return new ExternalNavigationHandler(mNavigationDelegate);
} }
@VisibleForTesting
TabContextMenuItemDelegate createTabContextMenuItemDelegate(Tab tab) {
TabModelSelector tabModelSelector =
mActivity != null ? mActivity.getTabModelSelector() : null;
return new TabContextMenuItemDelegate(tab, tabModelSelector,
EphemeralTabCoordinator.isSupported() ? mEphemeralTabCoordinator::get : ()
-> null,
() -> {}, mActivity == null ? null : mActivity::getSnackbarManager) {
@Override
public boolean supportsOpenInChromeFromCct() {
return mShouldShowOpenInChromeMenuItemInContextMenu;
}
};
}
@Override @Override
public ContextMenuPopulatorFactory createContextMenuPopulatorFactory(Tab tab) { public ContextMenuPopulatorFactory createContextMenuPopulatorFactory(Tab tab) {
@ChromeContextMenuPopulator.ContextMenuMode @ChromeContextMenuPopulator.ContextMenuMode
int contextMenuMode = getContextMenuMode(mActivityType); int contextMenuMode = getContextMenuMode(mActivityType);
Supplier<ShareDelegate> shareDelegateSupplier = Supplier<ShareDelegate> shareDelegateSupplier =
mActivity == null ? null : mActivity.getShareDelegateSupplier(); mActivity == null ? null : mActivity.getShareDelegateSupplier();
TabModelSelector tabModelSelector = return new ChromeContextMenuPopulatorFactory(createTabContextMenuItemDelegate(tab),
mActivity != null ? mActivity.getTabModelSelector() : null;
return new ChromeContextMenuPopulatorFactory(
new TabContextMenuItemDelegate(tab, tabModelSelector,
EphemeralTabCoordinator.isSupported() ? mEphemeralTabCoordinator::get : ()
-> null,
() -> {}, mActivity == null ? null : mActivity::getSnackbarManager),
shareDelegateSupplier, contextMenuMode, AppHooks.get().getExternalAuthUtils()); shareDelegateSupplier, contextMenuMode, AppHooks.get().getExternalAuthUtils());
} }
......
...@@ -171,6 +171,20 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid ...@@ -171,6 +171,20 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
public static final String EXTRA_HIDE_OMNIBOX_SUGGESTIONS_FROM_CCT = public static final String EXTRA_HIDE_OMNIBOX_SUGGESTIONS_FROM_CCT =
"androidx.browser.customtabs.extra.HIDE_OMNIBOX_SUGGESTIONS_FROM_CCT"; "androidx.browser.customtabs.extra.HIDE_OMNIBOX_SUGGESTIONS_FROM_CCT";
/**
* Extra that determines whether the 'open in chrome' menu item should be shown in the context
* menu. The value is a boolean. Default value is false, meaning the item is shown.
*/
public static final String EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU =
"androidx.browser.customtabs.extra.HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU";
/**
* Extra that determines whether the 'open in chrome' menu item should be shown in the menu. The
* value is a boolean. Default value is false, meaning the item is shown.
*/
public static final String EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM =
"androidx.browser.customtabs.extra.HIDE_OPEN_IN_CHROME_MENU_ITEM";
/** /**
* Extra that, if set, results in marking visits from cct as hidden. The value is * Extra that, if set, results in marking visits from cct as hidden. The value is
* a boolean, and is only considered if the feature kCCTHideVisits is enabled. * a boolean, and is only considered if the feature kCCTHideVisits is enabled.
...@@ -954,4 +968,24 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid ...@@ -954,4 +968,24 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
return IntentUtils.safeGetBooleanExtra( return IntentUtils.safeGetBooleanExtra(
mIntent, EXTRA_BLOCK_NEW_NOTIFICATION_REQUESTS_IN_CCT, false); mIntent, EXTRA_BLOCK_NEW_NOTIFICATION_REQUESTS_IN_CCT, false);
} }
@Override
public boolean shouldShowOpenInChromeMenuItemInContextMenu() {
// Only 1p apps are allowed to hide visits.
String clientPackageName =
CustomTabsConnection.getInstance().getClientPackageNameForSession(getSession());
if (!GSAState.isGsaPackageName(clientPackageName)) return true;
return !IntentUtils.safeGetBooleanExtra(
mIntent, EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU, false);
}
@Override
public boolean shouldShowOpenInChromeMenuItem() {
// Only 1p apps are allowed to hide visits.
String clientPackageName =
CustomTabsConnection.getInstance().getClientPackageNameForSession(getSession());
if (!GSAState.isGsaPackageName(clientPackageName)) return true;
return !IntentUtils.safeGetBooleanExtra(
mIntent, EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM, false);
}
} }
...@@ -317,6 +317,15 @@ public class TabContextMenuItemDelegate implements ContextMenuItemDelegate { ...@@ -317,6 +317,15 @@ public class TabContextMenuItemDelegate implements ContextMenuItemDelegate {
} }
} }
/**
* Returns whether the 'open in chrome' menu item should be shown. This is only called when the
* context menu is shown in cct.
*/
@Override
public boolean supportsOpenInChromeFromCct() {
return true;
}
@Override @Override
public void onOpenInNewChromeTabFromCCT(String linkUrl, boolean isIncognito) { public void onOpenInNewChromeTabFromCCT(String linkUrl, boolean isIncognito) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl));
......
...@@ -73,6 +73,8 @@ public class ChromeContextMenuPopulatorTest { ...@@ -73,6 +73,8 @@ public class ChromeContextMenuPopulatorTest {
@Mock @Mock
private ChromeContextMenuPopulator mPopulator; private ChromeContextMenuPopulator mPopulator;
private boolean mSupportsOpenInChromeFromCct = true;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
...@@ -86,6 +88,8 @@ public class ChromeContextMenuPopulatorTest { ...@@ -86,6 +88,8 @@ public class ChromeContextMenuPopulatorTest {
when(mItemDelegate.supportsSendEmailMessage()).thenReturn(true); when(mItemDelegate.supportsSendEmailMessage()).thenReturn(true);
when(mItemDelegate.supportsSendTextMessage()).thenReturn(true); when(mItemDelegate.supportsSendTextMessage()).thenReturn(true);
when(mItemDelegate.supportsAddToContacts()).thenReturn(true); when(mItemDelegate.supportsAddToContacts()).thenReturn(true);
when(mItemDelegate.supportsOpenInChromeFromCct())
.thenAnswer((mock) -> mSupportsOpenInChromeFromCct);
HashMap<String, Boolean> features = new HashMap<String, Boolean>(); HashMap<String, Boolean> features = new HashMap<String, Boolean>();
features.put(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, false); features.put(ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, false);
...@@ -171,6 +175,23 @@ public class ChromeContextMenuPopulatorTest { ...@@ -171,6 +175,23 @@ public class ChromeContextMenuPopulatorTest {
checkMenuOptions(expected4); checkMenuOptions(expected4);
} }
@Test
@SmallTest
@UiThreadTest
public void testShouldShowOpenInChromeMenuItemInContextMenu() {
FirstRunStatus.setFirstRunFlowComplete(true);
ContextMenuParams params = new ContextMenuParams(0, 0, PAGE_URL, LINK_URL, LINK_TEXT, "",
"", "", null, false, 0, 0, MenuSourceType.MENU_SOURCE_TOUCH);
// If the delegate returns false from supportsOpenInChromeFromCct() then open_in_chrome item
// should not be present.
mSupportsOpenInChromeFromCct = false;
initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params);
int[] expected = {R.id.contextmenu_copy_link_address, R.id.contextmenu_copy_link_text,
R.id.contextmenu_save_link_as, R.id.contextmenu_share_link};
checkMenuOptions(expected);
}
@Test @Test
@SmallTest @SmallTest
@UiThreadTest @UiThreadTest
......
...@@ -108,6 +108,7 @@ import org.chromium.chrome.browser.metrics.PageLoadMetrics; ...@@ -108,6 +108,7 @@ import org.chromium.chrome.browser.metrics.PageLoadMetrics;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabContextMenuItemDelegate;
import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabCreationState;
import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabHidingType;
import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabLaunchType;
...@@ -2572,6 +2573,131 @@ public class CustomTabActivityTest { ...@@ -2572,6 +2573,131 @@ public class CustomTabActivityTest {
.getActivityTab() .getActivityTab()
.getShouldBlockNewNotificationRequests()); .getShouldBlockNewNotificationRequests());
} }
@Test
@SmallTest
public void testHideOpenInChromeMenuItemInContextMenu() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation()
.getTargetContext()
.getApplicationContext();
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
intent.setData(Uri.parse(mTestPage));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(
CustomTabIntentDataProvider.EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU,
true);
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
CustomTabsConnection connection = CustomTabsConnection.getInstance();
connection.newSession(token);
connection.overridePackageNameForSessionForTesting(
token, "com.google.android.googlequicksearchbox");
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
TestThreadUtils.runOnUiThreadBlocking(() -> {
Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
Assert.assertTrue(tab != null);
Assert.assertTrue(
TabTestUtils.getDelegateFactory(tab) instanceof CustomTabDelegateFactory);
TabContextMenuItemDelegate tabContextMenuItemDelegate =
((CustomTabDelegateFactory) TabTestUtils.getDelegateFactory(tab))
.createTabContextMenuItemDelegate(tab);
// EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU should be propagated to the
// tabContextMenuItemDelegate.
Assert.assertFalse(tabContextMenuItemDelegate.supportsOpenInChromeFromCct());
});
}
@Test
@SmallTest
public void testHideOpenInChromeMenuItemInContextMenuIgnoredWrongPackage() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation()
.getTargetContext()
.getApplicationContext();
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
intent.setData(Uri.parse(mTestPage));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(
CustomTabIntentDataProvider.EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU,
true);
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
CustomTabsConnection connection = CustomTabsConnection.getInstance();
connection.newSession(token);
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
// EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU should be ignored without the right
// package.
TestThreadUtils.runOnUiThreadBlocking(() -> {
Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab();
Assert.assertTrue(tab != null);
Assert.assertTrue(
TabTestUtils.getDelegateFactory(tab) instanceof CustomTabDelegateFactory);
TabContextMenuItemDelegate tabContextMenuItemDelegate =
((CustomTabDelegateFactory) TabTestUtils.getDelegateFactory(tab))
.createTabContextMenuItemDelegate(tab);
// EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM_IN_CONTEXT_MENU should be ignored without the
// right package.
Assert.assertTrue(tabContextMenuItemDelegate.supportsOpenInChromeFromCct());
});
}
@Test
@SmallTest
public void testHideOpenInChromeMenuItem() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation()
.getTargetContext()
.getApplicationContext();
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
intent.setData(Uri.parse(mTestPage));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CustomTabIntentDataProvider.EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM, true);
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
CustomTabsConnection connection = CustomTabsConnection.getInstance();
connection.newSession(token);
connection.overridePackageNameForSessionForTesting(
token, "com.google.android.googlequicksearchbox");
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
final ActivityMonitor monitor =
InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, false);
openAppMenuAndAssertMenuShown();
PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
MenuItem item =
AppMenuTestSupport.getMenu(mCustomTabActivityTestRule.getAppMenuCoordinator())
.findItem(R.id.open_in_browser_id);
// The menu item should be there, but hidden.
Assert.assertNotNull(item);
Assert.assertFalse(item.isVisible());
});
}
@Test
@SmallTest
public void testHideOpenInChromeMenuItemVisibleWithWrongPackage() throws Exception {
Context context = InstrumentationRegistry.getInstrumentation()
.getTargetContext()
.getApplicationContext();
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage);
intent.setData(Uri.parse(mTestPage));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CustomTabIntentDataProvider.EXTRA_HIDE_OPEN_IN_CHROME_MENU_ITEM, true);
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
CustomTabsConnection connection = CustomTabsConnection.getInstance();
connection.newSession(token);
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW);
final ActivityMonitor monitor =
InstrumentationRegistry.getInstrumentation().addMonitor(filter, null, false);
openAppMenuAndAssertMenuShown();
PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
MenuItem item =
AppMenuTestSupport.getMenu(mCustomTabActivityTestRule.getAppMenuCoordinator())
.findItem(R.id.open_in_browser_id);
// As the package name doesn't match the expected package, the item should be visible.
Assert.assertNotNull(item);
Assert.assertTrue(item.isVisible());
});
}
/** /**
* The following test that history only has a single final page after speculation, * The following test that history only has a single final page after speculation,
* whether it was a hit or a miss. * whether it was a hit or a miss.
......
...@@ -185,6 +185,11 @@ public interface ContextMenuItemDelegate { ...@@ -185,6 +185,11 @@ public interface ContextMenuItemDelegate {
*/ */
void onOpenInChrome(String linkUrl, String pageUrl); void onOpenInChrome(String linkUrl, String pageUrl);
/**
* Returns true if menu entries should be added for open in chrome.
*/
boolean supportsOpenInChromeFromCct();
/** /**
* Called when the {@code url} should be opened in a new Chrome tab from CCT. * Called when the {@code url} should be opened in a new Chrome tab from CCT.
* @param linkUrl The URL to open. * @param linkUrl The URL to open.
......
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