summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon-expected.txt11
-rw-r--r--LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon.html13
-rw-r--r--LayoutTests/http/tests/cookies/multiple-cookies-expected.txt13
-rw-r--r--LayoutTests/http/tests/cookies/multiple-cookies.html13
-rwxr-xr-xLayoutTests/http/tests/cookies/resources/clearCookies.cgi27
-rw-r--r--LayoutTests/http/tests/cookies/resources/cookie-utility.php40
-rw-r--r--LayoutTests/http/tests/cookies/resources/cookies-test-post.js5
-rw-r--r--LayoutTests/http/tests/cookies/resources/cookies-test-pre.js239
-rw-r--r--LayoutTests/http/tests/cookies/resources/cookies-test-style.css12
-rwxr-xr-xLayoutTests/http/tests/cookies/resources/getCookies.cgi8
-rw-r--r--LayoutTests/http/tests/cookies/resources/resetCookies.js18
-rwxr-xr-xLayoutTests/http/tests/cookies/resources/setCookies.cgi9
-rw-r--r--LayoutTests/http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html59
-rw-r--r--LayoutTests/http/tests/cookies/script-tests/TEMPLATE.html13
-rw-r--r--LayoutTests/http/tests/cookies/script-tests/double-quoted-value-with-semi-colon.js11
-rw-r--r--LayoutTests/http/tests/cookies/script-tests/multiple-cookies.js13
-rw-r--r--LayoutTests/http/tests/cookies/script-tests/simple-cookies-expired.js18
-rw-r--r--LayoutTests/http/tests/cookies/script-tests/simple-cookies-max-age.js15
-rw-r--r--LayoutTests/http/tests/cookies/simple-cookies-expired-expected.txt13
-rw-r--r--LayoutTests/http/tests/cookies/simple-cookies-expired.html13
-rw-r--r--LayoutTests/http/tests/cookies/simple-cookies-max-age-expected.txt13
-rw-r--r--LayoutTests/http/tests/cookies/simple-cookies-max-age.html13
-rw-r--r--LayoutTests/http/tests/cookies/third-party-cookie-relaxing-expected.txt47
-rw-r--r--LayoutTests/http/tests/cookies/third-party-cookie-relaxing.html96
-rwxr-xr-xLayoutTests/platform/android/layout_test_directories.txt1
-rw-r--r--LayoutTests/platform/android/test_expectations.txt1
-rw-r--r--WebCore/bridge/jni/v8/JavaClassV8.cpp8
-rw-r--r--WebCore/bridge/jni/v8/JavaClassV8.h1
-rw-r--r--WebCore/dom/Element.cpp2
-rw-r--r--WebCore/platform/graphics/BitmapImage.cpp4
-rw-r--r--WebKit/Android.mk5
-rw-r--r--WebKit/android/WebCoreSupport/PlatformBridge.cpp11
-rw-r--r--WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp22
-rw-r--r--WebKit/android/WebCoreSupport/WebCache.cpp95
-rw-r--r--WebKit/android/WebCoreSupport/WebCache.h24
-rw-r--r--WebKit/android/WebCoreSupport/WebCookieJar.cpp124
-rw-r--r--WebKit/android/WebCoreSupport/WebCookieJar.h65
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp8
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h1
-rw-r--r--WebKit/android/WebCoreSupport/WebRequestContext.cpp147
-rw-r--r--WebKit/android/WebCoreSupport/WebRequestContext.h27
-rw-r--r--WebKit/android/WebCoreSupport/WebResourceRequest.cpp50
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.cpp28
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp10
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h2
-rw-r--r--WebKit/android/jni/CookieManager.cpp44
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp2
-rw-r--r--WebKit/android/jni/WebSettings.cpp4
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp2
-rw-r--r--WebKit/android/nav/CachedRoot.cpp14
-rw-r--r--WebKit/android/nav/WebView.cpp38
51 files changed, 1181 insertions, 291 deletions
diff --git a/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon-expected.txt b/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon-expected.txt
new file mode 100644
index 0000000..e3bf3f6
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon-expected.txt
@@ -0,0 +1,11 @@
+Test for <rdar://problem/5666078> Cookie parsing terminates at the first semicolon, ignoring quotes (16699)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Check that setting a cookie with a semi-colon in a duoble-quoted value works
+PASS cookie is 'disorder="477beccb;richard"'.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon.html b/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon.html
new file mode 100644
index 0000000..0b06db7
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/double-quoted-value-with-semi-colon.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/cookies-test-style.css">
+<script src="resources/cookies-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/double-quoted-value-with-semi-colon.js"></script>
+<script src="resources/cookies-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/multiple-cookies-expected.txt b/LayoutTests/http/tests/cookies/multiple-cookies-expected.txt
new file mode 100644
index 0000000..35b58c1
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/multiple-cookies-expected.txt
@@ -0,0 +1,13 @@
+This test checks that mulitple cookies are correctly set.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Check setting several cookies without clearing.
+PASS cookie is 'test=foobar'.
+PASS cookie is 'test2=foobar; test=foobar'.
+PASS cookie is 'test2=foobar; test3=foobar; test=foobar'.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/cookies/multiple-cookies.html b/LayoutTests/http/tests/cookies/multiple-cookies.html
new file mode 100644
index 0000000..e5b14f3
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/multiple-cookies.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/cookies-test-style.css">
+<script src="resources/cookies-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/multiple-cookies.js"></script>
+<script src="resources/cookies-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/resources/clearCookies.cgi b/LayoutTests/http/tests/cookies/resources/clearCookies.cgi
new file mode 100755
index 0000000..27896b7
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/clearCookies.cgi
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n";
+print "Cache-Control: no-store\n";
+print 'Cache-Control: no-cache="set-cookie"' . "\n";
+
+my $cookie = $ENV{"HTTP_CLEAR_COOKIE"};
+
+if ($cookie =~ /Max-Age/i) {
+ $cookie =~ s/Max-Age *= *[0-9]+/Max-Age=0/i;
+} else {
+ $cookie .= ";" unless ($cookie =~ m/;$/);
+ $cookie .= " " unless ($cookie =~ m/ $/);
+ $cookie .= "Max-Age=0";
+}
+
+if ($cookie =~ /Expires/i) {
+ # Set the "Expires" field to UNIX epoch
+ $cookie =~ s/Expires *= *[^;]+/Expires=Thu, 01 Jan 1970 00:00:00 GMT/i;
+} else {
+ $cookie .= ";" unless ($cookie =~ m/;$/);
+ $cookie .= " " unless ($cookie =~ m/ $/);
+ $cookie .= "Expires=Thu, 01 Jan 1970 00:00:00 GMT";
+}
+
+print "Set-Cookie: $cookie\n\n";
diff --git a/LayoutTests/http/tests/cookies/resources/cookie-utility.php b/LayoutTests/http/tests/cookies/resources/cookie-utility.php
new file mode 100644
index 0000000..a33e7ac
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/cookie-utility.php
@@ -0,0 +1,40 @@
+<?php
+parse_str($_SERVER["QUERY_STRING"]);
+
+function deleteCookie($value, $name)
+{
+ setcookie($name, "deleted", time() - 86400, '/');
+}
+
+if ($queryfunction == "deleteCookies") {
+ array_walk($_COOKIE, deleteCookie);
+ echo "Deleted all cookies";
+ return;
+}
+
+if ($queryfunction == "setFooCookie") {
+ setcookie("foo", "awesomevalue", time() + 86400, '/');
+ echo "Set the foo cookie";
+ return;
+}
+
+if ($queryfunction == "setFooAndBarCookie") {
+ setcookie("foo", "awesomevalue", time() + 86400, '/');
+ setcookie("bar", "anotherawesomevalue", time() + 86400, '/');
+ echo "Set the foo and bar cookies";
+ return;
+}
+
+// Default for any other string is echo cookies.
+function echoCookie($value, $name)
+{
+ echo "$name = $value\n";
+}
+
+function echoAllCookies()
+{
+ echo "Cookies are:\n";
+ array_walk($_COOKIE, echoCookie);
+}
+
+?>
diff --git a/LayoutTests/http/tests/cookies/resources/cookies-test-post.js b/LayoutTests/http/tests/cookies/resources/cookies-test-post.js
new file mode 100644
index 0000000..6970120
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/cookies-test-post.js
@@ -0,0 +1,5 @@
+shouldBeTrue("successfullyParsed");
+debug('<br /><span class="pass">TEST COMPLETE</span>');
+
+// Make sure that we do not leak any cookies.
+clearCookies();
diff --git a/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js b/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js
new file mode 100644
index 0000000..80b0ff1
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js
@@ -0,0 +1,239 @@
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function description(msg)
+{
+ // For MSIE 6 compatibility
+ var span = document.createElement("span");
+ span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>';
+ var description = document.getElementById("description");
+ if (description.firstChild)
+ description.replaceChild(span, description.firstChild);
+ else
+ description.appendChild(span);
+}
+
+function debug(msg)
+{
+ var span = document.createElement("span");
+ document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace
+ span.innerHTML = msg + '<br />';
+}
+
+function escapeHTML(text)
+{
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
+}
+
+function testPassed(msg)
+{
+ debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function testFailed(msg)
+{
+ debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function areArraysEqual(_a, _b)
+{
+ if (_a.length !== _b.length)
+ return false;
+ for (var i = 0; i < _a.length; i++)
+ if (_a[i] !== _b[i])
+ return false;
+ return true;
+}
+
+function isMinusZero(n)
+{
+ // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
+ // -Infinity instead of Infinity
+ return n === 0 && 1/n < 0;
+}
+
+function isResultCorrect(_actual, _expected)
+{
+ if (_expected === 0)
+ return _actual === _expected && (1/_actual) === (1/_expected);
+ if (_actual === _expected)
+ return true;
+ if (typeof(_expected) == "number" && isNaN(_expected))
+ return typeof(_actual) == "number" && isNaN(_actual);
+ if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
+ return areArraysEqual(_actual, _expected);
+ return false;
+}
+
+function stringify(v)
+{
+ if (v === 0 && 1/v < 0)
+ return "-0";
+ else return "" + v;
+}
+
+function shouldBe(_a, _b)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBe() expects string arguments");
+ var exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (exception)
+ testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
+ else if (isResultCorrect(_av, _bv))
+ testPassed(_a + " is " + _b);
+ else if (typeof(_av) == typeof(_bv))
+ testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
+ else
+ testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+}
+
+function shouldBeTrue(_a) { shouldBe(_a, "true"); }
+function shouldBeFalse(_a) { shouldBe(_a, "false"); }
+function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
+function shouldBeNull(_a) { shouldBe(_a, "null"); }
+
+function shouldBeEqualToString(a, b)
+{
+ var unevaledString = '"' + b.replace(/"/g, "\"") + '"';
+ shouldBe(a, unevaledString);
+}
+
+function shouldBeUndefined(_a)
+{
+ var exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ exception = e;
+ }
+
+ if (exception)
+ testFailed(_a + " should be undefined. Threw exception " + exception);
+ else if (typeof _av == "undefined")
+ testPassed(_a + " is undefined.");
+ else
+ testFailed(_a + " should be undefined. Was " + _av);
+}
+
+function shouldThrow(_a, _e)
+{
+ var exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ exception = e;
+ }
+
+ var _ev;
+ if (_e)
+ _ev = eval(_e);
+
+ if (exception) {
+ if (typeof _e == "undefined" || exception == _ev)
+ testPassed(_a + " threw exception " + exception + ".");
+ else
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + ".");
+ } else if (typeof _av == "undefined")
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
+ else
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
+}
+
+var cookies = new Array();
+
+// This method sets the cookies using XMLHttpRequest.
+// We do not set the cookie right away as it is forbidden by the XHR spec.
+// FIXME: Add the possibility to set multiple cookies in a row.
+function setCookies(cookie)
+{
+ try {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", "resources/setCookies.cgi", false);
+ xhr.setRequestHeader("SET_COOKIE", cookie);
+ xhr.send(null);
+ if (xhr.status == 200) {
+ // This is to clear them later.
+ cookies.push(cookie);
+ return true;
+ } else
+ return false;
+ } catch (e) {
+ return false;
+ }
+}
+
+// Normalize a cookie string
+function normalizeCookie(cookie)
+{
+ // Split the cookie string, sort it and then put it back together.
+ return cookie.split('; ').sort().join('; ');
+}
+
+// We get the cookies throught an XMLHttpRequest.
+function testCookies(result)
+{
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", "resources/getCookies.cgi", false);
+ xhr.send(null);
+ var cookie = xhr.getResponseHeader("HTTP_COOKIE") == null ? '"null"' : xhr.getResponseHeader("HTTP_COOKIE");
+
+ // Normalize the cookie strings.
+ result = normalizeCookie(result);
+ cookie = normalizeCookie(cookie);
+
+ if (cookie === result)
+ testPassed("cookie is '" + cookie + "'.");
+ else
+ testFailed("cookie was '" + cookie + "'. Expected '" + result + "'.");
+}
+
+function clearAllCookies()
+{
+ var cookieString;
+ while (cookieString = document.cookie) {
+ var cookieName = cookieString.substr(0, cookieString.indexOf("=") || cookieString.length());
+ cookies.push(cookieName);
+ clearCookies();
+ }
+}
+
+function clearCookies()
+{
+ if (!cookies.length)
+ return;
+
+ try {
+ var xhr = new XMLHttpRequest();
+ var cookie;
+ // We need to clean one cookie at a time because to be cleared the
+ // cookie must be exactly the same except for the "Max-Age"
+ // and "Expires" fields.
+ while (cookie = cookies.pop()) {
+ xhr.open("GET", "resources/clearCookies.cgi", false);
+ xhr.setRequestHeader("CLEAR_COOKIE", cookie);
+ xhr.send(null);
+ }
+ } catch (e) {
+ debug("Could not clear the cookies expect the following results to fail");
+ }
+}
+
+// This method check one cookie at a time.
+function cookiesShouldBe(cookiesToSet, result)
+{
+ if (!setCookies(cookiesToSet)) {
+ testFailed("could not set cookie(s) " + cookiesToSet);
+ return;
+ }
+ testCookies(result);
+}
diff --git a/LayoutTests/http/tests/cookies/resources/cookies-test-style.css b/LayoutTests/http/tests/cookies/resources/cookies-test-style.css
new file mode 100644
index 0000000..f12147c
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/cookies-test-style.css
@@ -0,0 +1,12 @@
+.pass {
+ font-weight: bold;
+ color: green;
+}
+.fail {
+ font-weight: bold;
+ color: red;
+}
+#console {
+ white-space: pre-wrap;
+ font-family: monospace;
+}
diff --git a/LayoutTests/http/tests/cookies/resources/getCookies.cgi b/LayoutTests/http/tests/cookies/resources/getCookies.cgi
new file mode 100755
index 0000000..c4377c3
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/getCookies.cgi
@@ -0,0 +1,8 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n";
+print "Cache-Control: no-store\n";
+print 'Cache-Control: no-cache="set-cookie"' . "\n";
+
+print "HTTP_COOKIE: " . ($ENV{HTTP_COOKIE} || "") . "\n\n";
diff --git a/LayoutTests/http/tests/cookies/resources/resetCookies.js b/LayoutTests/http/tests/cookies/resources/resetCookies.js
new file mode 100644
index 0000000..577822a
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/resetCookies.js
@@ -0,0 +1,18 @@
+function resetCookies()
+{
+ if (window.layoutTestController)
+ layoutTestController.setAlwaysAcceptCookies(true);
+
+ // Due to cross-origin restrictions, we can only (simply) reset cookies for our current origin.
+ var url = "http://" + window.location.hostname +":8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies";
+ var req = new XMLHttpRequest();
+ try {
+ req.open('GET', url, false);
+ req.send();
+ } catch (e) {
+ alert("Attempt to clear " + url + " cookies might have failed. Test results might be off from here on out. (" + e + ")");
+ }
+
+ if (window.layoutTestController)
+ layoutTestController.setAlwaysAcceptCookies(false);
+}
diff --git a/LayoutTests/http/tests/cookies/resources/setCookies.cgi b/LayoutTests/http/tests/cookies/resources/setCookies.cgi
new file mode 100755
index 0000000..b9c4b21
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/setCookies.cgi
@@ -0,0 +1,9 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n";
+print "Cache-Control: no-store\n";
+print 'Cache-Control: no-cache="set-cookie"' . "\n";
+
+# We only map the SET_COOKIE request header to "Set-Cookie"
+print "Set-Cookie: " . $ENV{"HTTP_SET_COOKIE"} . "\n\n";
diff --git a/LayoutTests/http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html b/LayoutTests/http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html
new file mode 100644
index 0000000..d16964e
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html
@@ -0,0 +1,59 @@
+<html>
+<script src="resetCookies.js"></script>
+<script>
+resetCookies();
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+window.onmessage = function(evt)
+{
+ if (evt.data == "showCookies") {
+ showCookies();
+ return;
+ } else if (evt.data.split(" ")[0] == "sendXHR") {
+ sendXHR(evt.data.split(" ")[1]);
+ return;
+ } else if (evt.data == "resetCookiesAndNotifyDone") {
+ resetCookiesAndNotifyDone();
+ return;
+ } else
+ alert("Unknown message.");
+}
+
+var stage = 1;
+function showCookies()
+{
+ alert("Test stage " + stage++ + " document.cookie is: " + document.cookie);
+ parent.window.postMessage("done", "*");
+}
+
+function sendXHR(queryCommand)
+{
+ var baseurl = "http://localhost:8000/cookies/resources/cookie-utility.php";
+ var url = queryCommand ? baseurl + "?queryfunction=" + queryCommand : baseurl;
+ alert(url);
+ var req = new XMLHttpRequest();
+ req.open('GET', url, false);
+ req.send();
+
+ if (req.status == 200)
+ alert("XHR response - " + req.responseText);
+ else
+ alert("xhr error");
+
+ parent.window.postMessage("done", "*");
+}
+
+function resetCookiesAndNotifyDone()
+{
+ resetCookies();
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+</script>
+<body>
+HELLO THERE
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/script-tests/TEMPLATE.html b/LayoutTests/http/tests/cookies/script-tests/TEMPLATE.html
new file mode 100644
index 0000000..6483f50
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/script-tests/TEMPLATE.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/cookies-test-style.css">
+<script src="resources/cookies-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="YOUR_JS_FILE_HERE"></script>
+<script src="resources/cookies-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/script-tests/double-quoted-value-with-semi-colon.js b/LayoutTests/http/tests/cookies/script-tests/double-quoted-value-with-semi-colon.js
new file mode 100644
index 0000000..9029875
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/script-tests/double-quoted-value-with-semi-colon.js
@@ -0,0 +1,11 @@
+description(
+'Test for &lt;<a href="rdar://problem/5666078">rdar://problem/5666078</a>&gt; Cookie parsing terminates at the first semicolon, ignoring quotes (<a href="https://bugs.webkit.org/show_bug.cgi?id=16699">16699</a>)'
+);
+
+clearAllCookies();
+
+debug("Check that setting a cookie with a semi-colon in a duoble-quoted value works");
+cookiesShouldBe('disorder="477beccb;richard";Version=1;Path=/', 'disorder="477beccb;richard"');
+clearCookies();
+
+successfullyParsed = true;
diff --git a/LayoutTests/http/tests/cookies/script-tests/multiple-cookies.js b/LayoutTests/http/tests/cookies/script-tests/multiple-cookies.js
new file mode 100644
index 0000000..618e224
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/script-tests/multiple-cookies.js
@@ -0,0 +1,13 @@
+description(
+"This test checks that mulitple cookies are correctly set."
+);
+
+clearAllCookies();
+
+debug("Check setting several cookies without clearing.");
+cookiesShouldBe("test=foobar;", "test=foobar");
+cookiesShouldBe("test2=foobar;", "test=foobar; test2=foobar");
+cookiesShouldBe("test3=foobar;", "test=foobar; test2=foobar; test3=foobar");
+clearCookies();
+
+successfullyParsed = true;
diff --git a/LayoutTests/http/tests/cookies/script-tests/simple-cookies-expired.js b/LayoutTests/http/tests/cookies/script-tests/simple-cookies-expired.js
new file mode 100644
index 0000000..61b70fb
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/script-tests/simple-cookies-expired.js
@@ -0,0 +1,18 @@
+description(
+"This test checks that cookies are correctly set using Expires."
+);
+
+clearAllCookies();
+
+debug("Check that setting a simple cookie works.");
+var date = new Date();
+date.setTime(date.getTime() + 60 * 1000);
+cookiesShouldBe("test=foobar; Expires=" + date.toGMTString(), "test=foobar");
+clearCookies();
+
+debug("Check setting a cookie that timed out.");
+date.setTime(date.getTime() - 2 * 60 * 1000);
+cookiesShouldBe("test2=foobar; Expires=" + date.toGMTString(), "");
+clearCookies();
+
+successfullyParsed = true;
diff --git a/LayoutTests/http/tests/cookies/script-tests/simple-cookies-max-age.js b/LayoutTests/http/tests/cookies/script-tests/simple-cookies-max-age.js
new file mode 100644
index 0000000..1d87b13
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/script-tests/simple-cookies-max-age.js
@@ -0,0 +1,15 @@
+description(
+"This test checks that cookies are correctly set using Max-Age."
+);
+
+clearAllCookies();
+
+debug("Check that setting a simple cookie works.");
+cookiesShouldBe("test=foobar; Max-Age=90000000", "test=foobar");
+clearCookies();
+
+debug("Check setting a cookie that timed out.");
+cookiesShouldBe("test2=foobar; Max-Age=0", "");
+clearCookies();
+
+successfullyParsed = true;
diff --git a/LayoutTests/http/tests/cookies/simple-cookies-expired-expected.txt b/LayoutTests/http/tests/cookies/simple-cookies-expired-expected.txt
new file mode 100644
index 0000000..d0a5c55
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/simple-cookies-expired-expected.txt
@@ -0,0 +1,13 @@
+This test checks that cookies are correctly set using Expires.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Check that setting a simple cookie works.
+PASS cookie is 'test=foobar'.
+Check setting a cookie that timed out.
+PASS cookie is ''.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/cookies/simple-cookies-expired.html b/LayoutTests/http/tests/cookies/simple-cookies-expired.html
new file mode 100644
index 0000000..6015d0d
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/simple-cookies-expired.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/cookies-test-style.css">
+<script src="resources/cookies-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/simple-cookies-expired.js"></script>
+<script src="resources/cookies-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/simple-cookies-max-age-expected.txt b/LayoutTests/http/tests/cookies/simple-cookies-max-age-expected.txt
new file mode 100644
index 0000000..859c392
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/simple-cookies-max-age-expected.txt
@@ -0,0 +1,13 @@
+This test checks that cookies are correctly set using Max-Age.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Check that setting a simple cookie works.
+PASS cookie is 'test=foobar'.
+Check setting a cookie that timed out.
+PASS cookie is ''.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/cookies/simple-cookies-max-age.html b/LayoutTests/http/tests/cookies/simple-cookies-max-age.html
new file mode 100644
index 0000000..23eee96
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/simple-cookies-max-age.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/cookies-test-style.css">
+<script src="resources/cookies-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/simple-cookies-max-age.js"></script>
+<script src="resources/cookies-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/cookies/third-party-cookie-relaxing-expected.txt b/LayoutTests/http/tests/cookies/third-party-cookie-relaxing-expected.txt
new file mode 100644
index 0000000..184a97a
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/third-party-cookie-relaxing-expected.txt
@@ -0,0 +1,47 @@
+ALERT:
+
+ALERT: Allowing all cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies
+ALERT: XHR response - Deleted all cookies
+ALERT: Test stage 1 document.cookie is:
+ALERT: Restricting to first party only cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=setFooCookie
+ALERT: XHR response - Set the foo cookie
+ALERT: Test stage 2 document.cookie is:
+ALERT:
+
+ALERT: Allowing all cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies
+ALERT: XHR response - Deleted all cookies
+ALERT: Test stage 3 document.cookie is:
+ALERT: Restricting to first party only cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=setFooAndBarCookie
+ALERT: XHR response - Set the foo and bar cookies
+ALERT: Test stage 4 document.cookie is:
+ALERT:
+
+ALERT: Allowing all cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies
+ALERT: XHR response - Deleted all cookies
+ALERT: Test stage 5 document.cookie is:
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=setFooCookie
+ALERT: XHR response - Set the foo cookie
+ALERT: Test stage 6 document.cookie is: foo=awesomevalue
+ALERT: Restricting to first party only cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies
+ALERT: XHR response - Deleted all cookies
+ALERT: Test stage 7 document.cookie is:
+ALERT:
+
+ALERT: Allowing all cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=deleteCookies
+ALERT: XHR response - Deleted all cookies
+ALERT: Test stage 8 document.cookie is:
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=setFooCookie
+ALERT: XHR response - Set the foo cookie
+ALERT: Test stage 9 document.cookie is: foo=awesomevalue
+ALERT: Restricting to first party only cookies
+ALERT: http://localhost:8000/cookies/resources/cookie-utility.php?queryfunction=setFooAndBarCookie
+ALERT: XHR response - Set the foo and bar cookies
+ALERT: Test stage 10 document.cookie is: bar=anotherawesomevalue; foo=awesomevalue
+
diff --git a/LayoutTests/http/tests/cookies/third-party-cookie-relaxing.html b/LayoutTests/http/tests/cookies/third-party-cookie-relaxing.html
new file mode 100644
index 0000000..df9c4b9
--- /dev/null
+++ b/LayoutTests/http/tests/cookies/third-party-cookie-relaxing.html
@@ -0,0 +1,96 @@
+<html>
+<head>
+<script src="resources/resetCookies.js"></script>
+<script>
+resetCookies();
+
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+window.onmessage = function(evt)
+{
+ if (evt.data != "done") {
+ alert("Unexpected message: " + evt.data);
+ return;
+ }
+
+ runNextTestOrFinish();
+}
+
+function allowAllCookies()
+{
+ alert("Allowing all cookies");
+ if (window.layoutTestController)
+ layoutTestController.setAlwaysAcceptCookies(true);
+ runNextTestOrFinish();
+}
+
+function restrictCookies()
+{
+ alert("Restricting to first party only cookies");
+ if (window.layoutTestController)
+ layoutTestController.setAlwaysAcceptCookies(false);
+ runNextTestOrFinish();
+}
+
+function deleteAllCookies()
+{
+ sendXHR("deleteCookies");
+}
+
+function echoCookies()
+{
+ window.frames[0].postMessage("showCookies", "*");
+}
+
+function sendXHR(command)
+{
+ window.frames[0].postMessage("sendXHR " + command, "*");
+}
+
+function setFooCookie()
+{
+ sendXHR("setFooCookie");
+}
+
+function setFooAndBarCookies()
+{
+ sendXHR("setFooAndBarCookie");
+}
+
+function startNewTest()
+{
+ alert("\n");
+ runNextTestOrFinish();
+}
+
+var currentFunction = 0;
+var functions = new Array(
+ startNewTest, allowAllCookies, deleteAllCookies, echoCookies, restrictCookies, setFooCookie, echoCookies,
+ startNewTest, allowAllCookies, deleteAllCookies, echoCookies, restrictCookies, setFooAndBarCookies, echoCookies,
+ startNewTest, allowAllCookies, deleteAllCookies, echoCookies, setFooCookie, echoCookies, restrictCookies, deleteAllCookies, echoCookies,
+ startNewTest, allowAllCookies, deleteAllCookies, echoCookies, setFooCookie, echoCookies, restrictCookies, setFooAndBarCookies, echoCookies
+);
+
+function runNextTestOrFinish()
+{
+ if (currentFunction >= functions.length) {
+ if (window.layoutTestController) {
+ resetCookies();
+ window.frames[0].postMessage("resetCookiesAndNotifyDone", "*");
+ }
+ return;
+ }
+
+ var functionToRun = currentFunction++;
+ functions[functionToRun]();
+}
+
+</script>
+</head>
+<body onload="runNextTestOrFinish();">
+<iframe id='testFrame' src="http://localhost:8000/cookies/resources/third-party-cookie-relaxing-iframe.html"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/platform/android/layout_test_directories.txt b/LayoutTests/platform/android/layout_test_directories.txt
index da81ffd..703c4da 100755
--- a/LayoutTests/platform/android/layout_test_directories.txt
+++ b/LayoutTests/platform/android/layout_test_directories.txt
@@ -36,6 +36,7 @@ fast/url
fast/xpath
http/conf
http/tests/appcache
+http/tests/cookies
http/tests/resources
http/tests/ssl
platform/android
diff --git a/LayoutTests/platform/android/test_expectations.txt b/LayoutTests/platform/android/test_expectations.txt
index 375a595..d0a039c 100644
--- a/LayoutTests/platform/android/test_expectations.txt
+++ b/LayoutTests/platform/android/test_expectations.txt
@@ -66,6 +66,7 @@ fast/events/touch/basic-multi-touch-events.html FAIL // Requires multi-touch ges
fast/events/touch/touch-coords-in-zoom-and-scroll.html FAIL // Requires eventSender.zoomPageIn(),zoomPageOut()
fast/events/touch/touch-target.html FAIL // Requires multi-touch gestures not supported by Android system
fast/workers FAIL // workers not supported
+http/tests/cookies/third-party-cookie-relaxing.html FAIL // We don't support conditional acceptance of third-party cookies
http/tests/eventsource/workers FAIL // workers not supported
http/tests/workers FAIL // workers not supported
http/tests/xmlhttprequest/workers FAIL // workers not supported
diff --git a/WebCore/bridge/jni/v8/JavaClassV8.cpp b/WebCore/bridge/jni/v8/JavaClassV8.cpp
index 04f8822..1d381af 100644
--- a/WebCore/bridge/jni/v8/JavaClassV8.cpp
+++ b/WebCore/bridge/jni/v8/JavaClassV8.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "JavaClassV8.h"
-
using namespace JSC::Bindings;
JavaClass::JavaClass(jobject anInstance)
@@ -38,11 +37,6 @@ JavaClass::JavaClass(jobject anInstance)
return;
}
- jstring className = static_cast<jstring>(callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;"));
- const char* classNameC = getCharactersFromJString(className);
- m_name = strdup(classNameC);
- releaseCharactersForJString(className, classNameC);
-
int i;
JNIEnv* env = getJNIEnv();
@@ -82,8 +76,6 @@ JavaClass::JavaClass(jobject anInstance)
JavaClass::~JavaClass()
{
- free(const_cast<char*>(m_name));
-
deleteAllValues(m_fields);
m_fields.clear();
diff --git a/WebCore/bridge/jni/v8/JavaClassV8.h b/WebCore/bridge/jni/v8/JavaClassV8.h
index 0c1d627..99137f1 100644
--- a/WebCore/bridge/jni/v8/JavaClassV8.h
+++ b/WebCore/bridge/jni/v8/JavaClassV8.h
@@ -49,7 +49,6 @@ public:
JavaField* fieldNamed(const char* name) const;
private:
- const char* m_name;
MethodListMap m_methods;
FieldMap m_fields;
};
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index be74487..9afde07 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -973,7 +973,7 @@ void Element::recalcStyle(StyleChange change)
if ((change > NoChange || needsStyleRecalc())) {
#ifdef ANDROID_STYLE_VERSION
- RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
+ RefPtr<RenderStyle> newStyle = document()->styleForElementIgnoringPendingStylesheets(this);
if (displayDiff(currentStyle.get(), newStyle.get()))
document()->incStyleVersion();
#endif
diff --git a/WebCore/platform/graphics/BitmapImage.cpp b/WebCore/platform/graphics/BitmapImage.cpp
index 2805b21..1148aa6 100644
--- a/WebCore/platform/graphics/BitmapImage.cpp
+++ b/WebCore/platform/graphics/BitmapImage.cpp
@@ -268,10 +268,6 @@ bool BitmapImage::shouldAnimate()
void BitmapImage::startAnimation(bool catchUpIfNecessary)
{
-#ifdef ANDROID_ANIMATED_GIF
- // We can't ever seem to keep up, so always let us just show the next frame
- catchUpIfNecessary = false;
-#endif
if (m_frameTimer || !shouldAnimate() || frameCount() <= 1)
return;
diff --git a/WebKit/Android.mk b/WebKit/Android.mk
index 844d8a5..e039421 100644
--- a/WebKit/Android.mk
+++ b/WebKit/Android.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
android/WebCoreSupport/GeolocationPermissions.cpp \
android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp \
android/WebCoreSupport/PlatformBridge.cpp \
+ android/WebCoreSupport/ResourceLoaderAndroid.cpp \
android/WebCoreSupport/UrlInterceptResponse.cpp \
android/WebCoreSupport/V8Counters.cpp
@@ -35,6 +36,7 @@ ifeq ($(HTTP_STACK),chrome)
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
android/WebCoreSupport/ChromiumLogging.cpp \
android/WebCoreSupport/WebCache.cpp \
+ android/WebCoreSupport/WebCookieJar.cpp \
android/WebCoreSupport/WebUrlLoader.cpp \
android/WebCoreSupport/WebUrlLoaderClient.cpp \
android/WebCoreSupport/WebRequest.cpp \
@@ -42,9 +44,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
android/WebCoreSupport/WebResourceRequest.cpp \
android/WebCoreSupport/WebResponse.cpp \
android/WebCoreSupport/WebViewClientError.cpp
-else
-LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
- android/WebCoreSupport/ResourceLoaderAndroid.cpp
endif # HTTP_STACK == chrome
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
index 1b249a4..cd5088b 100644
--- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp
+++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
@@ -34,6 +34,7 @@
#include "KeyGeneratorClient.h"
#include "PluginView.h"
#include "Settings.h"
+#include "WebCookieJar.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"
#include "npruntime.h"
@@ -72,7 +73,7 @@ void PlatformBridge::setCookies(const Document* document, const KURL& url, const
std::string cookieValue(value.utf8().data());
GURL cookieGurl(url.string().utf8().data());
bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
- WebRequestContext::get(isPrivateBrowsing)->cookie_store()->SetCookie(cookieGurl, cookieValue);
+ WebCookieJar::get(isPrivateBrowsing)->cookieStore()->SetCookie(cookieGurl, cookieValue);
#else
CookieClient* client = JavaSharedClient::GetCookieClient();
if (!client)
@@ -87,7 +88,7 @@ String PlatformBridge::cookies(const Document* document, const KURL& url)
#if USE(CHROME_NETWORK_STACK)
GURL cookieGurl(url.string().utf8().data());
bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
- std::string cookies = WebRequestContext::get(isPrivateBrowsing)->cookie_store()->GetCookies(cookieGurl);
+ std::string cookies = WebCookieJar::get(isPrivateBrowsing)->cookieStore()->GetCookies(cookieGurl);
String cookieString(cookies.c_str());
return cookieString;
#else
@@ -103,7 +104,7 @@ bool PlatformBridge::cookiesEnabled(const Document* document)
{
#if USE(CHROME_NETWORK_STACK)
bool isPrivateBrowsing = document->settings() && document->settings()->privateBrowsingEnabled();
- return WebRequestContext::get(isPrivateBrowsing)->allowCookies();
+ return WebCookieJar::get(isPrivateBrowsing)->allowCookies();
#else
CookieClient* client = JavaSharedClient::GetCookieClient();
if (!client)
@@ -160,11 +161,11 @@ FloatRect PlatformBridge::screenRect()
String PlatformBridge::computeDefaultLanguage()
{
#if USE(CHROME_NETWORK_STACK)
- std::string acceptLanguages = WebRequestContext::get(false)->GetAcceptLanguage();
+ String acceptLanguages = WebRequestContext::acceptLanguage();
size_t length = acceptLanguages.find(',');
if (length == std::string::npos)
length = acceptLanguages.length();
- return String::fromUTF8(acceptLanguages.c_str(), length);
+ return acceptLanguages.substring(0, length);
#else
return "en";
#endif
diff --git a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp b/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
index 8872a52..2b4a6fc 100644
--- a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
@@ -24,27 +24,45 @@
*/
#include <config.h>
-
#include <ResourceLoaderAndroid.h>
#include "FrameLoaderClientAndroid.h"
#include "WebCoreFrameBridge.h"
#include "WebCoreResourceLoader.h"
+#include "WebUrlLoader.h"
using namespace android;
namespace WebCore {
PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(
- ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync, bool /*isPrivateBrowsing*/)
+ ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync, bool isPrivateBrowsing)
{
+ // Called on main thread
+#if USE(CHROME_NETWORK_STACK)
+ // TODO: Implement sync requests
+ return WebUrlLoader::start(client, handle, request, isSync, isPrivateBrowsing);
+#else
FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*> (client);
return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync);
+#endif
}
bool ResourceLoaderAndroid::willLoadFromCache(const WebCore::KURL& url, int64_t identifier)
{
+#if USE(CHROME_NETWORK_STACK)
+ // This method is used to determine if a POST request can be repeated from
+ // cache, but you cannot really know until you actually try to read from the
+ // cache. Even if we checked now, something else could come along and wipe
+ // out the cache entry by the time we fetch it.
+ //
+ // So, we always say yes here, to prevent the FrameLoader from initiating a
+ // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
+ // fix-up the cache policy of the request to force a load from the cache.
+ return true;
+#else
return WebCoreResourceLoader::willLoadFromCache(url, identifier);
+#endif
}
}
diff --git a/WebKit/android/WebCoreSupport/WebCache.cpp b/WebKit/android/WebCoreSupport/WebCache.cpp
index b0ae915..9bc148c 100644
--- a/WebKit/android/WebCoreSupport/WebCache.cpp
+++ b/WebKit/android/WebCoreSupport/WebCache.cpp
@@ -23,37 +23,95 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
#include "WebCache.h"
+
+#include "JNIUtility.h"
+#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebUrlLoaderClient.h"
+using namespace WTF;
using namespace net;
namespace android {
-WebCache* WebCache::s_instance = 0;
+static const std::string& rootDirectory()
+{
+ // This method may be called on any thread, as the Java method is
+ // synchronized.
+ static WTF::Mutex mutex;
+ MutexLocker lock(mutex);
+ static std::string cacheDirectory;
+ if (cacheDirectory.empty()) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
+ jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;");
+ cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
+ env->DeleteLocalRef(bridgeClass);
+ }
+ return cacheDirectory;
+}
-void WebCache::clear()
+WebCache* WebCache::get(bool isPrivateBrowsing)
{
- base::Thread* thread = WebUrlLoaderClient::ioThread();
- if (thread)
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(getInstance(), &WebCache::doClear));
+ static const char* const kDirectory = "/webviewCacheChromium";
+ static const char* const kDirectoryPrivate = "/webviewCacheChromiumPrivate";
+
+ static WebCache* regularCache = 0;
+ static WebCache* privateCache = 0;
+
+ if (isPrivateBrowsing) {
+ if (!privateCache) {
+ std::string storageDirectory = rootDirectory();
+ storageDirectory.append(kDirectoryPrivate);
+ privateCache = new WebCache(storageDirectory);
+ }
+ return privateCache;
+ }
+
+ if (!regularCache) {
+ std::string storageDirectory = rootDirectory();
+ storageDirectory.append(kDirectory);
+ regularCache = new WebCache(storageDirectory);
+ }
+ return regularCache;
}
-WebCache::WebCache()
- : m_doomAllEntriesCallback(this, &WebCache::doomAllEntries)
- , m_doneCallback(this, &WebCache::done)
+WebCache::WebCache(const std::string& storageDirectory)
+ : m_storageDirectory(storageDirectory)
+ , m_doomAllEntriesCallback(this, &WebCache::doomAllEntries)
+ , m_doneCallback(this, &WebCache::onClearDone)
, m_isClearInProgress(false)
{
+ base::Thread* ioThread = WebUrlLoaderClient::ioThread();
+ scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();
+
+ static const int kMaximumCacheSizeBytes = 20 * 1024 * 1024;
+ FilePath directoryPath(m_storageDirectory.c_str());
+ net::HttpCache::DefaultBackend* backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy);
+
+ m_hostResolver = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0);
+ m_cache = new net::HttpCache(m_hostResolver.get(),
+ 0, // dnsrr_resolver
+ net::ProxyService::CreateDirect(),
+ net::SSLConfigService::CreateSystemSSLConfigService(),
+ net::HttpAuthHandlerFactory::CreateDefault(m_hostResolver.get()),
+ 0, // network_delegate
+ 0, // net_log
+ backendFactory);
}
-WebCache* WebCache::getInstance()
+void WebCache::clear()
{
- if (!s_instance) {
- s_instance = new WebCache();
- s_instance->AddRef();
- }
- return s_instance;
+ base::Thread* thread = WebUrlLoaderClient::ioThread();
+ if (thread)
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::doClear));
+}
+
+void WebCache::cleanupFiles()
+{
+ WebRequestContext::removeFileOrDirectory(m_storageDirectory.c_str());
}
void WebCache::doClear()
@@ -61,9 +119,8 @@ void WebCache::doClear()
if (m_isClearInProgress)
return;
m_isClearInProgress = true;
- URLRequestContext* context = WebRequestContext::get(false /* isPrivateBrowsing */);
- HttpTransactionFactory* factory = context->http_transaction_factory();
- int code = factory->GetCache()->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback);
+
+ int code = m_cache->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback);
// Code ERR_IO_PENDING indicates that the operation is still in progress and
// the supplied callback will be invoked when it completes.
if (code == ERR_IO_PENDING)
@@ -91,10 +148,10 @@ void WebCache::doomAllEntries(int)
m_isClearInProgress = false;
return;
}
- done(0 /*unused*/);
+ onClearDone(0 /*unused*/);
}
-void WebCache::done(int)
+void WebCache::onClearDone(int)
{
m_isClearInProgress = false;
}
diff --git a/WebKit/android/WebCoreSupport/WebCache.h b/WebKit/android/WebCoreSupport/WebCache.h
index 9fd980f..4aa67c0 100644
--- a/WebKit/android/WebCoreSupport/WebCache.h
+++ b/WebKit/android/WebCoreSupport/WebCache.h
@@ -28,21 +28,35 @@
#include "ChromiumIncludes.h"
+#include <OwnPtr.h>
+#include <wtf/ThreadingPrimitives.h>
+
namespace android {
+// This class is not generally threadsafe. get() is not threadsafe - instances
+// are created on the WebCore thread only.
class WebCache : public base::RefCountedThreadSafe<WebCache> {
public:
- static void clear();
+ static WebCache* get(bool isPrivateBrowsing);
+
+ void clear();
+ void cleanupFiles();
+ net::HostResolver* hostResolver() { return m_hostResolver.get(); }
+ net::HttpCache* cache() { return m_cache.get(); }
private:
- WebCache();
- static WebCache* getInstance();
+ WebCache(const std::string& storageDirectory);
+ // For clear()
void doClear();
void doomAllEntries(int);
- void done(int);
+ void onClearDone(int);
+
+ std::string m_storageDirectory;
+ OwnPtr<net::HostResolver> m_hostResolver;
+ OwnPtr<net::HttpCache> m_cache;
- static WebCache* s_instance;
+ // For clear()
net::CompletionCallbackImpl<WebCache> m_doomAllEntriesCallback;
net::CompletionCallbackImpl<WebCache> m_doneCallback;
disk_cache::Backend* m_cacheBackend;
diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.cpp b/WebKit/android/WebCoreSupport/WebCookieJar.cpp
new file mode 100644
index 0000000..91a565c
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/WebCookieJar.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebCookieJar.h"
+
+#include "JNIUtility.h"
+#include "WebCoreJni.h"
+#include "WebRequestContext.h"
+
+namespace android {
+
+const std::string& databaseDirectory()
+{
+ // This method may be called on any thread, as the Java method is
+ // synchronized.
+ static WTF::Mutex databaseDirectoryMutex;
+ MutexLocker lock(databaseDirectoryMutex);
+ static std::string databaseDirectory;
+ if (databaseDirectory.empty()) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
+ jmethodID method = env->GetStaticMethodID(bridgeClass, "getDatabaseDirectory", "()Ljava/lang/String;");
+ databaseDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
+ env->DeleteLocalRef(bridgeClass);
+ }
+ return databaseDirectory;
+}
+
+
+WebCookieJar* WebCookieJar::get(bool isPrivateBrowsing)
+{
+ static const char* const kDatabaseFilename = "/webviewCookiesChromium.db";
+ static const char* const kDatabaseFilenamePrivateBrowsing = "/webviewCookiesChromiumPrivate.db";
+
+ static WebCookieJar* regularCookieManager = 0;
+ static WebCookieJar* privateCookieManager = 0;
+
+ WTF::Mutex instanceMutex;
+ MutexLocker lock(instanceMutex);
+
+ if (isPrivateBrowsing) {
+ if (!privateCookieManager) {
+ std::string databaseFilePath = databaseDirectory();
+ databaseFilePath.append(kDatabaseFilenamePrivateBrowsing);
+ privateCookieManager = new WebCookieJar(databaseFilePath);
+ }
+ return privateCookieManager;
+ }
+
+ if (!regularCookieManager) {
+ std::string databaseFilePath = databaseDirectory();
+ databaseFilePath.append(kDatabaseFilename);
+ regularCookieManager = new WebCookieJar(databaseFilePath);
+ }
+ return regularCookieManager;
+}
+
+WebCookieJar::WebCookieJar(const std::string& databaseFilePath)
+ : m_allowCookies(true)
+ , m_databaseFilePath(databaseFilePath)
+{
+ // This is needed for the page cycler. See http://b/2944150
+ net::CookieMonster::EnableFileScheme();
+
+ FilePath cookiePath(m_databaseFilePath.c_str());
+ scoped_refptr<SQLitePersistentCookieStore> cookieDb = new SQLitePersistentCookieStore(cookiePath);
+ m_cookieStore = new net::CookieMonster(cookieDb.get(), 0);
+}
+
+bool WebCookieJar::allowCookies()
+{
+ MutexLocker lock(m_allowCookiesMutex);
+ return m_allowCookies;
+}
+
+void WebCookieJar::setAllowCookies(bool allow)
+{
+ MutexLocker lock(m_allowCookiesMutex);
+ m_allowCookies = allow;
+}
+
+void WebCookieJar::cleanupFiles()
+{
+ WebRequestContext::removeFileOrDirectory(m_databaseFilePath.c_str());
+}
+
+// From CookiePolicy in chromium
+int WebCookieJar::CanGetCookies(const GURL&, const GURL&, net::CompletionCallback*)
+{
+ MutexLocker lock(m_allowCookiesMutex);
+ return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
+}
+
+// From CookiePolicy in chromium
+int WebCookieJar::CanSetCookie(const GURL&, const GURL&, const std::string&, net::CompletionCallback*)
+{
+ MutexLocker lock(m_allowCookiesMutex);
+ return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
+}
+
+}
diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.h b/WebKit/android/WebCoreSupport/WebCookieJar.h
new file mode 100644
index 0000000..e3bfe02
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/WebCookieJar.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebCookieJar_h
+#define WebCookieJar_h
+
+#include "ChromiumIncludes.h"
+
+#include <wtf/ThreadingPrimitives.h>
+
+namespace android {
+
+// This class is threadsafe. It is used from the IO, WebCore and Chromium IO
+// threads.
+class WebCookieJar : public net::CookiePolicy {
+public:
+ static WebCookieJar* get(bool isPrivateBrowsing);
+
+ // CookiePolicy implementation from external/chromium
+ virtual int CanGetCookies(const GURL& url, const GURL& first_party_for_cookies, net::CompletionCallback*);
+ virtual int CanSetCookie(const GURL& url, const GURL& first_party_for_cookies, const std::string& cookie_line, net::CompletionCallback*);
+
+ bool allowCookies();
+ void setAllowCookies(bool allow);
+ void cleanupFiles();
+
+ // Instead of this it would probably be better to add the cookie methods
+ // here so the rest of WebKit doesn't have to know about Chromium classes
+ net::CookieStore* cookieStore() { return m_cookieStore.get(); }
+ net::CookiePolicy* cookiePolicy() { return this; }
+
+private:
+ WebCookieJar(const std::string& databaseFilePath);
+
+ scoped_refptr<net::CookieStore> m_cookieStore;
+ bool m_allowCookies;
+ WTF::Mutex m_allowCookiesMutex;
+ std::string m_databaseFilePath;
+};
+
+}
+
+#endif
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index 67144cb..366c3c9 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -51,7 +51,6 @@ extern android::AssetManager* globalAssetManager();
#define ASSERT(assertion, ...) do \
if (!(assertion)) { \
android_printLog(ANDROID_LOG_ERROR, __FILE__, __VA_ARGS__); \
- CRASH(); \
} \
while (0)
@@ -67,6 +66,7 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& web
, m_url(webResourceRequest.url())
, m_userAgent(webResourceRequest.userAgent())
, m_loadState(Created)
+ , m_authRequestCount(0)
{
GURL gurl(m_url);
@@ -87,6 +87,7 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& web
, m_url(webResourceRequest.url())
, m_userAgent(webResourceRequest.userAgent())
, m_loadState(Created)
+ , m_authRequestCount(0)
{
}
@@ -311,8 +312,11 @@ void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* aut
ASSERT(m_loadState == Started, "OnAuthRequired called on a WebRequest not in STARTED state (state=%d)", m_loadState);
scoped_refptr<net::AuthChallengeInfo> authInfoPtr(authInfo);
+ bool firstTime = (m_authRequestCount == 0);
+ ++m_authRequestCount;
+
m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
- m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr));
+ m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr, firstTime));
}
// After calling Start(), the delegate will receive an OnResponseStarted
diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h
index 2bcbb92..98e2921 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -101,6 +101,7 @@ private:
std::string m_url;
std::string m_userAgent;
LoadState m_loadState;
+ int m_authRequestCount;
};
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.cpp b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
index 1a82449..eed8863 100644
--- a/WebKit/android/WebCoreSupport/WebRequestContext.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
@@ -28,44 +28,31 @@
#include "ChromiumIncludes.h"
#include "ChromiumLogging.h"
-#include "JNIUtility.h"
-#include "WebCoreJni.h"
-#include "WebUrlLoaderClient.h"
-#include "jni.h"
+#include "WebCache.h"
+#include "WebCookieJar.h"
#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
#include <wtf/text/CString.h>
namespace {
// TODO: The userAgent should not be a static, as it can be set per WebView.
// http://b/3113804
std::string userAgent("");
-std::string acceptLanguage("");
-
Lock userAgentLock;
-Lock acceptLanguageLock;
-WTF::Mutex databaseDirectoryMutex;
-WTF::Mutex cacheDirectoryMutex;
+std::string acceptLanguageStdString("");
+WTF::String acceptLanguageWtfString("");
+WTF::Mutex acceptLanguageMutex;
}
using namespace WTF;
namespace android {
-static const char* const kCookiesDatabaseFilename = "/webviewCookiesChromium.db";
-static const char* const kCacheDirectory = "/webviewCacheChromium";
-static const char* const kCookiesDatabaseFilenamePrivate = "/webviewCookiesChromiumPrivate.db";
-static const char* const kCacheDirectoryPrivate = "/webviewCacheChromiumPrivate";
-
static scoped_refptr<WebRequestContext> privateBrowsingContext(0);
static WTF::Mutex privateBrowsingContextMutex;
WebRequestContext::WebRequestContext()
- : m_allowCookies(true)
{
// Also hardcoded in FrameLoader.java
accept_charset_ = "utf-8, iso-8859-1, utf-16, *;q=0.7";
@@ -92,91 +79,45 @@ const std::string& WebRequestContext::GetUserAgent(const GURL& url) const
return userAgent;
}
-void WebRequestContext::setAcceptLanguage(String string)
+void WebRequestContext::setAcceptLanguage(const String& string)
{
- // The accept language is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(acceptLanguageLock);
- acceptLanguage = string.utf8().data();
+ MutexLocker lock(acceptLanguageMutex);
+ acceptLanguageStdString = string.utf8().data();
+ acceptLanguageWtfString = string;
}
const std::string& WebRequestContext::GetAcceptLanguage() const
{
- // The accept language is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(acceptLanguageLock);
- return acceptLanguage;
+ MutexLocker lock(acceptLanguageMutex);
+ return acceptLanguageStdString;
}
-static const std::string& getDatabaseDirectory()
+const String& WebRequestContext::acceptLanguage()
{
- // This method may be called on any thread, as the Java method is
- // synchronized.
- MutexLocker lock(databaseDirectoryMutex);
- static std::string databaseDirectory;
- if (databaseDirectory.empty()) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
- jmethodID method = env->GetStaticMethodID(bridgeClass, "getDatabaseDirectory", "()Ljava/lang/String;");
- databaseDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
- env->DeleteLocalRef(bridgeClass);
- }
- return databaseDirectory;
+ MutexLocker lock(acceptLanguageMutex);
+ return acceptLanguageWtfString;
}
-static const std::string& getCacheDirectory()
+WebRequestContext* WebRequestContext::getImpl(bool isPrivateBrowsing)
{
- // This method may be called on any thread, as the Java method is
- // synchronized.
- MutexLocker lock(cacheDirectoryMutex);
- static std::string cacheDirectory;
- if (cacheDirectory.empty()) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
- jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;");
- cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
- env->DeleteLocalRef(bridgeClass);
- }
- return cacheDirectory;
-}
-
-WebRequestContext* WebRequestContext::getContextForPath(const char* cookieFilename, const char* cacheFilename)
-{
- std::string cookieString(getDatabaseDirectory());
- cookieString.append(cookieFilename);
- FilePath cookiePath(cookieString.c_str());
- std::string cacheString(getCacheDirectory());
- cacheString.append(cacheFilename);
- FilePath cachePath(cacheString.c_str());
-
WebRequestContext* context = new WebRequestContext();
- context->host_resolver_ = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0);
- base::Thread* ioThread = WebUrlLoaderClient::ioThread();
- scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();
- // Todo: check if the context takes ownership of the cache
- net::HttpCache::DefaultBackend* defaultBackend = new net::HttpCache::DefaultBackend(net::DISK_CACHE, cachePath, 20 * 1024 * 1024, cacheMessageLoopProxy);
- context->http_transaction_factory_ = new net::HttpCache(context->host_resolver(), context->dnsrr_resolver(), net::ProxyService::CreateDirect(), net::SSLConfigService::CreateSystemSSLConfigService(), net::HttpAuthHandlerFactory::CreateDefault(context->host_resolver_), 0, 0, defaultBackend);
+ WebCache* cache = WebCache::get(isPrivateBrowsing);
+ context->host_resolver_ = cache->hostResolver();
+ context->http_transaction_factory_ = cache->cache();
- scoped_refptr<SQLitePersistentCookieStore> cookieDb = new SQLitePersistentCookieStore(cookiePath);
-
- // This is needed for the page cycler. See http://b/2944150
- net::CookieMonster::EnableFileScheme();
-
- context->cookie_store_ = new net::CookieMonster(cookieDb.get(), 0);
- context->cookie_policy_ = context;
+ WebCookieJar* cookieJar = WebCookieJar::get(isPrivateBrowsing);
+ context->cookie_store_ = cookieJar->cookieStore();
+ context->cookie_policy_ = cookieJar;
return context;
}
WebRequestContext* WebRequestContext::getRegularContext()
{
- static WTF::Mutex regularContextMutex;
static scoped_refptr<WebRequestContext> regularContext(0);
-
- MutexLocker lock(regularContextMutex);
if (!regularContext)
- regularContext = getContextForPath(kCookiesDatabaseFilename, kCacheDirectory);
+ regularContext = getImpl(false);
return regularContext;
}
@@ -184,11 +125,10 @@ WebRequestContext* WebRequestContext::getPrivateBrowsingContext()
{
MutexLocker lock(privateBrowsingContextMutex);
- if (!privateBrowsingContext) {
- // TODO: Where is the right place to put the temporary db? Should it be
- // kept in memory?
- privateBrowsingContext = getContextForPath(kCookiesDatabaseFilenamePrivate, kCacheDirectoryPrivate);
- }
+ // TODO: Where is the right place to put the temporary db? Should it be
+ // kept in memory?
+ if (!privateBrowsingContext)
+ privateBrowsingContext = getImpl(true);
return privateBrowsingContext;
}
@@ -200,7 +140,7 @@ WebRequestContext* WebRequestContext::get(bool isPrivateBrowsing)
return isPrivateBrowsing ? getPrivateBrowsingContext() : getRegularContext();
}
-static void removeFileOrDirectory(const char* filename)
+void WebRequestContext::removeFileOrDirectory(const char* filename)
{
struct stat filetype;
if (stat(filename, &filetype) != 0)
@@ -224,7 +164,7 @@ static void removeFileOrDirectory(const char* filename)
unlink(filename);
}
-bool WebRequestContext::cleanupPrivateBrowsingFiles(const std::string& databaseDirectory, const std::string& cacheDirectory)
+bool WebRequestContext::cleanupPrivateBrowsingFiles()
{
// This is called on the UI thread.
MutexLocker lock(privateBrowsingContextMutex);
@@ -232,38 +172,11 @@ bool WebRequestContext::cleanupPrivateBrowsingFiles(const std::string& databaseD
if (!privateBrowsingContext || privateBrowsingContext->HasOneRef()) {
privateBrowsingContext = 0;
- std::string cookiePath(databaseDirectory);
- cookiePath.append(kCookiesDatabaseFilenamePrivate);
- removeFileOrDirectory(cookiePath.c_str());
- std::string cachePath(cacheDirectory);
- cachePath.append(kCacheDirectoryPrivate);
- removeFileOrDirectory(cachePath.c_str());
+ WebCookieJar::get(true)->cleanupFiles();
+ WebCache::get(true)->cleanupFiles();
return true;
}
return false;
}
-int WebRequestContext::CanGetCookies(const GURL&, const GURL&, net::CompletionCallback*)
-{
- MutexLocker lock(m_allowCookiesMutex);
- return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
-}
-
-int WebRequestContext::CanSetCookie(const GURL&, const GURL&, const std::string&, net::CompletionCallback*)
-{
- MutexLocker lock(m_allowCookiesMutex);
- return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
-}
-
-bool WebRequestContext::allowCookies() {
- MutexLocker lock(m_allowCookiesMutex);
- return m_allowCookies;
-}
-
-void WebRequestContext::setAllowCookies(bool allow)
-{
- MutexLocker lock(m_allowCookiesMutex);
- m_allowCookies = allow;
-}
-
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.h b/WebKit/android/WebCoreSupport/WebRequestContext.h
index f4a579c..ec1561b 100644
--- a/WebKit/android/WebCoreSupport/WebRequestContext.h
+++ b/WebKit/android/WebCoreSupport/WebRequestContext.h
@@ -33,39 +33,36 @@
namespace android {
-class WebRequestContext : public URLRequestContext, net::CookiePolicy {
+// This class is generally not threadsafe. .get() is not threadsafe - instances
+// are created on the WebCore thread only.
+class WebRequestContext : public URLRequestContext {
public:
// URLRequestContext overrides.
virtual const std::string& GetUserAgent(const GURL&) const;
virtual const std::string& GetAcceptLanguage() const;
- // CookiePolicy implementation.
- virtual int CanGetCookies(const GURL& url, const GURL& first_party_for_cookies, net::CompletionCallback*);
- virtual int CanSetCookie(const GURL& url, const GURL& first_party_for_cookies, const std::string& cookie_line, net::CompletionCallback*);
-
// Lazily create the relevant context. This class holds a reference.
- // This may be called on any thread. The context returned, however, is not
- // threadsafe, and should only be used on a single thread (the network stack
- // IO thread), with the exception of the methods below.
static WebRequestContext* get(bool isPrivateBrowsing);
// These methods are threadsafe.
- static bool cleanupPrivateBrowsingFiles(const std::string& databaseDirectory, const std::string& cacheDirectory);
+ static bool cleanupPrivateBrowsingFiles();
static void setUserAgent(WTF::String);
- static void setAcceptLanguage(WTF::String);
- bool allowCookies();
- void setAllowCookies(bool allow);
+ static void setAcceptLanguage(const WTF::String&);
+ static const WTF::String& acceptLanguage();
+
+ // A helper function used by the cache and cookie managers. Should probably
+ // find a better home, but wait for the refactoring in b/3113804 to be
+ // completed.
+ static void removeFileOrDirectory(const char* filename);
private:
WebRequestContext();
~WebRequestContext();
- static WebRequestContext* getContextForPath(const char* cookieFilename, const char* cacheFilename);
+ static WebRequestContext* getImpl(bool isPrivateBrowsing);
static WebRequestContext* getRegularContext();
static WebRequestContext* getPrivateBrowsingContext();
- bool m_allowCookies;
- WTF::Mutex m_allowCookiesMutex;
};
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp
index c3ec562..9b70fce 100644
--- a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp
@@ -36,10 +36,37 @@ namespace android {
WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceRequest)
{
+ // Set the load flags based on the WebCore request.
+ m_loadFlags = net::LOAD_NORMAL;
+ switch (resourceRequest.cachePolicy()) {
+ case ReloadIgnoringCacheData:
+ m_loadFlags |= net::LOAD_VALIDATE_CACHE;
+ break;
+ case ReturnCacheDataElseLoad:
+ m_loadFlags |= net::LOAD_PREFERRING_CACHE;
+ break;
+ case ReturnCacheDataDontLoad:
+ m_loadFlags |= net::LOAD_ONLY_FROM_CACHE;
+ break;
+ case UseProtocolCachePolicy:
+ break;
+ }
+
+ // TODO: We should consider setting these flags and net::LOAD_DO_NOT_SEND_AUTH_DATA
+ // when FrameLoaderClient::shouldUseCredentialStorage() is false. However,
+ // the required WebKit logic is not yet in place. See Chromium's
+ // FrameLoaderClientImpl::shouldUseCredentialStorage().
+ if (!resourceRequest.allowCookies()) {
+ m_loadFlags |= net::LOAD_DO_NOT_SAVE_COOKIES;
+ m_loadFlags |= net::LOAD_DO_NOT_SEND_COOKIES;
+ }
+
+
// Set the request headers
const HTTPHeaderMap& map = resourceRequest.httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it) {
const std::string& nameUtf8 = it->first.string().utf8().data();
+ const std::string& valueUtf8 = it->second.utf8().data();
// Skip over referrer headers found in the header map because we already
// pulled it out as a separate parameter. We likewise prune the UA since
@@ -47,17 +74,13 @@ WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceR
if (LowerCaseEqualsASCII(nameUtf8, "referer") || LowerCaseEqualsASCII(nameUtf8, "user-agent"))
continue;
- // The next comment does not match what is happening in code since the load flags are not implemented
- // (http://b/issue?id=2889880)
- // TODO: Check this is correct when load flags are implemented and working.
-
// Skip over "Cache-Control: max-age=0" header if the corresponding
// load flag is already specified. FrameLoader sets both the flag and
// the extra header -- the extra header is redundant since our network
// implementation will add the necessary headers based on load flags.
// See http://code.google.com/p/chromium/issues/detail?id=3434.
- const std::string& valueUtf8 = it->second.utf8().data();
- if (LowerCaseEqualsASCII(nameUtf8, "cache-control") && LowerCaseEqualsASCII(valueUtf8, "max-age=0"))
+ if ((m_loadFlags & net::LOAD_VALIDATE_CACHE) &&
+ LowerCaseEqualsASCII(nameUtf8, "cache-control") && LowerCaseEqualsASCII(valueUtf8, "max-age=0"))
continue;
m_requestHeaders.SetHeader(nameUtf8, valueUtf8);
@@ -68,21 +91,6 @@ WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceR
m_userAgent = resourceRequest.httpUserAgent().utf8().data();
m_url = resourceRequest.url().string().utf8().data();
-
- m_loadFlags = net::LOAD_NORMAL;
- switch (resourceRequest.cachePolicy()) {
- case ReloadIgnoringCacheData:
- m_loadFlags |= net::LOAD_VALIDATE_CACHE;
- break;
- case ReturnCacheDataElseLoad:
- m_loadFlags |= net::LOAD_PREFERRING_CACHE;
- break;
- case ReturnCacheDataDontLoad:
- m_loadFlags |= net::LOAD_ONLY_FROM_CACHE;
- break;
- case UseProtocolCachePolicy:
- break;
- }
}
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
index 170e78f..8c943a0 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
@@ -80,31 +80,3 @@ void WebUrlLoader::downloadFile()
}
} // namespace android
-
-
-namespace WebCore {
-// on main thread
-// static
-// TODO: Implement sync requests
-PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest,
- FrameLoaderClient* client, bool /*isMainResource*/, bool isSync, bool isPrivateBrowsing)
-{
- return android::WebUrlLoader::start(client, resourceHandle, resourceRequest, isSync, isPrivateBrowsing);
-}
-
-// static
-bool ResourceLoaderAndroid::willLoadFromCache(const WebCore::KURL&, int64_t identifier)
-{
- // This method is used to determine if a POST request can be repeated from
- // cache, but you cannot really know until you actually try to read from the
- // cache. Even if we checked now, something else could come along and wipe
- // out the cache entry by the time we fetch it.
- //
- // So, we always say yes here, to prevent the FrameLoader from initiating a
- // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
- // fix-up the cache policy of the request to force a load from the cache.
- //
- return true;
-}
-
-} // namespace WebCore
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index 7487e48..d7df279 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -337,7 +337,7 @@ void WebUrlLoaderClient::didFinishLoading()
finish();
}
-void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> authChallengeInfo)
+void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> authChallengeInfo, bool firstTime)
{
if (!isActive()) {
return;
@@ -346,13 +346,7 @@ void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> auth
std::string host = base::SysWideToUTF8(authChallengeInfo->host_and_port);
std::string realm = base::SysWideToUTF8(authChallengeInfo->realm);
- // TODO: Not clear whose responsibility it is to cache credentials. There's nothing
- // in AuthChallengeInfo that seems suitable, so for safety we'll tell the UI *not*
- // to use cached credentials. We may need to track this ourselves (pass "true" on
- // the first call, then "false" for a second call if the credentials are rejected).
- bool useCachedCredentials = false;
-
- m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, useCachedCredentials);
+ m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, firstTime);
}
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index 5f2c528..56d4289 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -86,7 +86,7 @@ public:
void didFinishLoading();
void didFail(PassOwnPtr<WebResponse>);
void willSendRequest(PassOwnPtr<WebResponse>);
- void authRequired(scoped_refptr<net::AuthChallengeInfo>);
+ void authRequired(scoped_refptr<net::AuthChallengeInfo>, bool firstTime);
// Handle to the chrome IO thread
static base::Thread* ioThread();
diff --git a/WebKit/android/jni/CookieManager.cpp b/WebKit/android/jni/CookieManager.cpp
index b38cc3a..821d28d 100644
--- a/WebKit/android/jni/CookieManager.cpp
+++ b/WebKit/android/jni/CookieManager.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "ChromiumIncludes.h"
+#include "WebCookieJar.h"
#include "WebRequestContext.h"
#include "WebCoreJni.h"
#include <JNIHelp.h>
@@ -38,16 +39,7 @@ namespace android {
// JNI for android.webkit.CookieManager
static const char* javaCookieManagerClass = "android/webkit/CookieManager";
-// Though WebRequestContext::get() is threadsafe, the context itself, in
-// general, is not. The context is generally used on the HTTP stack IO
-// thread, but calls to the methods of this class are made on the UI thread.
-// We ensure thread safety as follows ...
-// - The cookie_store() getter just returns a pointer which is only set when the
-// context is first constructed. The CookieMonster itself is threadsafe, so
-// using it from the UI thread is safe.
-// - Calls to the other WebRequestContext methods used here are explicitly
-// threadsafe.
-
+// WebCookieJar is threadsafe, as is CookieMonster.
static bool useChromiumHttpStack(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
@@ -63,8 +55,8 @@ static bool acceptCookie(JNIEnv*, jobject)
// This is a static method which gets the cookie policy for all WebViews. We
// always apply the same configuration to the contexts for both regular and
// private browsing, so expect the same result here.
- bool regularAcceptCookies = WebRequestContext::get(false)->allowCookies();
- ASSERT(regularAcceptCookies == WebRequestContext::get(true)->allowCookies());
+ bool regularAcceptCookies = WebCookieJar::get(false)->allowCookies();
+ ASSERT(regularAcceptCookies == WebCookieJar::get(true)->allowCookies());
return regularAcceptCookies;
#else
// The Android HTTP stack is implemented Java-side.
@@ -79,7 +71,7 @@ static jstring getCookie(JNIEnv* env, jobject, jstring url)
GURL gurl(jstringToStdString(env, url));
CookieOptions options;
options.set_include_httponly();
- std::string cookies = WebRequestContext::get(false)->cookie_store()->GetCookieMonster()->GetCookiesWithOptions(gurl, options);
+ std::string cookies = WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetCookiesWithOptions(gurl, options);
return cookies.empty() ? 0 : env->NewStringUTF(cookies.c_str());
#else
// The Android HTTP stack is implemented Java-side.
@@ -91,7 +83,7 @@ static jstring getCookie(JNIEnv* env, jobject, jstring url)
static bool hasCookies(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
- return !WebRequestContext::get(false)->cookie_store()->GetCookieMonster()->GetAllCookies().empty();
+ return !WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetAllCookies().empty();
#else
// The Android HTTP stack is implemented Java-side.
ASSERT_NOT_REACHED();
@@ -102,13 +94,13 @@ static bool hasCookies(JNIEnv*, jobject)
static void removeAllCookie(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
- WebRequestContext::get(false)->cookie_store()->GetCookieMonster()->DeleteAllCreatedAfter(Time(), true);
+ WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->DeleteAllCreatedAfter(Time(), true);
// This will lazily create a new private browsing context. However, if the
// context doesn't already exist, there's no need to create it, as cookies
// for such contexts are cleared up when we're done with them.
// TODO: Consider adding an optimisation to not create the context if it
// doesn't already exist.
- WebRequestContext::get(true)->cookie_store()->GetCookieMonster()->DeleteAllCreatedAfter(Time(), true);
+ WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->DeleteAllCreatedAfter(Time(), true);
#endif
}
@@ -116,18 +108,18 @@ static void removeExpiredCookie(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
// This simply forces a GC. The getters delete expired cookies so won't return expired cookies anyway.
- WebRequestContext::get(false)->cookie_store()->GetCookieMonster()->GetAllCookies();
- WebRequestContext::get(true)->cookie_store()->GetCookieMonster()->GetAllCookies();
+ WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetAllCookies();
+ WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->GetAllCookies();
#endif
}
-static void removeSessionCookies(WebRequestContext* context)
+static void removeSessionCookies(WebCookieJar* cookieJar)
{
#if USE(CHROME_NETWORK_STACK)
- CookieMonster* cookieMonster = context->cookie_store()->GetCookieMonster();
+ CookieMonster* cookieMonster = cookieJar->cookieStore()->GetCookieMonster();
CookieMonster::CookieList cookies = cookieMonster->GetAllCookies();
for (CookieMonster::CookieList::const_iterator iter = cookies.begin(); iter != cookies.end(); ++iter) {
- if (!iter->IsPersistent())
+ if (iter->IsSessionCookie())
cookieMonster->DeleteCanonicalCookie(*iter);
}
#endif
@@ -136,8 +128,8 @@ static void removeSessionCookies(WebRequestContext* context)
static void removeSessionCookie(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
- removeSessionCookies(WebRequestContext::get(false));
- removeSessionCookies(WebRequestContext::get(true));
+ removeSessionCookies(WebCookieJar::get(false));
+ removeSessionCookies(WebCookieJar::get(true));
#endif
}
@@ -147,8 +139,8 @@ static void setAcceptCookie(JNIEnv*, jobject, jboolean accept)
// This is a static method which configures the cookie policy for all
// WebViews, so we configure the contexts for both regular and private
// browsing.
- WebRequestContext::get(false)->setAllowCookies(accept);
- WebRequestContext::get(true)->setAllowCookies(accept);
+ WebCookieJar::get(false)->setAllowCookies(accept);
+ WebCookieJar::get(true)->setAllowCookies(accept);
#endif
}
@@ -159,7 +151,7 @@ static void setCookie(JNIEnv* env, jobject, jstring url, jstring value)
std::string line(jstringToStdString(env, value));
CookieOptions options;
options.set_include_httponly();
- WebRequestContext::get(false)->cookie_store()->GetCookieMonster()->SetCookieWithOptions(gurl, line, options);
+ WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->SetCookieWithOptions(gurl, line, options);
#endif
}
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 4212aa2..b9b4b75 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -1666,7 +1666,7 @@ static void ClearWebCoreCache()
static void ClearWebViewCache()
{
#if USE(CHROME_NETWORK_STACK)
- WebCache::clear();
+ WebCache::get(false /*privateBrowsing*/)->clear();
#else
// The Android network stack provides a WebView cache in CacheManager.java.
// Clearing this is handled entirely Java-side.
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index adee9d8..737f107 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -129,7 +129,6 @@ struct FieldIds {
mAutoFillEnabled = env->GetFieldID(clazz, "mAutoFillEnabled", "Z");
mAutoFillProfile = env->GetFieldID(clazz, "mAutoFillProfile", "Landroid/webkit/WebSettings$AutoFillProfile;");
jclass autoFillProfileClass = env->FindClass("android/webkit/WebSettings$AutoFillProfile");
- mAutoFillProfileUniqueId = env->GetFieldID(autoFillProfileClass, "mUniqueId", "I");
mAutoFillProfileFullName = env->GetFieldID(autoFillProfileClass, "mFullName", "Ljava/lang/String;");
mAutoFillProfileEmailAddress = env->GetFieldID(autoFillProfileClass, "mEmailAddress", "Ljava/lang/String;");
mAutoFillProfileCompanyName = env->GetFieldID(autoFillProfileClass, "mCompanyName", "Ljava/lang/String;");
@@ -254,7 +253,6 @@ struct FieldIds {
#if ENABLE(WEB_AUTOFILL)
jfieldID mAutoFillEnabled;
jfieldID mAutoFillProfile;
- jfieldID mAutoFillProfileUniqueId;
jfieldID mAutoFillProfileFullName;
jfieldID mAutoFillProfileEmailAddress;
jfieldID mAutoFillProfileCompanyName;
@@ -291,8 +289,6 @@ inline string16 getStringFieldAsString16(JNIEnv* env, jobject autoFillProfile, j
void syncAutoFillProfile(JNIEnv* env, jobject autoFillProfile, WebAutoFill* webAutoFill)
{
- // FIXME: id is deprecated.
- int id = env->GetIntField(autoFillProfile, gFieldIds->mAutoFillProfileUniqueId);
string16 fullName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileFullName);
string16 emailAddress = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileEmailAddress);
string16 companyName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCompanyName);
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index c631cd4..449b9e2 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -1275,6 +1275,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
isUnclipped = isTransparent;
} else if (input->isInputTypeHidden())
continue;
+ else if (input->isRadioButton() || input->isCheckbox())
+ isTransparent = false;
} else if (node->hasTagName(HTMLNames::textareaTag)) {
cachedInput.init();
type = TEXT_INPUT_CACHEDNODETYPE;
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index a41cfdc..1a31c15 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -717,9 +717,8 @@ public:
layers->getBounds().fLeft, layers->getBounds().fTop,
layers->getBounds().fRight, layers->getBounds().fBottom);
if (collectGlyphs && (layerType == kDrawGlyph_Type
- || ((layerType == kDrawRect_Type
- || layerType == kDrawBitmap_Type)
- && mTextTest.contains(*layers)))) {
+ || ((layerType == kDrawRect_Type && mTextTest.contains(*layers))
+ || (layerType == kDrawBitmap_Type && mTextSlop.contains(*layers))))) {
DBG_NAV_LOGD("RingCheck #%d collectOvers", layers - mLayers.begin());
collectOvers = true;
clipped->op(*layers, SkRegion::kUnion_Op);
@@ -964,9 +963,9 @@ private:
mTextSlop.contains(*layers) ? "true" : "false",
gb.fLeft, gb.fTop, gb.fRight, gb.fBottom);
#endif
- if ((layerType == kDrawGlyph_Type && mTextSlop.contains(*layers))
- || ((layerType == kDrawRect_Type
- || layerType == kDrawBitmap_Type)
+ if (((layerType == kDrawGlyph_Type || layerType == kDrawBitmap_Type)
+ && mTextSlop.contains(*layers))
+ || (layerType == kDrawRect_Type
&& mTextTest.contains(*layers))) {
if (!testLayer)
testLayer = layers;
@@ -1854,7 +1853,8 @@ void CachedRoot::Debug::print() const
b->mHistory->mDebug.print(b);
DUMP_NAV_LOGD("// int mMaxXScroll=%d, mMaxYScroll=%d;\n",
b->mMaxXScroll, b->mMaxYScroll);
- CachedLayer::Debug::printRootLayerAndroid(b->mRootLayer);
+ if (b->mRootLayer)
+ CachedLayer::Debug::printRootLayerAndroid(b->mRootLayer);
#ifdef DUMP_NAV_CACHE_USING_PRINTF
if (gNavCacheLogFile)
fclose(gNavCacheLogFile);
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 03052ca..6370021 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -1793,6 +1793,25 @@ static void nativeSelectBestAt(JNIEnv *env, jobject obj, jobject jrect)
view->selectBestAt(rect);
}
+static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer)
+{
+ SkRect r;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layer = (LayerAndroid*) jlayer;
+ r = layer->bounds();
+#else
+ r.setEmpty();
+#endif
+ SkIRect irect;
+ r.round(&irect);
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop,
+ irect.fRight, irect.fBottom);
+ env->DeleteLocalRef(rectClass);
+ return rect;
+}
+
static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect)
{
SkIRect irect = jrect_to_webrect(env, jrect);
@@ -2048,19 +2067,10 @@ static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y)
GET_NATIVE_VIEW(env, obj)->moveSelection(x, y);
}
-static jboolean nativeCleanupPrivateBrowsingFiles(
- JNIEnv *env, jobject obj, jstring databaseDirectoryJString, jstring cacheDirectoryJString) {
+static jboolean nativeCleanupPrivateBrowsingFiles(JNIEnv*, jobject)
+{
#if USE(CHROME_NETWORK_STACK)
- jboolean isCopy;
- const char* cString = env->GetStringUTFChars(databaseDirectoryJString, &isCopy);
- std::string databaseDirectory(cString);
- if (isCopy == JNI_TRUE)
- env->ReleaseStringUTFChars(databaseDirectoryJString, cString);
- cString = env->GetStringUTFChars(cacheDirectoryJString, &isCopy);
- std::string cacheDirectory(cString);
- if (isCopy == JNI_TRUE)
- env->ReleaseStringUTFChars(cacheDirectoryJString, cString);
- return WebRequestContext::cleanupPrivateBrowsingFiles(databaseDirectory, cacheDirectory);
+ return WebRequestContext::cleanupPrivateBrowsingFiles();
#else
return JNI_FALSE;
#endif
@@ -2312,6 +2322,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeImageURI },
{ "nativeInstrumentReport", "()V",
(void*) nativeInstrumentReport },
+ { "nativeLayerBounds", "(I)Landroid/graphics/Rect;",
+ (void*) nativeLayerBounds },
{ "nativeMotionUp", "(III)Z",
(void*) nativeMotionUp },
{ "nativeMoveCursor", "(IIZ)Z",
@@ -2322,7 +2334,7 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeMoveGeneration },
{ "nativeMoveSelection", "(II)V",
(void*) nativeMoveSelection },
- { "nativeCleanupPrivateBrowsingFiles", "(Ljava/lang/String;Ljava/lang/String;)Z",
+ { "nativeCleanupPrivateBrowsingFiles", "()Z",
(void*) nativeCleanupPrivateBrowsingFiles },
{ "nativePointInNavCache", "(III)Z",
(void*) nativePointInNavCache },