Home | History | Annotate | Download | only in browser
      1 /*
      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  */
     16 package com.android.browser;
     17 
     18 import android.content.ContentResolver;
     19 import android.content.ContentUris;
     20 import android.content.ContentValues;
     21 import android.content.Context;
     22 import android.database.Cursor;
     23 import android.graphics.BitmapFactory;
     24 import android.net.Uri;
     25 import android.os.AsyncTask;
     26 import android.os.Bundle;
     27 import android.text.TextUtils;
     28 import android.util.Log;
     29 import android.webkit.WebView;
     30 import android.webkit.WebViewClassic;
     31 
     32 import com.android.browser.provider.SnapshotProvider.Snapshots;
     33 
     34 import java.io.ByteArrayInputStream;
     35 import java.io.FileNotFoundException;
     36 import java.io.InputStream;
     37 import java.util.Map;
     38 import java.util.zip.GZIPInputStream;
     39 
     40 
     41 public class SnapshotTab extends Tab {
     42 
     43     private static final String LOGTAG = "SnapshotTab";
     44 
     45     private long mSnapshotId;
     46     private LoadData mLoadTask;
     47     private WebViewFactory mWebViewFactory;
     48     private int mBackgroundColor;
     49     private long mDateCreated;
     50     private boolean mIsLive;
     51 
     52     public SnapshotTab(WebViewController wvcontroller, long snapshotId) {
     53         super(wvcontroller, null, null);
     54         mSnapshotId = snapshotId;
     55         mWebViewFactory = mWebViewController.getWebViewFactory();
     56         WebView web = mWebViewFactory.createWebView(false);
     57         setWebView(web);
     58         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();
     78     }
     79 
     80     void loadData() {
     81         if (mLoadTask == null) {
     82             mLoadTask = new LoadData(this, mContext);
     83             mLoadTask.execute();
     84         }
     85     }
     86 
     87     @Override
     88     void addChildTab(Tab child) {
     89         if (mIsLive) {
     90             super.addChildTab(child);
     91         } else {
     92             throw new IllegalStateException("Snapshot tabs cannot have child tabs!");
     93         }
     94     }
     95 
     96     @Override
     97     public boolean isSnapshot() {
     98         return !mIsLive;
     99     }
    100 
    101     public long getSnapshotId() {
    102         return mSnapshotId;
    103     }
    104 
    105     @Override
    106     public ContentValues createSnapshotValues() {
    107         if (mIsLive) {
    108             return super.createSnapshotValues();
    109         }
    110         return null;
    111     }
    112 
    113     @Override
    114     public Bundle saveState() {
    115         if (mIsLive) {
    116             return super.saveState();
    117         }
    118         return null;
    119     }
    120 
    121     public long getDateCreated() {
    122         return mDateCreated;
    123     }
    124 
    125     @Override
    126     public void loadUrl(String url, Map<String, String> headers) {
    127         if (!mIsLive) {
    128             mIsLive = true;
    129             getWebViewClassic().clearViewState();
    130         }
    131         super.loadUrl(url, headers);
    132     }
    133 
    134     @Override
    135     public boolean canGoBack() {
    136         return super.canGoBack() || mIsLive;
    137     }
    138 
    139     @Override
    140     public boolean canGoForward() {
    141         return mIsLive && super.canGoForward();
    142     }
    143 
    144     @Override
    145     public void goBack() {
    146         if (super.canGoBack()) {
    147             super.goBack();
    148         } else {
    149             mIsLive = false;
    150             getWebView().stopLoading();
    151             loadData();
    152         }
    153     }
    154 
    155     static class LoadData extends AsyncTask<Void, Void, Cursor> {
    156 
    157         static final String[] PROJECTION = new String[] {
    158             Snapshots._ID, // 0
    159             Snapshots.URL, // 1
    160             Snapshots.TITLE, // 2
    161             Snapshots.FAVICON, // 3
    162             Snapshots.VIEWSTATE, // 4
    163             Snapshots.BACKGROUND, // 5
    164             Snapshots.DATE_CREATED, // 6
    165             Snapshots.VIEWSTATE_PATH, // 7
    166         };
    167         static final int SNAPSHOT_ID = 0;
    168         static final int SNAPSHOT_URL = 1;
    169         static final int SNAPSHOT_TITLE = 2;
    170         static final int SNAPSHOT_FAVICON = 3;
    171         static final int SNAPSHOT_VIEWSTATE = 4;
    172         static final int SNAPSHOT_BACKGROUND = 5;
    173         static final int SNAPSHOT_DATE_CREATED = 6;
    174         static final int SNAPSHOT_VIEWSTATE_PATH = 7;
    175 
    176         private SnapshotTab mTab;
    177         private ContentResolver mContentResolver;
    178         private Context mContext;
    179 
    180         public LoadData(SnapshotTab t, Context context) {
    181             mTab = t;
    182             mContentResolver = context.getContentResolver();
    183             mContext = context;
    184         }
    185 
    186         @Override
    187         protected Cursor doInBackground(Void... params) {
    188             long id = mTab.mSnapshotId;
    189             Uri uri = ContentUris.withAppendedId(Snapshots.CONTENT_URI, id);
    190             return mContentResolver.query(uri, PROJECTION, null, null, null);
    191         }
    192 
    193         private InputStream getInputStream(Cursor c) throws FileNotFoundException {
    194             String path = c.getString(SNAPSHOT_VIEWSTATE_PATH);
    195             if (!TextUtils.isEmpty(path)) {
    196                 return mContext.openFileInput(path);
    197             }
    198             byte[] data = c.getBlob(SNAPSHOT_VIEWSTATE);
    199             ByteArrayInputStream bis = new ByteArrayInputStream(data);
    200             return bis;
    201         }
    202 
    203         @Override
    204         protected void onPostExecute(Cursor result) {
    205             try {
    206                 if (result.moveToFirst()) {
    207                     mTab.mCurrentState.mTitle = result.getString(SNAPSHOT_TITLE);
    208                     mTab.mCurrentState.mUrl = result.getString(SNAPSHOT_URL);
    209                     byte[] favicon = result.getBlob(SNAPSHOT_FAVICON);
    210                     if (favicon != null) {
    211                         mTab.mCurrentState.mFavicon = BitmapFactory
    212                                 .decodeByteArray(favicon, 0, favicon.length);
    213                     }
    214                     WebViewClassic web = mTab.getWebViewClassic();
    215                     if (web != null) {
    216                         InputStream ins = getInputStream(result);
    217                         GZIPInputStream stream = new GZIPInputStream(ins);
    218                         web.loadViewState(stream);
    219                     }
    220                     mTab.mBackgroundColor = result.getInt(SNAPSHOT_BACKGROUND);
    221                     mTab.mDateCreated = result.getLong(SNAPSHOT_DATE_CREATED);
    222                     mTab.mWebViewController.onPageFinished(mTab);
    223                 }
    224             } catch (Exception e) {
    225                 Log.w(LOGTAG, "Failed to load view state, closing tab", e);
    226                 mTab.mWebViewController.closeTab(mTab);
    227             } finally {
    228                 if (result != null) {
    229                     result.close();
    230                 }
    231                 mTab.mLoadTask = null;
    232             }
    233         }
    234 
    235     }
    236 
    237     @Override
    238     protected void persistThumbnail() {
    239         if (mIsLive) {
    240             super.persistThumbnail();
    241         }
    242     }
    243 }
    244