Freeze tab improvements
Change-Id: I5d5e5a7a18cafdbe845fa1ef949276bdfd1996d3
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index b0a991a..95c7850 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -16,9 +16,6 @@
package com.android.browser;
-import com.android.browser.homepages.HomeProvider;
-import com.android.common.speech.LoggingEvents;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
@@ -28,6 +25,7 @@
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.net.http.SslError;
@@ -60,6 +58,15 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.browser.homepages.HomeProvider;
+import com.android.common.speech.LoggingEvents;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -135,6 +142,7 @@
private DataController mDataController;
// State of the auto-login request.
private DeviceAccountLogin mDeviceAccountLogin;
+ private boolean mIsSnapshot = false;
// AsyncTask for downloading touch icons
DownloadTouchIcon mTouchIconLoader;
@@ -1475,6 +1483,10 @@
* @param child the Tab that was created from this Tab
*/
void addChildTab(Tab child) {
+ if (mIsSnapshot) {
+ throw new IllegalStateException(
+ "Snapshot tabs cannot have child tabs!");
+ }
if (mChildren == null) {
mChildren = new Vector<Tab>();
}
@@ -1739,10 +1751,7 @@
}
mSavedState = new Bundle();
- final WebBackForwardList list = mMainView.saveState(mSavedState);
-
- // Store some extra info for displaying the tab in the picker.
- final WebHistoryItem item = list != null ? list.getCurrentItem() : null;
+ mMainView.saveState(mSavedState);
mSavedState.putLong(ID, mId);
mSavedState.putString(CURRURL, mCurrentState.mUrl);
@@ -1807,4 +1816,101 @@
return mScreenshot;
}
+ public boolean isSnapshot() {
+ return mIsSnapshot;
+ }
+
+ public boolean loadSnapshot(InputStream rstream) {
+ if (rstream == null) {
+ mIsSnapshot = false;
+ if (mMainView != null) {
+ mMainView.clearViewState();
+ }
+ return true;
+ }
+ DataInputStream stream = new DataInputStream(rstream);
+ if (!readTabInfo(stream)) {
+ return false;
+ }
+ if (!mMainView.loadViewState(stream)) {
+ return false;
+ }
+ mIsSnapshot = true;
+ return true;
+ }
+
+ public boolean saveSnapshot(OutputStream rstream) {
+ if (rstream == null) return false;
+ if (mMainView == null) return false;
+ DataOutputStream stream = new DataOutputStream(rstream);
+ if (saveTabInfo(stream)) {
+ return mMainView.saveViewState(stream);
+ }
+ return false;
+ }
+
+ private boolean readTabInfo(DataInputStream stream) {
+ try {
+ PageState state = new PageState(mActivity, false);
+ state.mTitle = stream.readUTF();
+ if (state.mTitle.length() == 0) {
+ state.mTitle = null;
+ }
+ state.mUrl = stream.readUTF();
+ int faviconLen = stream.readInt();
+ if (faviconLen > 0) {
+ byte[] data = new byte[faviconLen];
+ int read = stream.read(data);
+ if (read != faviconLen) {
+ throw new IOException("Read didn't match expected len!"
+ + " Expected: " + faviconLen
+ + " Got: " + read);
+ }
+ state.mFavicon = BitmapFactory.decodeByteArray(data, 0, data.length);
+ }
+ mCurrentState = state;
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ private boolean saveTabInfo(DataOutputStream stream) {
+ try {
+ // mTitle might be null, but writeUTF doesn't handle that
+ String title = mCurrentState.mTitle;
+ stream.writeUTF(title != null ? title : "");
+ // mUrl is never null
+ stream.writeUTF(mCurrentState.mUrl);
+ byte[] compressedPixels = compressFavicon();
+ if (compressedPixels == null) {
+ stream.writeInt(-1);
+ } else {
+ stream.writeInt(compressedPixels.length);
+ stream.write(compressedPixels);
+ }
+ return true;
+ } catch (Exception e) {
+ Log.w(LOGTAG, "Failed to saveTabInfo", e);
+ return false;
+ }
+ }
+
+ private byte[] compressFavicon() {
+ Bitmap favicon = mCurrentState.mFavicon;
+ if (favicon == null) {
+ return null;
+ }
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ byte[] data = null;
+ try {
+ favicon.compress(CompressFormat.PNG, 100, stream);
+ data = stream.toByteArray();
+ stream.close();
+ } catch (IOException e) {
+ // Will return null below then
+ }
+ return data;
+ }
+
}