blob: e403dbcaafa0e102ec8f85952101f9e962871c87 [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 */
Bijan Amirzada41242f22014-03-21 12:12:18 -070016package com.android.browser;
John Reckd8c74522011-06-14 08:45:00 -070017
18import android.content.ContentResolver;
19import android.content.ContentUris;
20import android.content.ContentValues;
John Reck2b71d6d2012-04-18 17:42:06 -070021import android.content.Context;
John Reckd8c74522011-06-14 08:45:00 -070022import android.database.Cursor;
23import android.graphics.BitmapFactory;
John Reckd8c74522011-06-14 08:45:00 -070024import android.net.Uri;
25import android.os.AsyncTask;
John Reck1cf4b792011-07-26 10:22:22 -070026import android.os.Bundle;
John Reck2b71d6d2012-04-18 17:42:06 -070027import android.text.TextUtils;
John Reck8cc92352011-07-06 17:41:52 -070028import android.util.Log;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080029import org.codeaurora.swe.WebView;
John Reckd8c74522011-06-14 08:45:00 -070030
Bijan Amirzada41242f22014-03-21 12:12:18 -070031import com.android.browser.provider.SnapshotProvider.Snapshots;
John Reckd8c74522011-06-14 08:45:00 -070032
33import java.io.ByteArrayInputStream;
John Reck2b71d6d2012-04-18 17:42:06 -070034import java.io.FileNotFoundException;
35import java.io.InputStream;
John Reckef654f12011-07-12 16:42:08 -070036import java.util.Map;
John Reck8cc92352011-07-06 17:41:52 -070037import java.util.zip.GZIPInputStream;
John Reckd8c74522011-06-14 08:45:00 -070038
39
40public class SnapshotTab extends Tab {
41
John Reck8cc92352011-07-06 17:41:52 -070042 private static final String LOGTAG = "SnapshotTab";
43
John Reckd8c74522011-06-14 08:45:00 -070044 private long mSnapshotId;
45 private LoadData mLoadTask;
46 private WebViewFactory mWebViewFactory;
John Reckd8c74522011-06-14 08:45:00 -070047 private int mBackgroundColor;
John Reckef654f12011-07-12 16:42:08 -070048 private long mDateCreated;
49 private boolean mIsLive;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080050 private String mLiveUrl;
John Reckd8c74522011-06-14 08:45:00 -070051
52 public SnapshotTab(WebViewController wvcontroller, long snapshotId) {
John Reck1cf4b792011-07-26 10:22:22 -070053 super(wvcontroller, null, null);
John Reckd8c74522011-06-14 08:45:00 -070054 mSnapshotId = snapshotId;
55 mWebViewFactory = mWebViewController.getWebViewFactory();
John Reckef654f12011-07-12 16:42:08 -070056 WebView web = mWebViewFactory.createWebView(false);
57 setWebView(web);
John Reckd8c74522011-06-14 08:45:00 -070058 loadData();
59 }
60
61 @Override
62 void putInForeground() {
63 if (getWebView() == null) {
64 WebView web = mWebViewFactory.createWebView(false);
65 if (mBackgroundColor != 0) {
66 web.setBackgroundColor(mBackgroundColor);
67 }
68 setWebView(web);
69 loadData();
70 }
71 super.putInForeground();
72 }
73
74 @Override
75 void putInBackground() {
76 if (getWebView() == null) return;
77 super.putInBackground();
John Reckd8c74522011-06-14 08:45:00 -070078 }
79
80 void loadData() {
81 if (mLoadTask == null) {
John Reck2b71d6d2012-04-18 17:42:06 -070082 mLoadTask = new LoadData(this, mContext);
John Reckd8c74522011-06-14 08:45:00 -070083 mLoadTask.execute();
84 }
85 }
86
87 @Override
88 void addChildTab(Tab child) {
John Recke91c7482011-08-23 14:04:29 -070089 if (mIsLive) {
90 super.addChildTab(child);
91 } else {
92 throw new IllegalStateException("Snapshot tabs cannot have child tabs!");
93 }
John Reckd8c74522011-06-14 08:45:00 -070094 }
95
96 @Override
97 public boolean isSnapshot() {
John Reckef654f12011-07-12 16:42:08 -070098 return !mIsLive;
John Reckd8c74522011-06-14 08:45:00 -070099 }
100
101 public long getSnapshotId() {
102 return mSnapshotId;
103 }
104
105 @Override
106 public ContentValues createSnapshotValues() {
John Recke91c7482011-08-23 14:04:29 -0700107 if (mIsLive) {
108 return super.createSnapshotValues();
109 }
John Reckd8c74522011-06-14 08:45:00 -0700110 return null;
111 }
112
113 @Override
John Reck80a5fbb2011-07-27 15:05:16 -0700114 public Bundle saveState() {
John Recke91c7482011-08-23 14:04:29 -0700115 if (mIsLive) {
116 return super.saveState();
117 }
John Reck1cf4b792011-07-26 10:22:22 -0700118 return null;
John Reckd8c74522011-06-14 08:45:00 -0700119 }
120
John Reckef654f12011-07-12 16:42:08 -0700121 public long getDateCreated() {
122 return mDateCreated;
123 }
124
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800125 public String getLiveUrl() {
126 return mLiveUrl;
127 }
128
John Reckef654f12011-07-12 16:42:08 -0700129 @Override
130 public void loadUrl(String url, Map<String, String> headers) {
131 if (!mIsLive) {
132 mIsLive = true;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800133 getWebView().clearViewState();
John Reckef654f12011-07-12 16:42:08 -0700134 }
135 super.loadUrl(url, headers);
136 }
137
138 @Override
139 public boolean canGoBack() {
140 return super.canGoBack() || mIsLive;
141 }
142
143 @Override
144 public boolean canGoForward() {
145 return mIsLive && super.canGoForward();
146 }
147
148 @Override
149 public void goBack() {
150 if (super.canGoBack()) {
151 super.goBack();
152 } else {
153 mIsLive = false;
154 getWebView().stopLoading();
155 loadData();
156 }
157 }
158
John Reckd8c74522011-06-14 08:45:00 -0700159 static class LoadData extends AsyncTask<Void, Void, Cursor> {
160
161 static final String[] PROJECTION = new String[] {
162 Snapshots._ID, // 0
John Reck2b71d6d2012-04-18 17:42:06 -0700163 Snapshots.URL, // 1
164 Snapshots.TITLE, // 2
John Reckd8c74522011-06-14 08:45:00 -0700165 Snapshots.FAVICON, // 3
166 Snapshots.VIEWSTATE, // 4
167 Snapshots.BACKGROUND, // 5
John Reckef654f12011-07-12 16:42:08 -0700168 Snapshots.DATE_CREATED, // 6
John Reck2b71d6d2012-04-18 17:42:06 -0700169 Snapshots.VIEWSTATE_PATH, // 7
John Reckd8c74522011-06-14 08:45:00 -0700170 };
John Reck2b71d6d2012-04-18 17:42:06 -0700171 static final int SNAPSHOT_ID = 0;
172 static final int SNAPSHOT_URL = 1;
173 static final int SNAPSHOT_TITLE = 2;
174 static final int SNAPSHOT_FAVICON = 3;
175 static final int SNAPSHOT_VIEWSTATE = 4;
176 static final int SNAPSHOT_BACKGROUND = 5;
177 static final int SNAPSHOT_DATE_CREATED = 6;
178 static final int SNAPSHOT_VIEWSTATE_PATH = 7;
John Reckd8c74522011-06-14 08:45:00 -0700179
180 private SnapshotTab mTab;
181 private ContentResolver mContentResolver;
John Reck2b71d6d2012-04-18 17:42:06 -0700182 private Context mContext;
John Reckd8c74522011-06-14 08:45:00 -0700183
John Reck2b71d6d2012-04-18 17:42:06 -0700184 public LoadData(SnapshotTab t, Context context) {
John Reckd8c74522011-06-14 08:45:00 -0700185 mTab = t;
John Reck2b71d6d2012-04-18 17:42:06 -0700186 mContentResolver = context.getContentResolver();
187 mContext = context;
John Reckd8c74522011-06-14 08:45:00 -0700188 }
189
190 @Override
191 protected Cursor doInBackground(Void... params) {
192 long id = mTab.mSnapshotId;
193 Uri uri = ContentUris.withAppendedId(Snapshots.CONTENT_URI, id);
194 return mContentResolver.query(uri, PROJECTION, null, null, null);
195 }
196
John Reck2b71d6d2012-04-18 17:42:06 -0700197 private InputStream getInputStream(Cursor c) throws FileNotFoundException {
John Reck2b71d6d2012-04-18 17:42:06 -0700198 byte[] data = c.getBlob(SNAPSHOT_VIEWSTATE);
199 ByteArrayInputStream bis = new ByteArrayInputStream(data);
200 return bis;
201 }
202
John Reckd8c74522011-06-14 08:45:00 -0700203 @Override
204 protected void onPostExecute(Cursor result) {
205 try {
206 if (result.moveToFirst()) {
John Reck2b71d6d2012-04-18 17:42:06 -0700207 mTab.mCurrentState.mTitle = result.getString(SNAPSHOT_TITLE);
208 mTab.mCurrentState.mUrl = result.getString(SNAPSHOT_URL);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800209 mTab.mLiveUrl = result.getString(SNAPSHOT_URL);
John Reck2b71d6d2012-04-18 17:42:06 -0700210 byte[] favicon = result.getBlob(SNAPSHOT_FAVICON);
John Reckd8c74522011-06-14 08:45:00 -0700211 if (favicon != null) {
212 mTab.mCurrentState.mFavicon = BitmapFactory
213 .decodeByteArray(favicon, 0, favicon.length);
214 }
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800215 WebView web = mTab.getWebView();
John Reckd8c74522011-06-14 08:45:00 -0700216 if (web != null) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800217 String path = result.getString(SNAPSHOT_VIEWSTATE_PATH);
218 if (!TextUtils.isEmpty(path)) {
219 web.loadViewState(path);
220 } else {
221 InputStream ins = getInputStream(result);
222 GZIPInputStream stream = new GZIPInputStream(ins);
223 web.loadViewState(stream);
224 }
John Reckd8c74522011-06-14 08:45:00 -0700225 }
John Reck2b71d6d2012-04-18 17:42:06 -0700226 mTab.mBackgroundColor = result.getInt(SNAPSHOT_BACKGROUND);
227 mTab.mDateCreated = result.getLong(SNAPSHOT_DATE_CREATED);
John Reckd8c74522011-06-14 08:45:00 -0700228 mTab.mWebViewController.onPageFinished(mTab);
229 }
John Reck28263772011-10-11 17:13:42 -0700230 } catch (Exception e) {
231 Log.w(LOGTAG, "Failed to load view state, closing tab", e);
232 mTab.mWebViewController.closeTab(mTab);
John Reckd8c74522011-06-14 08:45:00 -0700233 } finally {
234 if (result != null) {
235 result.close();
236 }
237 mTab.mLoadTask = null;
238 }
239 }
240
241 }
John Reck1cf4b792011-07-26 10:22:22 -0700242
243 @Override
244 protected void persistThumbnail() {
John Recke91c7482011-08-23 14:04:29 -0700245 if (mIsLive) {
246 super.persistThumbnail();
247 }
John Reck1cf4b792011-07-26 10:22:22 -0700248 }
John Reckd8c74522011-06-14 08:45:00 -0700249}