Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(712)

Unified Diff: android_webview/java/src/org/chromium/android_webview/AwContents.java

Issue 10946013: Add WebView.saveWebArchive support to android_webview. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/java/src/org/chromium/android_webview/AwContents.java
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 94b0eae75dacaf9cc1ede495ddde70efedf4a9c9..9c50fa14b3b1bcb4d4910f0c5ef67da31be02ee0 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -4,14 +4,24 @@
package org.chromium.android_webview;
-import android.view.ViewGroup;
+import android.os.AsyncTask;
import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.webkit.ValueCallback;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
+import org.chromium.base.ThreadUtils;
import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.NavigationHistory;
import org.chromium.content.common.CleanupReference;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
/**
* Exposes the native AwContents class, and together these classes wrap the ContentViewCore
* and Browser components that are required to implement Android WebView API. This is the
@@ -22,6 +32,7 @@ import org.chromium.content.common.CleanupReference;
*/
@JNINamespace("android_webview")
public class AwContents {
+ private static final String TAG = AwContents.class.getSimpleName();
private int mNativeAwContents;
private ContentViewCore mContentViewCore;
@@ -93,7 +104,95 @@ public class AwContents {
//--------------------------------------------------------------------------------------------
public void documentHasImages(Message message) {
- nativeDocumentHasImages(mNativeAwContents, message);
+ nativeDocumentHasImages(mNativeAwContents, message);
+ }
+
+ /**
+ * Generate an MHTML archive of the current page.
+ *
+ * @see android.webkit.WebView#saveWebArchive(String, boolean, ValueCallback)
+ */
benm (inactive) 2012/09/19 14:06:52 Don't think we need these comments.
Ted C 2012/09/19 16:53:22 Done.
+ public void saveWebArchive(
+ final String basename, boolean autoname, final ValueCallback<String> callback) {
+ if (!autoname) {
+ saveWebArchiveInternal(basename, callback);
+ return;
+ }
+ // If auto-generating the file name, handle the name generation on a background thread
+ // as it will require I/O access for checking whether previous files existed.
+ new AsyncTask<Void, Void, String>() {
+ @Override
+ protected String doInBackground(Void... params) {
+ return generateArchiveAutoNamePath(getOriginalUrl(), basename, ".mht");
benm (inactive) 2012/09/19 14:06:52 .mht feels like it should be a const
Ted C 2012/09/19 16:53:22 Made it a constant and since generateArchiveAutoNa
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ saveWebArchiveInternal(result, callback);
+ }
+ }.execute();
+ }
+
+ private void saveWebArchiveInternal(String path, final ValueCallback<String> callback) {
benm (inactive) 2012/09/19 14:06:52 Probably best to move this helper to the bottom an
Ted C 2012/09/19 16:53:22 Done.
+ if (path == null) {
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ callback.onReceiveValue(null);
+ }
+ });
+ } else {
+ nativeGenerateMHTML(mNativeAwContents, path, callback);
+ }
+ }
+
+ /**
+ * Try to generate a pathname for saving an MHTML archive. This roughly follows WebView's
+ * autoname logic.
+ */
+ private static String generateArchiveAutoNamePath(
benm (inactive) 2012/09/19 14:06:52 ditto move as a helper.
Ted C 2012/09/19 16:53:22 Done.
+ String originalUrl, String baseName, String extension) {
+ String name = null;
+ if (originalUrl != null && !originalUrl.isEmpty()) {
+ try {
+ String path = new URL(originalUrl).getPath();
+ int lastSlash = path.lastIndexOf('/');
+ if (lastSlash > 0) {
+ name = path.substring(lastSlash + 1);
+ } else {
+ name = path;
+ }
+ } catch (MalformedURLException e) {
+ // TODO(jgreenwald): is this really possible? Is there some other default we should
mkosiba (inactive) 2012/09/19 12:21:39 nit: I don't think Jesse's going to be addressing
Ted C 2012/09/19 16:53:22 Done.
+ // use?
+ }
+ }
+
+ if (TextUtils.isEmpty(name)) name = "index";
+
+ String testName = baseName + name + extension;
+ if (!new File(testName).exists()) return testName;
+
+ for (int i = 1; i < 100; i++) {
+ testName = baseName + name + "-" + i + extension;
+ if (!new File(testName).exists()) return testName;
+ }
+
+ Log.e(TAG, "Unable to auto generate archive name for path: " + baseName);
+ return null;
+ }
+
+ /**
+ * @see android.webkit.WebView#getOriginalUrl()
benm (inactive) 2012/09/19 14:06:52 Don't need this comment.
Ted C 2012/09/19 16:53:22 Done.
+ */
+ public String getOriginalUrl() {
+ NavigationHistory history = mContentViewCore.getNavigationHistory();
+ int currentIndex = history.getCurrentEntryIndex();
+ if (currentIndex >= 0 && currentIndex < history.getEntryCount()) {
+ return history.getEntryAtIndex(currentIndex).getOriginalUrl();
+ } else {
benm (inactive) 2012/09/19 14:06:52 no need for an else block here.
Ted C 2012/09/19 16:53:22 Done.
+ return null;
+ }
}
//--------------------------------------------------------------------------------------------
@@ -106,6 +205,14 @@ public class AwContents {
message.sendToTarget();
}
+ /** Callback for generateMHTML. */
+ @CalledByNative
+ private static void generateMHTMLCallback(
+ String path, long size, ValueCallback<String> callback) {
+ if (callback == null) return;
+ callback.onReceiveValue(size < 0 ? null : path);
+ }
+
@CalledByNative
private void onReceivedHttpAuthRequest(AwHttpAuthHandler handler, String host, String realm) {
mContentsClient.onReceivedHttpAuthRequest(handler, host, realm);
@@ -122,4 +229,6 @@ public class AwContents {
private native int nativeGetWebContents(int nativeAwContents);
private native void nativeDocumentHasImages(int nativeAwContents, Message message);
+ private native void nativeGenerateMHTML(
+ int nativeAwContents, String path, ValueCallback<String> callback);
}

Powered by Google App Engine
This is Rietveld 408576698