Commit 6aea9a3e authored by ppi@chromium.org's avatar ppi@chromium.org

Android: support http referrers for context menu navigations.

This patch provides the support needed for setting http referrers on URL
loads triggered from the context menu:

- adds Referrer.java holder corresponding to the native
  content::Referrer
- ContextMenuParams.java now holds a Referrer field set (along with
  sanitization) by ContextMenuHelper
- ContextMenuItemDelegate methods that trigger new navigations accept a
  Referrer parameter (save for OpenInNewIncognitoTab, as we drop the
  referrer in this case)
- LoadUrlParams.java also gets a Referrer field, so that embedders can
  set it in their ContextMenuItemDelegate implementations

BUG=340295

Review URL: https://codereview.chromium.org/178193033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255370 0039d316-1c4b-4281-b951-d872f2087c98
parent ad35a60c
......@@ -5,7 +5,7 @@
package org.chromium.chrome.browser.contextmenu;
import org.chromium.chrome.browser.Tab;
import org.chromium.content.browser.ContentView;
import org.chromium.content_public.Referrer;
/**
* A delegate responsible for taking actions based on context menu selections.
......@@ -39,7 +39,7 @@ public interface ChromeContextMenuItemDelegate {
* the current {@link Tab}.
* @param url The URL to open.
*/
void onOpenInNewTab(String url);
void onOpenInNewTab(String url, Referrer referrer);
/**
* Called when the {@code url} should be opened in a new incognito tab.
......@@ -51,13 +51,13 @@ public interface ChromeContextMenuItemDelegate {
* Called when the {@code url} is of an image and should be opened in the same tab.
* @param url The image URL to open.
*/
void onOpenImageUrl(String url);
void onOpenImageUrl(String url, Referrer referrer);
/**
* Called when the {@code url} is of an image and should be opened in a new tab.
* @param url The image URL to open.
*/
void onOpenImageInNewTab(String url);
void onOpenImageInNewTab(String url, Referrer referrer);
/**
* Called when the {@code text} should be saved to the clipboard.
......
......@@ -95,14 +95,14 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
@Override
public boolean onItemSelected(ContextMenuHelper helper, ContextMenuParams params, int itemId) {
if (itemId == R.id.contextmenu_open_in_new_tab) {
mDelegate.onOpenInNewTab(params.getLinkUrl());
mDelegate.onOpenInNewTab(params.getLinkUrl(), params.getReferrer());
} else if (itemId == R.id.contextmenu_open_in_incognito_tab) {
mDelegate.onOpenInNewIncognitoTab(params.getLinkUrl());
} else if (itemId == R.id.contextmenu_open_image) {
mDelegate.onOpenImageUrl(params.getSrcUrl());
mDelegate.onOpenImageUrl(params.getSrcUrl(), params.getReferrer());
} else if (itemId == R.id.contextmenu_open_image_in_new_tab ||
itemId == R.id.contextmenu_open_original_image_in_new_tab) {
mDelegate.onOpenImageInNewTab(params.getSrcUrl());
mDelegate.onOpenImageInNewTab(params.getSrcUrl(), params.getReferrer());
} else if (itemId == R.id.contextmenu_copy_link_address_text) {
mDelegate.onSaveToClipboard(params.getUnfilteredLinkUrl(), true);
} else if (itemId == R.id.contextmenu_copy_link_text) {
......@@ -122,4 +122,4 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
return true;
}
}
\ No newline at end of file
}
......@@ -8,6 +8,7 @@ import android.text.TextUtils;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.content_public.Referrer;
import java.util.ArrayList;
......@@ -43,6 +44,7 @@ public class ContextMenuParams {
private final String mUnfilteredLinkUrl;
private final String mSrcUrl;
private final boolean mIsEditable;
private final Referrer mReferrer;
private final boolean mIsAnchor;
private final boolean mIsSelectedText;
......@@ -120,6 +122,13 @@ public class ContextMenuParams {
return mIsEditable;
}
/**
* @return the referrer associated with the frame on which the menu is invoked
*/
public Referrer getReferrer() {
return mReferrer;
}
/**
* @return Whether or not the context menu is being shown for an anchor.
*/
......@@ -149,12 +158,14 @@ public class ContextMenuParams {
}
private ContextMenuParams(int mediaType, String linkUrl, String linkText,
String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable) {
String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable,
Referrer referrer) {
mLinkUrl = linkUrl;
mLinkText = linkText;
mUnfilteredLinkUrl = unfilteredLinkUrl;
mSrcUrl = srcUrl;
mIsEditable = isEditable;
mReferrer = referrer;
mIsAnchor = !TextUtils.isEmpty(linkUrl);
mIsSelectedText = !TextUtils.isEmpty(selectionText);
......@@ -164,13 +175,16 @@ public class ContextMenuParams {
@CalledByNative
private static ContextMenuParams create(int mediaType, String linkUrl, String linkText,
String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable) {
String unfilteredLinkUrl, String srcUrl, String selectionText, boolean isEditable,
String sanitizedReferrer, int referrerPolicy) {
Referrer referrer = TextUtils.isEmpty(sanitizedReferrer) ?
null : new Referrer(sanitizedReferrer, referrerPolicy);
return new ContextMenuParams(mediaType, linkUrl, linkText, unfilteredLinkUrl, srcUrl,
selectionText, isEditable);
selectionText, isEditable, referrer);
}
@CalledByNative
private void addCustomItem(String label, int action) {
mCustomMenuItems.add(new CustomMenuItem(label, action));
}
}
\ No newline at end of file
}
......@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.contextmenu;
import org.chromium.content_public.Referrer;
/**
* An empty implementation of {@link ChromeContextMenuItemDelegate} to make overriding subsets of
* the delegate methods easier.
......@@ -30,7 +32,7 @@ public class EmptyChromeContextMenuItemDelegate implements ChromeContextMenuItem
}
@Override
public void onOpenInNewTab(String url) {
public void onOpenInNewTab(String url, Referrer referrer) {
}
@Override
......@@ -38,11 +40,11 @@ public class EmptyChromeContextMenuItemDelegate implements ChromeContextMenuItem
}
@Override
public void onOpenImageUrl(String url) {
public void onOpenImageUrl(String url, Referrer referrer) {
}
@Override
public void onOpenImageInNewTab(String url) {
public void onOpenImageInNewTab(String url, Referrer referrer) {
}
@Override
......@@ -56,4 +58,4 @@ public class EmptyChromeContextMenuItemDelegate implements ChromeContextMenuItem
@Override
public void onSearchByImageInNewTab() {
}
}
\ No newline at end of file
}
......@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.infobar.AutoLoginProcessor;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewClient;
import org.chromium.content.browser.LoadUrlParams;
import org.chromium.content_public.Referrer;
import org.chromium.ui.base.WindowAndroid;
/**
......@@ -102,7 +103,7 @@ public class TestShellTab extends Tab {
protected ContextMenuPopulator createContextMenuPopulator() {
return new ChromeContextMenuPopulator(new TabChromeContextMenuItemDelegate() {
@Override
public void onOpenImageUrl(String url) {
public void onOpenImageUrl(String url, Referrer referrer) {
loadUrlWithSanitization(url);
}
});
......
......@@ -66,6 +66,9 @@ void ContextMenuHelper::SetPopulator(jobject jpopulator) {
base::android::ScopedJavaLocalRef<jobject>
ContextMenuHelper::CreateJavaContextMenuParams(
const content::ContextMenuParams& params) {
GURL sanitizedReferrer = SanitizeReferrer(
params.frame_url.is_empty() ? params.page_url : params.frame_url);
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> jmenu_info =
ContextMenuParamsAndroid::Java_ContextMenuParams_create(
......@@ -76,7 +79,9 @@ ContextMenuHelper::CreateJavaContextMenuParams(
ConvertUTF8ToJavaString(env, params.unfiltered_link_url.spec()).obj(),
ConvertUTF8ToJavaString(env, params.src_url.spec()).obj(),
ConvertUTF16ToJavaString(env, params.selection_text).obj(),
params.is_editable);
params.is_editable,
ConvertUTF8ToJavaString(env, sanitizedReferrer.spec()).obj(),
params.referrer_policy);
std::vector<content::MenuItem>::const_iterator i;
for (i = params.custom_items.begin(); i != params.custom_items.end(); ++i) {
......@@ -90,6 +95,19 @@ ContextMenuHelper::CreateJavaContextMenuParams(
return jmenu_info;
}
GURL ContextMenuHelper::SanitizeReferrer(const GURL& referring_url) {
// This mirrors sanitization done on Desktop in RenderViewContextMenu.
if (referring_url.is_valid() && (referring_url.has_ref() ||
referring_url.has_username() || referring_url.has_password())) {
GURL::Replacements referrer_mods;
referrer_mods.ClearRef();
referrer_mods.ClearUsername();
referrer_mods.ClearPassword();
return referring_url.ReplaceComponents(referrer_mods);
}
return referring_url;
}
void ContextMenuHelper::OnCustomItemSelected(JNIEnv* env,
jobject obj,
jint action) {
......
......@@ -41,6 +41,9 @@ class ContextMenuHelper
static base::android::ScopedJavaLocalRef<jobject> CreateJavaContextMenuParams(
const content::ContextMenuParams& params);
// Strips the referring url of the username, password and ref fields.
static GURL SanitizeReferrer(const GURL& referrer);
base::android::ScopedJavaGlobalRef<jobject> java_obj_;
content::WebContents* web_contents_;
......
......@@ -33,6 +33,16 @@ public final class TestHttpServerClient {
return "http://localhost:" + SERVER_PORT + "/" + path;
}
/**
* Construct a URL for loading a test data file with HTTP authentication fields.
*
* @param path path relative to the document root.
* @return an HTTP url.
*/
public static String getUrl(String path, String username, String password) {
return "http://" + username + ":" + password + "@localhost:" + SERVER_PORT + "/" + path;
}
/**
* Establishes a connection with the test server at default URL and verifies that it is running.
*/
......
......@@ -6,6 +6,7 @@ package org.chromium.content.browser;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.content_public.Referrer;
import java.util.Locale;
import java.util.Map;
......@@ -37,9 +38,10 @@ public class LoadUrlParams {
String mUrl;
int mLoadUrlType;
int mTransitionType;
int mUaOverrideOption;
Referrer mReferrer;
private Map<String, String> mExtraHeaders;
private String mVerbatimHeaders;
int mUaOverrideOption;
byte[] mPostData;
String mBaseUrlForDataUrl;
String mVirtualUrlForDataUrl;
......@@ -222,11 +224,17 @@ public class LoadUrlParams {
}
/**
* Set user agent override option of this load. Defaults to UA_OVERRIDE_INHERIT.
* @param uaOption One of UA_OVERRIDE static constants above.
* @return the referrer of this load
*/
public void setOverrideUserAgent(int uaOption) {
mUaOverrideOption = uaOption;
public void setReferrer(Referrer referrer) {
mReferrer = referrer;
}
/**
* Sets the referrer of this load.
*/
public Referrer getReferrer() {
return mReferrer;
}
/**
......@@ -291,6 +299,14 @@ public class LoadUrlParams {
return mVerbatimHeaders;
}
/**
* Set user agent override option of this load. Defaults to UA_OVERRIDE_INHERIT.
* @param uaOption One of UA_OVERRIDE static constants above.
*/
public void setOverrideUserAgent(int uaOption) {
mUaOverrideOption = uaOption;
}
/**
* Set the post data of this load. This field is ignored unless load type is
* LOAD_TYPE_BROWSER_INITIATED_HTTP_POST.
......
// Copyright 2014 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.content_public;
/**
* Container that holds together a referrer URL along with the referrer policy set on the
* originating frame. This corresponds to native content/public/common/referrer.h.
*/
public class Referrer {
private final String mUrl;
private final int mPolicy;
public Referrer(String url, int policy) {
mUrl = url;
mPolicy = policy;
}
public String getUrl() {
return mUrl;
}
public int getPolicy() {
return mPolicy;
}
}
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