blob: 7471bca938a6698d790ff774e146afcd53a6eb40 [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;
Vivek Sekhar46c3ec02014-10-09 17:28:57 -070023import android.graphics.Bitmap;
John Reckd8c74522011-06-14 08:45:00 -070024import android.graphics.BitmapFactory;
John Reckd8c74522011-06-14 08:45:00 -070025import android.net.Uri;
26import android.os.AsyncTask;
John Reck1cf4b792011-07-26 10:22:22 -070027import android.os.Bundle;
John Reck2b71d6d2012-04-18 17:42:06 -070028import android.text.TextUtils;
John Reck8cc92352011-07-06 17:41:52 -070029import android.util.Log;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080030import org.codeaurora.swe.WebView;
John Reckd8c74522011-06-14 08:45:00 -070031
Bijan Amirzada41242f22014-03-21 12:12:18 -070032import com.android.browser.provider.SnapshotProvider.Snapshots;
John Reckd8c74522011-06-14 08:45:00 -070033
34import java.io.ByteArrayInputStream;
John Reck2b71d6d2012-04-18 17:42:06 -070035import java.io.FileNotFoundException;
36import java.io.InputStream;
John Reckef654f12011-07-12 16:42:08 -070037import java.util.Map;
John Reck8cc92352011-07-06 17:41:52 -070038import java.util.zip.GZIPInputStream;
John Reckd8c74522011-06-14 08:45:00 -070039
40
41public class SnapshotTab extends Tab {
42
John Reck8cc92352011-07-06 17:41:52 -070043 private static final String LOGTAG = "SnapshotTab";
44
John Reckd8c74522011-06-14 08:45:00 -070045 private long mSnapshotId;
46 private LoadData mLoadTask;
47 private WebViewFactory mWebViewFactory;
John Reckd8c74522011-06-14 08:45:00 -070048 private int mBackgroundColor;
John Reckef654f12011-07-12 16:42:08 -070049 private long mDateCreated;
50 private boolean mIsLive;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080051 private String mLiveUrl;
Axesh R. Ajmerae6b11aa2015-03-16 18:20:41 -070052 private Bundle mSavedState;
53
54 // Used for saving and restoring each Tab
55 static final String SNAPSHOT_ID = "snapshotId";
Axesh R. Ajmera4b000312015-07-23 10:00:16 -070056 static final String ID = "ID";
John Reckd8c74522011-06-14 08:45:00 -070057
Axesh R. Ajmera4b000312015-07-23 10:00:16 -070058
59 public SnapshotTab(WebViewController wvcontroller,
60 long snapshotId,
61 Bundle state) {
62 super(wvcontroller, null, state);
John Reckd8c74522011-06-14 08:45:00 -070063 mSnapshotId = snapshotId;
64 mWebViewFactory = mWebViewController.getWebViewFactory();
John Reckef654f12011-07-12 16:42:08 -070065 WebView web = mWebViewFactory.createWebView(false);
66 setWebView(web);
John Reckd8c74522011-06-14 08:45:00 -070067 loadData();
68 }
69
70 @Override
71 void putInForeground() {
72 if (getWebView() == null) {
73 WebView web = mWebViewFactory.createWebView(false);
74 if (mBackgroundColor != 0) {
75 web.setBackgroundColor(mBackgroundColor);
76 }
77 setWebView(web);
78 loadData();
79 }
80 super.putInForeground();
81 }
82
83 @Override
84 void putInBackground() {
85 if (getWebView() == null) return;
86 super.putInBackground();
John Reckd8c74522011-06-14 08:45:00 -070087 }
88
89 void loadData() {
90 if (mLoadTask == null) {
John Reck2b71d6d2012-04-18 17:42:06 -070091 mLoadTask = new LoadData(this, mContext);
John Reckd8c74522011-06-14 08:45:00 -070092 mLoadTask.execute();
93 }
94 }
95
96 @Override
97 void addChildTab(Tab child) {
John Recke91c7482011-08-23 14:04:29 -070098 if (mIsLive) {
99 super.addChildTab(child);
100 } else {
101 throw new IllegalStateException("Snapshot tabs cannot have child tabs!");
102 }
John Reckd8c74522011-06-14 08:45:00 -0700103 }
104
105 @Override
106 public boolean isSnapshot() {
John Reckef654f12011-07-12 16:42:08 -0700107 return !mIsLive;
John Reckd8c74522011-06-14 08:45:00 -0700108 }
109
110 public long getSnapshotId() {
111 return mSnapshotId;
112 }
113
114 @Override
Vivek Sekhar46c3ec02014-10-09 17:28:57 -0700115 public ContentValues createSnapshotValues(Bitmap bm) {
John Recke91c7482011-08-23 14:04:29 -0700116 if (mIsLive) {
Vivek Sekhar46c3ec02014-10-09 17:28:57 -0700117 return super.createSnapshotValues(bm);
John Recke91c7482011-08-23 14:04:29 -0700118 }
John Reckd8c74522011-06-14 08:45:00 -0700119 return null;
120 }
121
122 @Override
John Reck80a5fbb2011-07-27 15:05:16 -0700123 public Bundle saveState() {
John Recke91c7482011-08-23 14:04:29 -0700124 if (mIsLive) {
125 return super.saveState();
126 }
Axesh R. Ajmerae6b11aa2015-03-16 18:20:41 -0700127
128 mSavedState = new Bundle();
Axesh R. Ajmera4b000312015-07-23 10:00:16 -0700129 mSavedState = super.saveState();
Axesh R. Ajmerae6b11aa2015-03-16 18:20:41 -0700130 mSavedState.putLong(SNAPSHOT_ID, mSnapshotId);
Axesh R. Ajmerae6b11aa2015-03-16 18:20:41 -0700131 return mSavedState;
John Reckd8c74522011-06-14 08:45:00 -0700132 }
133
John Reckef654f12011-07-12 16:42:08 -0700134 public long getDateCreated() {
135 return mDateCreated;
136 }
137
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800138 public String getLiveUrl() {
139 return mLiveUrl;
140 }
141
John Reckef654f12011-07-12 16:42:08 -0700142 @Override
143 public void loadUrl(String url, Map<String, String> headers) {
144 if (!mIsLive) {
145 mIsLive = true;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800146 getWebView().clearViewState();
John Reckef654f12011-07-12 16:42:08 -0700147 }
148 super.loadUrl(url, headers);
149 }
150
151 @Override
152 public boolean canGoBack() {
153 return super.canGoBack() || mIsLive;
154 }
155
156 @Override
157 public boolean canGoForward() {
158 return mIsLive && super.canGoForward();
159 }
160
161 @Override
162 public void goBack() {
163 if (super.canGoBack()) {
164 super.goBack();
165 } else {
166 mIsLive = false;
167 getWebView().stopLoading();
168 loadData();
169 }
170 }
171
John Reckd8c74522011-06-14 08:45:00 -0700172 static class LoadData extends AsyncTask<Void, Void, Cursor> {
173
174 static final String[] PROJECTION = new String[] {
175 Snapshots._ID, // 0
John Reck2b71d6d2012-04-18 17:42:06 -0700176 Snapshots.URL, // 1
177 Snapshots.TITLE, // 2
John Reckd8c74522011-06-14 08:45:00 -0700178 Snapshots.FAVICON, // 3
179 Snapshots.VIEWSTATE, // 4
180 Snapshots.BACKGROUND, // 5
John Reckef654f12011-07-12 16:42:08 -0700181 Snapshots.DATE_CREATED, // 6
John Reck2b71d6d2012-04-18 17:42:06 -0700182 Snapshots.VIEWSTATE_PATH, // 7
John Reckd8c74522011-06-14 08:45:00 -0700183 };
John Reck2b71d6d2012-04-18 17:42:06 -0700184 static final int SNAPSHOT_ID = 0;
185 static final int SNAPSHOT_URL = 1;
186 static final int SNAPSHOT_TITLE = 2;
187 static final int SNAPSHOT_FAVICON = 3;
188 static final int SNAPSHOT_VIEWSTATE = 4;
189 static final int SNAPSHOT_BACKGROUND = 5;
190 static final int SNAPSHOT_DATE_CREATED = 6;
191 static final int SNAPSHOT_VIEWSTATE_PATH = 7;
John Reckd8c74522011-06-14 08:45:00 -0700192
193 private SnapshotTab mTab;
194 private ContentResolver mContentResolver;
John Reck2b71d6d2012-04-18 17:42:06 -0700195 private Context mContext;
John Reckd8c74522011-06-14 08:45:00 -0700196
John Reck2b71d6d2012-04-18 17:42:06 -0700197 public LoadData(SnapshotTab t, Context context) {
John Reckd8c74522011-06-14 08:45:00 -0700198 mTab = t;
John Reck2b71d6d2012-04-18 17:42:06 -0700199 mContentResolver = context.getContentResolver();
200 mContext = context;
John Reckd8c74522011-06-14 08:45:00 -0700201 }
202
203 @Override
204 protected Cursor doInBackground(Void... params) {
205 long id = mTab.mSnapshotId;
206 Uri uri = ContentUris.withAppendedId(Snapshots.CONTENT_URI, id);
207 return mContentResolver.query(uri, PROJECTION, null, null, null);
208 }
209
John Reck2b71d6d2012-04-18 17:42:06 -0700210 private InputStream getInputStream(Cursor c) throws FileNotFoundException {
John Reck2b71d6d2012-04-18 17:42:06 -0700211 byte[] data = c.getBlob(SNAPSHOT_VIEWSTATE);
212 ByteArrayInputStream bis = new ByteArrayInputStream(data);
213 return bis;
214 }
215
John Reckd8c74522011-06-14 08:45:00 -0700216 @Override
217 protected void onPostExecute(Cursor result) {
218 try {
219 if (result.moveToFirst()) {
John Reck2b71d6d2012-04-18 17:42:06 -0700220 mTab.mCurrentState.mTitle = result.getString(SNAPSHOT_TITLE);
221 mTab.mCurrentState.mUrl = result.getString(SNAPSHOT_URL);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800222 mTab.mLiveUrl = result.getString(SNAPSHOT_URL);
John Reck2b71d6d2012-04-18 17:42:06 -0700223 byte[] favicon = result.getBlob(SNAPSHOT_FAVICON);
John Reckd8c74522011-06-14 08:45:00 -0700224 if (favicon != null) {
225 mTab.mCurrentState.mFavicon = BitmapFactory
226 .decodeByteArray(favicon, 0, favicon.length);
227 }
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800228 WebView web = mTab.getWebView();
John Reckd8c74522011-06-14 08:45:00 -0700229 if (web != null) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800230 String path = result.getString(SNAPSHOT_VIEWSTATE_PATH);
231 if (!TextUtils.isEmpty(path)) {
232 web.loadViewState(path);
233 } else {
234 InputStream ins = getInputStream(result);
235 GZIPInputStream stream = new GZIPInputStream(ins);
236 web.loadViewState(stream);
237 }
John Reckd8c74522011-06-14 08:45:00 -0700238 }
John Reck2b71d6d2012-04-18 17:42:06 -0700239 mTab.mBackgroundColor = result.getInt(SNAPSHOT_BACKGROUND);
240 mTab.mDateCreated = result.getLong(SNAPSHOT_DATE_CREATED);
John Reckd8c74522011-06-14 08:45:00 -0700241 mTab.mWebViewController.onPageFinished(mTab);
242 }
John Reck28263772011-10-11 17:13:42 -0700243 } catch (Exception e) {
244 Log.w(LOGTAG, "Failed to load view state, closing tab", e);
245 mTab.mWebViewController.closeTab(mTab);
John Reckd8c74522011-06-14 08:45:00 -0700246 } finally {
247 if (result != null) {
248 result.close();
249 }
250 mTab.mLoadTask = null;
251 }
252 }
253
254 }
John Reck1cf4b792011-07-26 10:22:22 -0700255
256 @Override
257 protected void persistThumbnail() {
John Recke91c7482011-08-23 14:04:29 -0700258 if (mIsLive) {
259 super.persistThumbnail();
260 }
John Reck1cf4b792011-07-26 10:22:22 -0700261 }
John Reckd8c74522011-06-14 08:45:00 -0700262}