diff options
author | John Reck <jreck@google.com> | 2011-06-07 16:34:43 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2011-06-07 16:34:58 -0700 |
commit | 541f55a0178da7c09fb32aa5385effae031ea071 (patch) | |
tree | c1e6d7554b9d682fbd6db5b00e7702a8f355ab5f | |
parent | f33b1637487af3786ee30f295f2c84db6db1e6b3 (diff) | |
download | packages_apps_Browser-541f55a0178da7c09fb32aa5385effae031ea071.zip packages_apps_Browser-541f55a0178da7c09fb32aa5385effae031ea071.tar.gz packages_apps_Browser-541f55a0178da7c09fb32aa5385effae031ea071.tar.bz2 |
Freeze tab improvements
Change-Id: I5d5e5a7a18cafdbe845fa1ef949276bdfd1996d3
-rw-r--r-- | res/drawable-hdpi/ic_snapshot.png | bin | 0 -> 3576 bytes | |||
-rw-r--r-- | res/drawable-mdpi/ic_snapshot.png | bin | 0 -> 1834 bytes | |||
-rw-r--r-- | res/layout/tab_title.xml | 7 | ||||
-rw-r--r-- | src/com/android/browser/Controller.java | 16 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 120 | ||||
-rw-r--r-- | src/com/android/browser/TabBar.java | 19 | ||||
-rw-r--r-- | src/com/android/browser/XLargeUi.java | 2 |
7 files changed, 141 insertions, 23 deletions
diff --git a/res/drawable-hdpi/ic_snapshot.png b/res/drawable-hdpi/ic_snapshot.png Binary files differnew file mode 100644 index 0000000..a621cb4 --- /dev/null +++ b/res/drawable-hdpi/ic_snapshot.png diff --git a/res/drawable-mdpi/ic_snapshot.png b/res/drawable-mdpi/ic_snapshot.png Binary files differnew file mode 100644 index 0000000..6054acb --- /dev/null +++ b/res/drawable-mdpi/ic_snapshot.png 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); |