| // 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.MailTo; |
| import android.net.Uri; |
| import android.provider.Browser; |
| import android.provider.ContactsContract; |
| import android.support.customtabs.CustomTabsIntent; |
| |
| import org.chromium.base.metrics.RecordUserAction; |
| import org.chromium.chrome.browser.DefaultBrowserInfo; |
| import org.chromium.chrome.browser.IntentHandler; |
| import org.chromium.chrome.browser.UrlConstants; |
| import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate; |
| import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
| import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; |
| import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; |
| 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.IntentUtils; |
| 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-Accept-Transform: identity\nCache-Control: no-cache"; |
| |
| private final Tab mTab; |
| private boolean mLoadOriginalImageRequestedForPageLoad; |
| private EmptyTabObserver mDataReductionProxyContextMenuTabObserver; |
| |
| /** |
| * Builds a {@link TabContextMenuItemDelegate} instance. |
| */ |
| public TabContextMenuItemDelegate(Tab tab) { |
| mTab = tab; |
| mDataReductionProxyContextMenuTabObserver = new EmptyTabObserver() { |
| @Override |
| public void onPageLoadStarted(Tab tab, String url) { |
| mLoadOriginalImageRequestedForPageLoad = false; |
| } |
| }; |
| mTab.addObserver(mDataReductionProxyContextMenuTabObserver); |
| } |
| |
| @Override |
| public void onDestroy() { |
| mTab.removeObserver(mDataReductionProxyContextMenuTabObserver); |
| } |
| |
| @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) { |
| Clipboard.getInstance().setText(text); |
| } |
| |
| @Override |
| public boolean supportsCall() { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setData(Uri.parse("tel:")); |
| return mTab.getWindowAndroid().canResolveActivity(intent); |
| } |
| |
| @Override |
| public void onCall(String uri) { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| intent.setData(Uri.parse(uri)); |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| @Override |
| public boolean supportsSendEmailMessage() { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setData(Uri.parse("mailto:test@example.com")); |
| return mTab.getWindowAndroid().canResolveActivity(intent); |
| } |
| |
| @Override |
| public void onSendEmailMessage(String url) { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| intent.setData(Uri.parse(url)); |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| @Override |
| public boolean supportsSendTextMessage() { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setData(Uri.parse("sms:")); |
| return mTab.getWindowAndroid().canResolveActivity(intent); |
| } |
| |
| @Override |
| public void onSendTextMessage(String url) { |
| Intent intent = new Intent(Intent.ACTION_VIEW); |
| intent.setData(Uri.parse("sms:" + UrlUtilities.getTelNumber(url))); |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| @Override |
| public boolean supportsAddToContacts() { |
| Intent intent = new Intent(Intent.ACTION_INSERT); |
| intent.setType(ContactsContract.Contacts.CONTENT_TYPE); |
| return mTab.getWindowAndroid().canResolveActivity(intent); |
| } |
| |
| @Override |
| public void onAddToContacts(String url) { |
| Intent intent = new Intent(Intent.ACTION_INSERT); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| intent.setType(ContactsContract.Contacts.CONTENT_TYPE); |
| if (MailTo.isMailTo(url)) { |
| intent.putExtra( |
| ContactsContract.Intents.Insert.EMAIL, MailTo.parse(url).getTo().split(",")[0]); |
| } else if (UrlUtilities.isTelScheme(url)) { |
| intent.putExtra(ContactsContract.Intents.Insert.PHONE, UrlUtilities.getTelNumber(url)); |
| } |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| @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 onLoadOriginalImage() { |
| mLoadOriginalImageRequestedForPageLoad = true; |
| mTab.loadOriginalImage(); |
| } |
| |
| @Override |
| public boolean wasLoadOriginalImageRequestedForPageLoad() { |
| return mLoadOriginalImageRequestedForPageLoad; |
| } |
| |
| @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); |
| // For "Open in Chrome" from the context menu in FullscreenActivity we want to bypass |
| // CustomTab, and this flag ensures we open in TabbedChrome. |
| chromeIntent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PARENT, false); |
| |
| boolean activityStarted = false; |
| if (pageUrl != null) { |
| try { |
| URI pageUri = URI.create(pageUrl); |
| if (UrlUtilities.isInternalScheme(pageUri)) { |
| IntentHandler.startChromeLauncherActivityForTrustedIntent(chromeIntent); |
| 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 onOpenInNewChromeTabFromCCT(String linkUrl, boolean isIncognito) { |
| Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| intent.setClass(mTab.getApplicationContext(), ChromeLauncherActivity.class); |
| intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PARENT, false); |
| if (isIncognito) { |
| intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); |
| intent.putExtra( |
| Browser.EXTRA_APPLICATION_ID, mTab.getApplicationContext().getPackageName()); |
| IntentHandler.addTrustedIntentExtras(intent); |
| IntentHandler.setTabLaunchType(intent, TabLaunchType.FROM_EXTERNAL_APP); |
| } |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| @Override |
| public String getTitleForOpenTabInExternalApp() { |
| return DefaultBrowserInfo.getTitleOpenInDefaultBrowser(false); |
| } |
| |
| @Override |
| public void onOpenInDefaultBrowser(String url) { |
| Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); |
| CustomTabsIntent.setAlwaysUseBrowserUI(intent); |
| IntentUtils.safeStartActivity(mTab.getActivity(), intent); |
| } |
| |
| /** |
| * 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( |
| UrlConstants.HTTPS_URL_PREFIX) |
| && !isIncognito()) { |
| return true; |
| } |
| return false; |
| } |
| |
| } |