// Copyright 2015 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.tab;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.common.Referrer;
import org.chromium.ui.base.Clipboard;
import org.chromium.ui.base.PageTransition;
import java.net.URI;
import java.util.Locale;
/**
* A default {@link ContextMenuItemDelegate} that supports the context menu functionality in Tab.
*/
public class TabContextMenuItemDelegate implements ContextMenuItemDelegate {
public static final String PAGESPEED_PASSTHROUGH_HEADERS =
"Chrome-Proxy: pass-through\nCache-Control: no-cache";
private final Clipboard mClipboard;
private final Tab mTab;
/**
* Builds a {@link TabContextMenuItemDelegate} instance.
*/
public TabContextMenuItemDelegate(Tab tab) {
mTab = tab;
mClipboard = new Clipboard(mTab.getApplicationContext());
}
@Override
public boolean isIncognito() {
return mTab.isIncognito();
}
@Override
public boolean isIncognitoSupported() {
return PrefServiceBridge.getInstance().isIncognitoModeEnabled();
}
@Override
public boolean isOpenInOtherWindowSupported() {
return MultiWindowUtils.getInstance().isOpenInOtherWindowSupported(mTab.getActivity());
}
@Override
public boolean isDataReductionProxyEnabledForURL(String url) {
return isSpdyProxyEnabledForUrl(url);
}
@Override
public boolean startDownload(String url, boolean isLink) {
return !isLink || !mTab.shouldInterceptContextMenuDownload(url);
}
@Override
public void onSaveToClipboard(String text, int clipboardType) {
mClipboard.setText(text);
}
@Override
public void onOpenInOtherWindow(String url, Referrer referrer) {
TabDelegate tabDelegate = new TabDelegate(mTab.isIncognito());
LoadUrlParams loadUrlParams = new LoadUrlParams(url);
loadUrlParams.setReferrer(referrer);
tabDelegate.createTabInOtherWindow(loadUrlParams, mTab.getActivity(), mTab.getParentId());
}
@Override
public void onOpenInNewTab(String url, Referrer referrer) {
RecordUserAction.record("MobileNewTabOpened");
LoadUrlParams loadUrlParams = new LoadUrlParams(url);
loadUrlParams.setReferrer(referrer);
Tab newTab = mTab.getTabModelSelector().openNewTab(
loadUrlParams, TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab, isIncognito());
// {@code newTab} is null in document mode. Do not record metrics for document mode.
if (mTab.getTabUma() != null && newTab != null) {
mTab.getTabUma().onBackgroundTabOpenedFromContextMenu(newTab);
}
}
@Override
public void onReloadLoFiImages() {
mTab.reloadLoFiImages();
}
@Override
public void onLoadOriginalImage() {
mTab.loadOriginalImage();
}
@Override
public void onOpenInNewIncognitoTab(String url) {
RecordUserAction.record("MobileNewTabOpened");
mTab.getTabModelSelector().openNewTab(new LoadUrlParams(url),
TabLaunchType.FROM_LONGPRESS_FOREGROUND, mTab, true);
}
@Override
public String getPageUrl() {
return mTab.getUrl();
}
@Override
public void onOpenImageUrl(String url, Referrer referrer) {
LoadUrlParams loadUrlParams = new LoadUrlParams(url);
loadUrlParams.setTransitionType(PageTransition.LINK);
loadUrlParams.setReferrer(referrer);
mTab.loadUrl(loadUrlParams);
}
@Override
public void onOpenImageInNewTab(String url, Referrer referrer) {
boolean useOriginal = isSpdyProxyEnabledForUrl(url);
LoadUrlParams loadUrlParams = new LoadUrlParams(url);
loadUrlParams.setVerbatimHeaders(useOriginal ? PAGESPEED_PASSTHROUGH_HEADERS : null);
loadUrlParams.setReferrer(referrer);
mTab.getActivity().getTabModelSelector().openNewTab(loadUrlParams,
TabLaunchType.FROM_LONGPRESS_BACKGROUND, mTab, isIncognito());
}
@Override
public void onOpenInChrome(String linkUrl, String pageUrl) {
Intent chromeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl));
chromeIntent.setPackage(mTab.getApplicationContext().getPackageName());
chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
boolean activityStarted = false;
if (pageUrl != null) {
try {
URI pageUri = URI.create(pageUrl);
if (UrlUtilities.isInternalScheme(pageUri)) {
IntentHandler.startChromeLauncherActivityForTrustedIntent(
chromeIntent, mTab.getApplicationContext());
activityStarted = true;
}
} catch (IllegalArgumentException ex) {
// Ignore the exception for creating the URI and launch the intent
// without the trusted intent extras.
}
}
if (!activityStarted) {
Context context = mTab.getActivity();
if (context == null) context = mTab.getApplicationContext();
context.startActivity(chromeIntent);
activityStarted = true;
}
}
@Override
public void onSavePageLater(String linkUrl) {
OfflinePageBridge.getForProfile(mTab.getProfile())
.savePageLater(linkUrl, "async_loading", true /* userRequested */);
}
/**
* Checks if spdy proxy is enabled for input url.
* @param url Input url to check for spdy setting.
* @return true if url is enabled for spdy proxy.
*/
private boolean isSpdyProxyEnabledForUrl(String url) {
if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled()
&& url != null && !url.toLowerCase(Locale.US).startsWith("https://")
&& !isIncognito()) {
return true;
}
return false;
}
}