blob: f58f88b4c9c12819eb59c2bbb459fcacec80fc91 [file] [log] [blame]
John Reckd8c74522011-06-14 08:45:00 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.browser;
17
18import android.content.ContentResolver;
19import android.content.ContentUris;
20import android.content.ContentValues;
21import android.database.Cursor;
22import android.graphics.BitmapFactory;
John Reckd8c74522011-06-14 08:45:00 -070023import android.net.Uri;
24import android.os.AsyncTask;
John Reck1cf4b792011-07-26 10:22:22 -070025import android.os.Bundle;
John Reck8cc92352011-07-06 17:41:52 -070026import android.util.Log;
John Reckd8c74522011-06-14 08:45:00 -070027import android.webkit.WebView;
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +000028import android.webkit.WebViewClassic;
John Reckd8c74522011-06-14 08:45:00 -070029
John Reck8cc92352011-07-06 17:41:52 -070030import com.android.browser.provider.SnapshotProvider.Snapshots;
John Reckd8c74522011-06-14 08:45:00 -070031
32import java.io.ByteArrayInputStream;
John Reckef654f12011-07-12 16:42:08 -070033import java.util.Map;
John Reck8cc92352011-07-06 17:41:52 -070034import java.util.zip.GZIPInputStream;
John Reckd8c74522011-06-14 08:45:00 -070035
36
37public class SnapshotTab extends Tab {
38
John Reck8cc92352011-07-06 17:41:52 -070039 private static final String LOGTAG = "SnapshotTab";
40
John Reckd8c74522011-06-14 08:45:00 -070041 private long mSnapshotId;
42 private LoadData mLoadTask;
43 private WebViewFactory mWebViewFactory;
John Reckd8c74522011-06-14 08:45:00 -070044 private int mBackgroundColor;
John Reckef654f12011-07-12 16:42:08 -070045 private long mDateCreated;
46 private boolean mIsLive;
John Reckd8c74522011-06-14 08:45:00 -070047
48 public SnapshotTab(WebViewController wvcontroller, long snapshotId) {
John Reck1cf4b792011-07-26 10:22:22 -070049 super(wvcontroller, null, null);
John Reckd8c74522011-06-14 08:45:00 -070050 mSnapshotId = snapshotId;
51 mWebViewFactory = mWebViewController.getWebViewFactory();
John Reckef654f12011-07-12 16:42:08 -070052 WebView web = mWebViewFactory.createWebView(false);
53 setWebView(web);
John Reckd8c74522011-06-14 08:45:00 -070054 loadData();
55 }
56
57 @Override
58 void putInForeground() {
59 if (getWebView() == null) {
60 WebView web = mWebViewFactory.createWebView(false);
61 if (mBackgroundColor != 0) {
62 web.setBackgroundColor(mBackgroundColor);
63 }
64 setWebView(web);
65 loadData();
66 }
67 super.putInForeground();
68 }
69
70 @Override
71 void putInBackground() {
72 if (getWebView() == null) return;
73 super.putInBackground();
John Reckd8c74522011-06-14 08:45:00 -070074 }
75
76 void loadData() {
77 if (mLoadTask == null) {
Michael Kolb14612442011-06-24 13:06:29 -070078 mLoadTask = new LoadData(this, mContext.getContentResolver());
John Reckd8c74522011-06-14 08:45:00 -070079 mLoadTask.execute();
80 }
81 }
82
83 @Override
84 void addChildTab(Tab child) {
John Recke91c7482011-08-23 14:04:29 -070085 if (mIsLive) {
86 super.addChildTab(child);
87 } else {
88 throw new IllegalStateException("Snapshot tabs cannot have child tabs!");
89 }
John Reckd8c74522011-06-14 08:45:00 -070090 }
91
92 @Override
93 public boolean isSnapshot() {
John Reckef654f12011-07-12 16:42:08 -070094 return !mIsLive;
John Reckd8c74522011-06-14 08:45:00 -070095 }
96
97 public long getSnapshotId() {
98 return mSnapshotId;
99 }
100
101 @Override
102 public ContentValues createSnapshotValues() {
John Recke91c7482011-08-23 14:04:29 -0700103 if (mIsLive) {
104 return super.createSnapshotValues();
105 }
John Reckd8c74522011-06-14 08:45:00 -0700106 return null;
107 }
108
109 @Override
John Reck80a5fbb2011-07-27 15:05:16 -0700110 public Bundle saveState() {
John Recke91c7482011-08-23 14:04:29 -0700111 if (mIsLive) {
112 return super.saveState();
113 }
John Reck1cf4b792011-07-26 10:22:22 -0700114 return null;
John Reckd8c74522011-06-14 08:45:00 -0700115 }
116
John Reckef654f12011-07-12 16:42:08 -0700117 public long getDateCreated() {
118 return mDateCreated;
119 }
120
121 @Override
122 public void loadUrl(String url, Map<String, String> headers) {
123 if (!mIsLive) {
124 mIsLive = true;
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +0000125 getWebViewClassic().clearViewState();
John Reckef654f12011-07-12 16:42:08 -0700126 }
127 super.loadUrl(url, headers);
128 }
129
130 @Override
131 public boolean canGoBack() {
132 return super.canGoBack() || mIsLive;
133 }
134
135 @Override
136 public boolean canGoForward() {
137 return mIsLive && super.canGoForward();
138 }
139
140 @Override
141 public void goBack() {
142 if (super.canGoBack()) {
143 super.goBack();
144 } else {
145 mIsLive = false;
146 getWebView().stopLoading();
147 loadData();
148 }
149 }
150
John Reckd8c74522011-06-14 08:45:00 -0700151 static class LoadData extends AsyncTask<Void, Void, Cursor> {
152
153 static final String[] PROJECTION = new String[] {
154 Snapshots._ID, // 0
155 Snapshots.TITLE, // 1
156 Snapshots.URL, // 2
157 Snapshots.FAVICON, // 3
158 Snapshots.VIEWSTATE, // 4
159 Snapshots.BACKGROUND, // 5
John Reckef654f12011-07-12 16:42:08 -0700160 Snapshots.DATE_CREATED, // 6
John Reckd8c74522011-06-14 08:45:00 -0700161 };
162
163 private SnapshotTab mTab;
164 private ContentResolver mContentResolver;
165
166 public LoadData(SnapshotTab t, ContentResolver cr) {
167 mTab = t;
168 mContentResolver = cr;
169 }
170
171 @Override
172 protected Cursor doInBackground(Void... params) {
173 long id = mTab.mSnapshotId;
174 Uri uri = ContentUris.withAppendedId(Snapshots.CONTENT_URI, id);
175 return mContentResolver.query(uri, PROJECTION, null, null, null);
176 }
177
178 @Override
179 protected void onPostExecute(Cursor result) {
180 try {
181 if (result.moveToFirst()) {
182 mTab.mCurrentState.mTitle = result.getString(1);
183 mTab.mCurrentState.mUrl = result.getString(2);
184 byte[] favicon = result.getBlob(3);
185 if (favicon != null) {
186 mTab.mCurrentState.mFavicon = BitmapFactory
187 .decodeByteArray(favicon, 0, favicon.length);
188 }
Jonathan Dixon4d2fcab2012-02-24 00:13:06 +0000189 WebViewClassic web = mTab.getWebViewClassic();
John Reckd8c74522011-06-14 08:45:00 -0700190 if (web != null) {
191 byte[] data = result.getBlob(4);
John Reck8cc92352011-07-06 17:41:52 -0700192 ByteArrayInputStream bis = new ByteArrayInputStream(data);
John Reck28263772011-10-11 17:13:42 -0700193 GZIPInputStream stream = new GZIPInputStream(bis);
194 web.loadViewState(stream);
John Reckd8c74522011-06-14 08:45:00 -0700195 }
196 mTab.mBackgroundColor = result.getInt(5);
John Reckef654f12011-07-12 16:42:08 -0700197 mTab.mDateCreated = result.getLong(6);
John Reckd8c74522011-06-14 08:45:00 -0700198 mTab.mWebViewController.onPageFinished(mTab);
199 }
John Reck28263772011-10-11 17:13:42 -0700200 } catch (Exception e) {
201 Log.w(LOGTAG, "Failed to load view state, closing tab", e);
202 mTab.mWebViewController.closeTab(mTab);
John Reckd8c74522011-06-14 08:45:00 -0700203 } finally {
204 if (result != null) {
205 result.close();
206 }
207 mTab.mLoadTask = null;
208 }
209 }
210
211 }
John Reck1cf4b792011-07-26 10:22:22 -0700212
213 @Override
214 protected void persistThumbnail() {
John Recke91c7482011-08-23 14:04:29 -0700215 if (mIsLive) {
216 super.persistThumbnail();
217 }
John Reck1cf4b792011-07-26 10:22:22 -0700218 }
John Reckd8c74522011-06-14 08:45:00 -0700219}