1d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck/*
2d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * Copyright (C) 2011 The Android Open Source Project
3d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck *
4d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * you may not use this file except in compliance with the License.
6d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * You may obtain a copy of the License at
7d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck *
8d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck *
10d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * Unless required by applicable law or agreed to in writing, software
11d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * See the License for the specific language governing permissions and
14d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck * limitations under the License.
15d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck */
16d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckpackage com.android.browser;
17d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
18d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentResolver;
19d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentUris;
20d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.content.ContentValues;
212b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport android.content.Context;
22d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.database.Cursor;
23d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.graphics.BitmapFactory;
24d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.net.Uri;
25d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.os.AsyncTask;
261cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reckimport android.os.Bundle;
272b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport android.text.TextUtils;
288cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport android.util.Log;
29d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport android.webkit.WebView;
304d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixonimport android.webkit.WebViewClassic;
31d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
328cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport com.android.browser.provider.SnapshotProvider.Snapshots;
33d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
34d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckimport java.io.ByteArrayInputStream;
352b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.FileNotFoundException;
362b71d6dad1cbdc84da3eed140429a102971a1106John Reckimport java.io.InputStream;
37ef654f1dd80f55609060005342fc4f2cde62990cJohn Reckimport java.util.Map;
388cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reckimport java.util.zip.GZIPInputStream;
39d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
40d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
41d8c7452a7d8975a2d60414c5a33842b4a743e631John Reckpublic class SnapshotTab extends Tab {
42d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
438cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck    private static final String LOGTAG = "SnapshotTab";
448cc9235816ac9b3f1b3551d6234684f0455746dcJohn Reck
45d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private long mSnapshotId;
46d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private LoadData mLoadTask;
47d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private WebViewFactory mWebViewFactory;
48d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    private int mBackgroundColor;
49ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    private long mDateCreated;
50ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    private boolean mIsLive;
51d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
52d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public SnapshotTab(WebViewController wvcontroller, long snapshotId) {
531cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        super(wvcontroller, null, null);
54d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        mSnapshotId = snapshotId;
55d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        mWebViewFactory = mWebViewController.getWebViewFactory();
56ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        WebView web = mWebViewFactory.createWebView(false);
57ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        setWebView(web);
58d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        loadData();
59d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
60d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
61d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
62d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    void putInForeground() {
63d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        if (getWebView() == null) {
64d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            WebView web = mWebViewFactory.createWebView(false);
65d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            if (mBackgroundColor != 0) {
66d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                web.setBackgroundColor(mBackgroundColor);
67d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            }
68d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            setWebView(web);
69d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            loadData();
70d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
71d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        super.putInForeground();
72d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
73d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
74d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
75d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    void putInBackground() {
76d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        if (getWebView() == null) return;
77d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        super.putInBackground();
78d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
79d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
80d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    void loadData() {
81d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        if (mLoadTask == null) {
822b71d6dad1cbdc84da3eed140429a102971a1106John Reck            mLoadTask = new LoadData(this, mContext);
83d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            mLoadTask.execute();
84d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
85d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
86d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
87d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
88d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    void addChildTab(Tab child) {
89e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        if (mIsLive) {
90e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck            super.addChildTab(child);
91e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        } else {
92e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck            throw new IllegalStateException("Snapshot tabs cannot have child tabs!");
93e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        }
94d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
95d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
96d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
97d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public boolean isSnapshot() {
98ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return !mIsLive;
99d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
100d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
101d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public long getSnapshotId() {
102d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        return mSnapshotId;
103d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
104d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
105d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
106d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    public ContentValues createSnapshotValues() {
107e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        if (mIsLive) {
108e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck            return super.createSnapshotValues();
109e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        }
110d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        return null;
111d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
112d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
113d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    @Override
11480a5fbb2965a859e0ccc814c02b30434645044e7John Reck    public Bundle saveState() {
115e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        if (mIsLive) {
116e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck            return super.saveState();
117e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        }
1181cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck        return null;
119d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
120d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
121ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public long getDateCreated() {
122ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mDateCreated;
123ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
124ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
125ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    @Override
126ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void loadUrl(String url, Map<String, String> headers) {
127ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (!mIsLive) {
128ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mIsLive = true;
1294d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon            getWebViewClassic().clearViewState();
130ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
131ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        super.loadUrl(url, headers);
132ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
133ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
134ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    @Override
135ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoBack() {
136ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return super.canGoBack() || mIsLive;
137ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
138ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
139ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    @Override
140ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public boolean canGoForward() {
141ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        return mIsLive && super.canGoForward();
142ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
143ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
144ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    @Override
145ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    public void goBack() {
146ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        if (super.canGoBack()) {
147ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            super.goBack();
148ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        } else {
149ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            mIsLive = false;
150ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            getWebView().stopLoading();
151ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            loadData();
152ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck        }
153ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck    }
154ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck
155d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    static class LoadData extends AsyncTask<Void, Void, Cursor> {
156d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
157d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        static final String[] PROJECTION = new String[] {
158d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            Snapshots._ID, // 0
1592b71d6dad1cbdc84da3eed140429a102971a1106John Reck            Snapshots.URL, // 1
1602b71d6dad1cbdc84da3eed140429a102971a1106John Reck            Snapshots.TITLE, // 2
161d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            Snapshots.FAVICON, // 3
162d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            Snapshots.VIEWSTATE, // 4
163d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            Snapshots.BACKGROUND, // 5
164ef654f1dd80f55609060005342fc4f2cde62990cJohn Reck            Snapshots.DATE_CREATED, // 6
1652b71d6dad1cbdc84da3eed140429a102971a1106John Reck            Snapshots.VIEWSTATE_PATH, // 7
166d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        };
1672b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_ID = 0;
1682b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_URL = 1;
1692b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_TITLE = 2;
1702b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_FAVICON = 3;
1712b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_VIEWSTATE = 4;
1722b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_BACKGROUND = 5;
1732b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_DATE_CREATED = 6;
1742b71d6dad1cbdc84da3eed140429a102971a1106John Reck        static final int SNAPSHOT_VIEWSTATE_PATH = 7;
175d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
176d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        private SnapshotTab mTab;
177d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        private ContentResolver mContentResolver;
1782b71d6dad1cbdc84da3eed140429a102971a1106John Reck        private Context mContext;
179d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
1802b71d6dad1cbdc84da3eed140429a102971a1106John Reck        public LoadData(SnapshotTab t, Context context) {
181d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            mTab = t;
1822b71d6dad1cbdc84da3eed140429a102971a1106John Reck            mContentResolver = context.getContentResolver();
1832b71d6dad1cbdc84da3eed140429a102971a1106John Reck            mContext = context;
184d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
185d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
186d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        @Override
187d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        protected Cursor doInBackground(Void... params) {
188d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            long id = mTab.mSnapshotId;
189d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            Uri uri = ContentUris.withAppendedId(Snapshots.CONTENT_URI, id);
190d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            return mContentResolver.query(uri, PROJECTION, null, null, null);
191d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
192d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
1932b71d6dad1cbdc84da3eed140429a102971a1106John Reck        private InputStream getInputStream(Cursor c) throws FileNotFoundException {
1942b71d6dad1cbdc84da3eed140429a102971a1106John Reck            String path = c.getString(SNAPSHOT_VIEWSTATE_PATH);
1952b71d6dad1cbdc84da3eed140429a102971a1106John Reck            if (!TextUtils.isEmpty(path)) {
1962b71d6dad1cbdc84da3eed140429a102971a1106John Reck                return mContext.openFileInput(path);
1972b71d6dad1cbdc84da3eed140429a102971a1106John Reck            }
1982b71d6dad1cbdc84da3eed140429a102971a1106John Reck            byte[] data = c.getBlob(SNAPSHOT_VIEWSTATE);
1992b71d6dad1cbdc84da3eed140429a102971a1106John Reck            ByteArrayInputStream bis = new ByteArrayInputStream(data);
2002b71d6dad1cbdc84da3eed140429a102971a1106John Reck            return bis;
2012b71d6dad1cbdc84da3eed140429a102971a1106John Reck        }
2022b71d6dad1cbdc84da3eed140429a102971a1106John Reck
203d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        @Override
204d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        protected void onPostExecute(Cursor result) {
205d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            try {
206d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                if (result.moveToFirst()) {
2072b71d6dad1cbdc84da3eed140429a102971a1106John Reck                    mTab.mCurrentState.mTitle = result.getString(SNAPSHOT_TITLE);
2082b71d6dad1cbdc84da3eed140429a102971a1106John Reck                    mTab.mCurrentState.mUrl = result.getString(SNAPSHOT_URL);
2092b71d6dad1cbdc84da3eed140429a102971a1106John Reck                    byte[] favicon = result.getBlob(SNAPSHOT_FAVICON);
210d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    if (favicon != null) {
211d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                        mTab.mCurrentState.mFavicon = BitmapFactory
212d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                                .decodeByteArray(favicon, 0, favicon.length);
213d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    }
2144d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon                    WebViewClassic web = mTab.getWebViewClassic();
215d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    if (web != null) {
2162b71d6dad1cbdc84da3eed140429a102971a1106John Reck                        InputStream ins = getInputStream(result);
2172b71d6dad1cbdc84da3eed140429a102971a1106John Reck                        GZIPInputStream stream = new GZIPInputStream(ins);
218282637771aaffd93f29fd72bf5cd49dd82d24d0dJohn Reck                        web.loadViewState(stream);
219d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    }
2202b71d6dad1cbdc84da3eed140429a102971a1106John Reck                    mTab.mBackgroundColor = result.getInt(SNAPSHOT_BACKGROUND);
2212b71d6dad1cbdc84da3eed140429a102971a1106John Reck                    mTab.mDateCreated = result.getLong(SNAPSHOT_DATE_CREATED);
222d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    mTab.mWebViewController.onPageFinished(mTab);
223d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                }
224282637771aaffd93f29fd72bf5cd49dd82d24d0dJohn Reck            } catch (Exception e) {
225282637771aaffd93f29fd72bf5cd49dd82d24d0dJohn Reck                Log.w(LOGTAG, "Failed to load view state, closing tab", e);
226282637771aaffd93f29fd72bf5cd49dd82d24d0dJohn Reck                mTab.mWebViewController.closeTab(mTab);
227d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            } finally {
228d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                if (result != null) {
229d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                    result.close();
230d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                }
231d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck                mTab.mLoadTask = null;
232d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck            }
233d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck        }
234d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck
235d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck    }
2361cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck
2371cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    @Override
2381cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    protected void persistThumbnail() {
239e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        if (mIsLive) {
240e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck            super.persistThumbnail();
241e91c74859a4e5b319f52da4f61b0f5e6f60d9bd6John Reck        }
2421cf4b79a0020bc18c83ca8bde0e318ecd5252bc2John Reck    }
243d8c7452a7d8975a2d60414c5a33842b4a743e631John Reck}
244