summaryrefslogtreecommitdiffstats
path: root/src/com/android/browser
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2011-10-07 15:57:53 -0700
committerGeorge Mount <mount@google.com>2011-10-10 13:11:56 -0700
commit387d45d2284c7fd7f12cbadc96161f946ae29cad (patch)
tree04bc0d8cdcca96dc2d5730f26309885f55d99d95 /src/com/android/browser
parent07af26d9ae4239bad876e8fd7ac69984a1d66996 (diff)
downloadandroid_packages_apps_Gello-387d45d2284c7fd7f12cbadc96161f946ae29cad.tar.gz
android_packages_apps_Gello-387d45d2284c7fd7f12cbadc96161f946ae29cad.tar.bz2
android_packages_apps_Gello-387d45d2284c7fd7f12cbadc96161f946ae29cad.zip
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
Diffstat (limited to 'src/com/android/browser')
-rw-r--r--src/com/android/browser/Controller.java70
-rw-r--r--src/com/android/browser/DataUri.java74
-rw-r--r--src/com/android/browser/NavigationBarTablet.java20
-rw-r--r--src/com/android/browser/PhoneUi.java4
-rw-r--r--src/com/android/browser/WallpaperHandler.java37
5 files changed, 189 insertions, 16 deletions
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 282d4f2e..81ba9411 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -40,6 +40,7 @@ import android.net.Uri;
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.view.View;
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.browser.search.SearchEngine;
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 @@ public class Controller
// "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 @@ public class Controller
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 @@ public class Controller
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 {
diff --git a/src/com/android/browser/DataUri.java b/src/com/android/browser/DataUri.java
new file mode 100644
index 00000000..642b0601
--- /dev/null
+++ b/src/com/android/browser/DataUri.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.browser;
+
+import java.net.MalformedURLException;
+
+import libcore.io.Base64;
+
+/**
+ * Class extracts the mime type and data from a data uri.
+ * A data URI is of the form:
+ * <pre>
+ * data:[&lt;MIME-type&gt;][;charset=&lt;encoding&gt;][;base64],&lt;data&gt;
+ * </pre>
+ */
+public class DataUri {
+ private static final String DATA_URI_PREFIX = "data:";
+ private static final String BASE_64_ENCODING = ";base64";
+
+ private String mMimeType;
+ private byte[] mData;
+
+ public DataUri(String uri) throws MalformedURLException {
+ if (!isDataUri(uri)) {
+ throw new MalformedURLException("Not a data URI");
+ }
+
+ int commaIndex = uri.indexOf(',', DATA_URI_PREFIX.length());
+ if (commaIndex < 0) {
+ throw new MalformedURLException("Comma expected in data URI");
+ }
+ String contentType = uri.substring(DATA_URI_PREFIX.length(),
+ commaIndex);
+ mData = uri.substring(commaIndex + 1).getBytes();
+ if (contentType.contains(BASE_64_ENCODING)) {
+ mData = Base64.decode(mData);
+ }
+ int semiIndex = contentType.indexOf(';');
+ if (semiIndex > 0) {
+ mMimeType = contentType.substring(0, semiIndex);
+ } else {
+ mMimeType = contentType;
+ }
+ }
+
+ /**
+ * Returns true if the text passed in appears to be a data URI.
+ */
+ public static boolean isDataUri(String text)
+ {
+ return text.startsWith(DATA_URI_PREFIX);
+ }
+
+ public String getMimeType() {
+ return mMimeType;
+ }
+
+ public byte[] getData() {
+ return mData;
+ }
+}
diff --git a/src/com/android/browser/NavigationBarTablet.java b/src/com/android/browser/NavigationBarTablet.java
index c22b1a0c..be3a9aba 100644
--- a/src/com/android/browser/NavigationBarTablet.java
+++ b/src/com/android/browser/NavigationBarTablet.java
@@ -151,6 +151,12 @@ public class NavigationBarTablet extends NavigationBarBase {
}
@Override
+ public void onTabDataChanged(Tab tab) {
+ super.onTabDataChanged(tab);
+ showHideStar(tab);
+ }
+
+ @Override
public void setCurrentUrlIsBookmark(boolean isBookmark) {
mStar.setActivated(isBookmark);
}
@@ -235,7 +241,7 @@ public class NavigationBarTablet extends NavigationBarBase {
}
mGoButton.setVisibility(View.GONE);
mVoiceSearch.setVisibility(View.GONE);
- mStar.setVisibility(View.VISIBLE);
+ showHideStar(mUiController.getCurrentTab());
mClearButton.setVisibility(View.GONE);
if (mTitleBar.useQuickControls()) {
mSearchButton.setVisibility(View.GONE);
@@ -321,4 +327,16 @@ public class NavigationBarTablet extends NavigationBarBase {
combo.start();
}
+ private void showHideStar(Tab tab) {
+ // hide the bookmark star for data URLs
+ if (tab != null && tab.inForeground()) {
+ int starVisibility = View.VISIBLE;
+ String url = tab.getUrl();
+ if (DataUri.isDataUri(url)) {
+ starVisibility = View.GONE;
+ }
+ mStar.setVisibility(starVisibility);
+ }
+ }
+
}
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 0e2710de..ddb4e0e0 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -196,7 +196,9 @@ public class PhoneUi extends BaseUi {
public void updateMenuState(Tab tab, Menu menu) {
MenuItem bm = menu.findItem(R.id.bookmarks_menu_id);
if (bm != null) {
- bm.setVisible(!showingNavScreen());
+ String url = tab.getUrl();
+ boolean isDataUrl = DataUri.isDataUri(url);
+ bm.setVisible(!showingNavScreen() && !isDataUrl);
}
MenuItem nt = menu.findItem(R.id.new_tab_menu_id);
if (nt != null) {
diff --git a/src/com/android/browser/WallpaperHandler.java b/src/com/android/browser/WallpaperHandler.java
index 6437b1a2..b76861cc 100644
--- a/src/com/android/browser/WallpaperHandler.java
+++ b/src/com/android/browser/WallpaperHandler.java
@@ -27,8 +27,8 @@ import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
-
import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -41,24 +41,19 @@ import java.net.URL;
public class WallpaperHandler extends Thread
implements OnMenuItemClickListener, DialogInterface.OnCancelListener {
-
private static final String LOGTAG = "WallpaperHandler";
// This should be large enough for BitmapFactory to decode the header so
// that we can mark and reset the input stream to avoid duplicate network i/o
private static final int BUFFER_SIZE = 128 * 1024;
private Context mContext;
- private URL mUrl;
+ private String mUrl;
private ProgressDialog mWallpaperProgress;
private boolean mCanceled = false;
public WallpaperHandler(Context context, String url) {
mContext = context;
- try {
- mUrl = new URL(url);
- } catch (MalformedURLException e) {
- mUrl = null;
- }
+ mUrl = url;
}
@Override
@@ -97,7 +92,7 @@ public class WallpaperHandler extends Thread
// version and instead open an input stream on that. This pattern
// could also be used in the download manager where the same problem
// exists.
- inputstream = mUrl.openStream();
+ inputstream = openStream();
if (inputstream != null) {
if (!inputstream.markSupported()) {
inputstream = new BufferedInputStream(inputstream, BUFFER_SIZE);
@@ -118,7 +113,7 @@ public class WallpaperHandler extends Thread
int bmHeight = options.outHeight;
int scale = 1;
- while (bmWidth > maxWidth || bmHeight > maxWidth) {
+ while (bmWidth > maxWidth || bmHeight > maxHeight) {
scale <<= 1;
bmWidth >>= 1;
bmHeight >>= 1;
@@ -131,7 +126,7 @@ public class WallpaperHandler extends Thread
// BitmapFactory read more than we could buffer
// Re-open the stream
inputstream.close();
- inputstream = mUrl.openStream();
+ inputstream = openStream();
}
Bitmap scaledWallpaper = BitmapFactory.decodeStream(inputstream,
null, options);
@@ -175,4 +170,24 @@ public class WallpaperHandler extends Thread
mWallpaperProgress.dismiss();
}
}
+
+ /**
+ * Opens the input stream for the URL that the class should
+ * use to set the wallpaper. Abstracts the difference between
+ * standard URLs and data URLs.
+ * @return An open InputStream for the data at the URL
+ * @throws IOException if there is an error opening the URL stream
+ * @throws MalformedURLException if the URL is malformed
+ */
+ private InputStream openStream() throws IOException, MalformedURLException {
+ InputStream inputStream = null;
+ if (DataUri.isDataUri(mUrl)) {
+ DataUri dataUri = new DataUri(mUrl);
+ inputStream = new ByteArrayInputStream(dataUri.getData());
+ } else {
+ URL url = new URL(mUrl);
+ inputStream = url.openStream();
+ }
+ return inputStream;
+ }
}