Add a CTS test for a WebView crash due to AppCache
This crash occurred when AppCache was used without having set the
database path.
Bug: 3305684
Change-Id: I90209f63c77b731f98280ea6da8c453e02840f5a
diff --git a/tests/src/android/webkit/cts/CtsTestServer.java b/tests/src/android/webkit/cts/CtsTestServer.java
index 87b3d1d..075f98d 100644
--- a/tests/src/android/webkit/cts/CtsTestServer.java
+++ b/tests/src/android/webkit/cts/CtsTestServer.java
@@ -81,6 +81,8 @@
public static final String USERAGENT_PATH = "/useragent.html";
public static final String ASSET_PREFIX = "/assets/";
public static final String FAVICON_ASSET_PATH = ASSET_PREFIX + "webkit/favicon.png";
+ public static final String APPCACHE_PATH = "/appcache.html";
+ public static final String APPCACHE_MANIFEST_PATH = "/appcache.manifest";
public static final String REDIRECT_PREFIX = "/redirect";
public static final String DELAY_PREFIX = "/delayed";
public static final String BINARY_PREFIX = "/binary";
@@ -342,6 +344,12 @@
return sb.toString();
}
+ public String getAppCacheUrl() {
+ StringBuilder sb = new StringBuilder(getBaseUri());
+ sb.append(APPCACHE_PATH);
+ return sb.toString();
+ }
+
public String getLastRequestUrl() {
return mLastQuery;
}
@@ -500,6 +508,38 @@
// We cannot close the socket here, because we need to respond.
// Status must be set to OK, or else the test will fail due to
// a RunTimeException.
+ } else if (path.equals(APPCACHE_PATH)) {
+ response = createResponse(HttpStatus.SC_OK);
+ response.setEntity(createEntity("<!DOCTYPE HTML>" +
+ "<html manifest=\"appcache.manifest\">" +
+ " <head>" +
+ " <title>Waiting</title>" +
+ " <script>" +
+ " function updateTitle() { document.title = \"Done\"; }" +
+ " window.applicationCache.onnoupdate = updateTitle;" +
+ " window.applicationCache.oncached = updateTitle;" +
+ " window.applicationCache.onupdateready = updateTitle;" +
+ " window.applicationCache.onobsolete = updateTitle;" +
+ " window.applicationCache.onerror = updateTitle;" +
+ " </script>" +
+ " </head>" +
+ " <body>AppCache test</body>" +
+ "</html>"));
+ } else if (path.equals(APPCACHE_MANIFEST_PATH)) {
+ response = createResponse(HttpStatus.SC_OK);
+ try {
+ StringEntity entity = new StringEntity("CACHE MANIFEST");
+ // This entity property is not used when constructing the response, (See
+ // AbstractMessageWriter.write(), which is called by
+ // AbstractHttpServerConnection.sendResponseHeader()) so we have to set this header
+ // manually.
+ // TODO: Should we do this for all responses from this server?
+ entity.setContentType("text/cache-manifest");
+ response.setEntity(entity);
+ response.setHeader("Content-Type", "text/cache-manifest");
+ } catch (UnsupportedEncodingException e) {
+ Log.w(TAG, "Unexpected UnsupportedEncodingException");
+ }
}
if (response == null) {
response = createResponse(HttpStatus.SC_NOT_FOUND);
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index de80713..6b9f9dc 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -996,6 +996,37 @@
assertTrue(mSettings.getBuiltInZoomControls());
}
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAppCacheEnabled",
+ args = {}
+ )
+ })
+ public void testSetAppCacheEnabled() throws Exception {
+ // Tests that when AppCache is enabled and used, but the database path
+ // is not set or is set to an inaccessible path, the WebView does not crash.
+ startWebServer();
+ String url = mWebServer.getAppCacheUrl();
+ mSettings.setAppCacheEnabled(true);
+ mSettings.setJavaScriptEnabled(true);
+
+ mWebView.loadUrl(url);
+ new DelayedCheck(10000) {
+ protected boolean check() {
+ return mWebView.getTitle().equals("Done");
+ }
+ }.run();
+
+ mSettings.setAppCachePath("/data/foo");
+ mWebView.loadUrl(url);
+ new DelayedCheck(10000) {
+ protected boolean check() {
+ return mWebView.getTitle().equals("Done");
+ }
+ }.run();
+ }
+
/**
* Starts the internal web server. The server will be shut down automatically
* during tearDown().