Data URL fixes - bookmarks, save, and wallpaper
Bug 5383517
Images kept in data URLs can now be selected and this fixes the
Save and Set Wallpaper options. It also removes the bookmarking
capability.
Change-Id: I461bdcb4c950f6fcd8db8b38f4c599212106b027
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 282d4f2..81ba941 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -40,6 +40,7 @@
import android.net.http.SslError;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
@@ -68,6 +69,7 @@
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.HttpAuthHandler;
+import android.webkit.MimeTypeMap;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
@@ -86,9 +88,15 @@
import com.android.common.Search;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.URLEncoder;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -140,7 +148,7 @@
// "source" parameter for Google search through simplily type
final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
- // "no-crash-recovery" parameter in intetnt to suppress crash recovery
+ // "no-crash-recovery" parameter in intent to suppress crash recovery
final static String NO_CRASH_RECOVERY = "no-crash-recovery";
// A bitmap that is re-used in createScreenshot as scratch space
@@ -2048,10 +2056,16 @@
private Activity mActivity;
private String mText;
private boolean mPrivateBrowsing;
+ private static final String FALLBACK_EXTENSION = "dat";
+ private static final String IMAGE_BASE_FORMAT = "yyyy-MM-dd-HH-mm-ss-";
public boolean onMenuItemClick(MenuItem item) {
- DownloadHandler.onDownloadStartNoStream(mActivity, mText, null,
- null, null, mPrivateBrowsing);
+ if (DataUri.isDataUri(mText)) {
+ saveDataUri();
+ } else {
+ DownloadHandler.onDownloadStartNoStream(mActivity, mText, null,
+ null, null, mPrivateBrowsing);
+ }
return true;
}
@@ -2060,6 +2074,56 @@
mText = toDownload;
mPrivateBrowsing = privateBrowsing;
}
+
+ /**
+ * Treats mText as a data URI and writes its contents to a file
+ * based on the current time.
+ */
+ private void saveDataUri() {
+ FileOutputStream outputStream = null;
+ try {
+ DataUri uri = new DataUri(mText);
+ File target = getTarget(uri);
+ outputStream = new FileOutputStream(target);
+ outputStream.write(uri.getData());
+ final DownloadManager manager =
+ (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE);
+ manager.addCompletedDownload(target.getName(),
+ mActivity.getTitle().toString(), false,
+ uri.getMimeType(), target.getAbsolutePath(),
+ (long)uri.getData().length, false);
+ } catch (IOException e) {
+ Log.e(LOGTAG, "Could not save data URL");
+ } finally {
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ // ignore close errors
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a File based on the current time stamp and uses
+ * the mime type of the DataUri to get the extension.
+ */
+ private File getTarget(DataUri uri) throws IOException {
+ File dir = mActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
+ DateFormat format = new SimpleDateFormat(IMAGE_BASE_FORMAT);
+ String nameBase = format.format(new Date());
+ String mimeType = uri.getMimeType();
+ MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
+ String extension = mimeTypeMap.getExtensionFromMimeType(mimeType);
+ if (extension == null) {
+ Log.w(LOGTAG, "Unknown mime type in data URI" + mimeType);
+ extension = FALLBACK_EXTENSION;
+ }
+ extension = "." + extension; // createTempFile needs the '.'
+ File targetFile = File.createTempFile(nameBase, extension, dir);
+ return targetFile;
+ }
}
private static class SelectText implements OnMenuItemClickListener {