summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/drawable-hdpi/ic_snapshot.pngbin0 -> 3576 bytes
-rw-r--r--res/drawable-mdpi/ic_snapshot.pngbin0 -> 1834 bytes
-rw-r--r--res/layout/tab_title.xml7
-rw-r--r--src/com/android/browser/Controller.java16
-rw-r--r--src/com/android/browser/Tab.java120
-rw-r--r--src/com/android/browser/TabBar.java19
-rw-r--r--src/com/android/browser/XLargeUi.java2
7 files changed, 141 insertions, 23 deletions
diff --git a/res/drawable-hdpi/ic_snapshot.png b/res/drawable-hdpi/ic_snapshot.png
new file mode 100644
index 0000000..a621cb4
--- /dev/null
+++ b/res/drawable-hdpi/ic_snapshot.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_snapshot.png b/res/drawable-mdpi/ic_snapshot.png
new file mode 100644
index 0000000..6054acb
--- /dev/null
+++ b/res/drawable-mdpi/ic_snapshot.png
Binary files differ
diff --git a/res/layout/tab_title.xml b/res/layout/tab_title.xml
index e2c6d0a..fcae2bc 100644
--- a/res/layout/tab_title.xml
+++ b/res/layout/tab_title.xml
@@ -31,6 +31,13 @@
android:src="@drawable/ic_incognito_holo_dark"
android:visibility="gone" />
<ImageView
+ android:id="@+id/snapshot"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_snapshot"
+ android:visibility="gone" />
+ <ImageView
android:id="@+id/favicon"
android:layout_width="20dip"
android:layout_height="20dip"
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 6a951c2..986b617 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -1496,7 +1496,6 @@ public class Controller
final MenuItem counter = menu.findItem(R.id.dump_counters_menu_id);
counter.setVisible(showDebugSettings);
counter.setEnabled(showDebugSettings);
- menu.findItem(R.id.freeze_tab_menu_id).setVisible(showDebugSettings);
final MenuItem newtab = menu.findItem(R.id.new_tab_menu_id);
newtab.setEnabled(getTabControl().canCreateNewTab());
@@ -1605,21 +1604,20 @@ public class Controller
case R.id.freeze_tab_menu_id:
// TODO: Show error messages
- WebView source = getCurrentTopWebView();
+ Tab source = getTabControl().getCurrentTab();
if (source == null) break;
- Tab t = createNewTab(false, true, false);
- if (t == null) break;
- WebView pinned = t.getWebView();
- if (pinned == null) break;
+ Tab snapshot = createNewTab(false, false, false);
+ if (snapshot == null) break;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- source.saveViewState(bos);
+ source.saveSnapshot(bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- pinned.loadViewState(bis);
+ snapshot.loadSnapshot(bis);
+ mUi.onTabDataChanged(snapshot);
bis.close();
bos.close();
+ setActiveTab(snapshot);
} catch (IOException e) {
- closeTab(t);
}
break;
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;
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.LinearLayout;
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 @@ class Tab {
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 @@ class Tab {
* @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 @@ class Tab {
}
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 @@ class Tab {
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;
+ }
+
}
diff --git a/src/com/android/browser/TabBar.java b/src/com/android/browser/TabBar.java
index 6c3949a..6e84a40 100644
--- a/src/com/android/browser/TabBar.java
+++ b/src/com/android/browser/TabBar.java
@@ -238,7 +238,7 @@ public class TabBar extends LinearLayout
void showTitleBarIndicator(boolean show) {
Tab tab = mTabControl.getCurrentTab();
- if (tab != null) {
+ if (tab != null && !tab.isSnapshot()) {
TabView tv = mTabMap.get(tab);
if (tv != null) {
tv.showIndicator(show);
@@ -325,6 +325,7 @@ public class TabBar extends LinearLayout
TextView mTitle;
View mIndicator;
View mIncognito;
+ View mSnapshot;
ImageView mIconView;
ImageView mLock;
ImageView mClose;
@@ -355,6 +356,7 @@ public class TabBar extends LinearLayout
mClose = (ImageView) mTabContent.findViewById(R.id.close);
mClose.setOnClickListener(this);
mIncognito = mTabContent.findViewById(R.id.incognito);
+ mSnapshot = mTabContent.findViewById(R.id.snapshot);
mIndicator = mTabContent.findViewById(R.id.chevron);
mSelected = false;
mInLoad = false;
@@ -399,11 +401,15 @@ public class TabBar extends LinearLayout
if (mTab.getFavicon() != null) {
setFavicon(renderFavicon(mTab.getFavicon()));
}
- if (mTab != null) {
- mIncognito.setVisibility(
- mTab.isPrivateBrowsingEnabled() ?
- View.VISIBLE : View.GONE);
- }
+ updateTabIcons();
+ }
+
+ private void updateTabIcons() {
+ mIncognito.setVisibility(
+ mTab.isPrivateBrowsingEnabled() ?
+ View.VISIBLE : View.GONE);
+ mSnapshot.setVisibility(mTab.isSnapshot()
+ ? View.VISIBLE : View.GONE);
}
@Override
@@ -666,6 +672,7 @@ public class TabBar extends LinearLayout
} else if (url != null) {
tv.setDisplayTitle(UrlUtils.stripUrl(url));
}
+ tv.updateTabIcons();
}
}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 1530ed3..25cdbd9 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -213,7 +213,7 @@ public class XLargeUi extends BaseUi implements ScrollListener {
mTabBar.showTitleBarIndicator(false);
} else {
// check if title bar is already attached by animation
- if (mTitleBar.getParent() == null) {
+ if (mTitleBar.getParent() == null && !tab.isSnapshot()) {
view.setEmbeddedTitleBar(mTitleBar);
}
view.setScrollListener(this);