• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 
17 package com.android.browser;
18 
19 import java.io.IOException;
20 import java.net.HttpURLConnection;
21 import java.net.URL;
22 
23 import android.content.ContentResolver;
24 import android.content.ContentValues;
25 import android.content.Context;
26 import android.database.Cursor;
27 import android.graphics.Bitmap;
28 import android.graphics.BitmapFactory;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.os.Message;
32 import android.provider.BrowserContract;
33 import android.provider.BrowserContract.Images;
34 import android.webkit.WebView;
35 
36 import java.io.ByteArrayOutputStream;
37 import java.io.InputStream;
38 
39 class DownloadTouchIcon extends AsyncTask<String, Void, Void> {
40 
41     private final ContentResolver mContentResolver;
42     private Cursor mCursor;
43     private final String mOriginalUrl;
44     private final String mUrl;
45     private final String mUserAgent; // Sites may serve a different icon to different UAs
46     private Message mMessage;
47 
48     /* package */ Tab mTab;
49 
50     /**
51      * Use this ctor to store the touch icon in the bookmarks database for
52      * the originalUrl so we take account of redirects. Used when the user
53      * bookmarks a page from outside the bookmarks activity.
54      */
DownloadTouchIcon(Tab tab, ContentResolver cr, WebView view)55     public DownloadTouchIcon(Tab tab, ContentResolver cr, WebView view) {
56         mTab = tab;
57         mContentResolver = cr;
58         // Store these in case they change.
59         mOriginalUrl = view.getOriginalUrl();
60         mUrl = view.getUrl();
61         mUserAgent = view.getSettings().getUserAgentString();
62     }
63 
64     /**
65      * Use this ctor to download the touch icon and update the bookmarks database
66      * entry for the given url. Used when the user creates a bookmark from
67      * within the bookmarks activity and there haven't been any redirects.
68      * TODO: Would be nice to set the user agent here so that there is no
69      * potential for the three different ctors here to return different icons.
70      */
DownloadTouchIcon(ContentResolver cr, String url)71     public DownloadTouchIcon(ContentResolver cr, String url) {
72         mTab = null;
73         mContentResolver = cr;
74         mOriginalUrl = null;
75         mUrl = url;
76         mUserAgent = null;
77     }
78 
79     /**
80      * Use this ctor to not store the touch icon in a database, rather add it to
81      * the passed Message's data bundle with the key
82      * {@link BrowserContract.Bookmarks#TOUCH_ICON} and then send the message.
83      */
DownloadTouchIcon(Message msg, String userAgent)84     public DownloadTouchIcon(Message msg, String userAgent) {
85         mMessage = msg;
86         mContentResolver = null;
87         mOriginalUrl = null;
88         mUrl = null;
89         mUserAgent = userAgent;
90     }
91 
92     @Override
doInBackground(String... values)93     public Void doInBackground(String... values) {
94         if (mContentResolver != null) {
95             mCursor = Bookmarks.queryCombinedForUrl(mContentResolver,
96                     mOriginalUrl, mUrl);
97         }
98 
99         boolean inDatabase = mCursor != null && mCursor.getCount() > 0;
100 
101         if (inDatabase || mMessage != null) {
102             HttpURLConnection connection = null;
103             try {
104                 URL url = new URL(values[0]);
105                 connection = (HttpURLConnection) url.openConnection();
106                 if (mUserAgent != null) {
107                     connection.addRequestProperty("User-Agent", mUserAgent);
108                 }
109 
110                 if (connection.getResponseCode() == 200) {
111                     InputStream content = connection.getInputStream();
112                     Bitmap icon = null;
113                     try {
114                         icon = BitmapFactory.decodeStream(
115                                 content, null, null);
116                     } finally {
117                         try {
118                             content.close();
119                         } catch (IOException ignored) {
120                         }
121                     }
122 
123                     if (inDatabase) {
124                         storeIcon(icon);
125                     } else if (mMessage != null) {
126                         Bundle b = mMessage.getData();
127                         b.putParcelable(BrowserContract.Bookmarks.TOUCH_ICON, icon);
128                     }
129                 }
130             } catch (IOException ignored) {
131             } finally {
132                 if (connection != null) {
133                     connection.disconnect();
134                 }
135             }
136         }
137 
138         if (mCursor != null) {
139             mCursor.close();
140         }
141 
142         if (mMessage != null) {
143             mMessage.sendToTarget();
144         }
145 
146         return null;
147     }
148 
149     @Override
onCancelled()150     protected void onCancelled() {
151         if (mCursor != null) {
152             mCursor.close();
153         }
154     }
155 
storeIcon(Bitmap icon)156     private void storeIcon(Bitmap icon) {
157         // Do this first in case the download failed.
158         if (mTab != null) {
159             // Remove the touch icon loader from the BrowserActivity.
160             mTab.mTouchIconLoader = null;
161         }
162 
163         if (icon == null || mCursor == null || isCancelled()) {
164             return;
165         }
166 
167         if (mCursor.moveToFirst()) {
168             final ByteArrayOutputStream os = new ByteArrayOutputStream();
169             icon.compress(Bitmap.CompressFormat.PNG, 100, os);
170 
171             ContentValues values = new ContentValues();
172             values.put(Images.TOUCH_ICON, os.toByteArray());
173 
174             do {
175                 values.put(Images.URL, mCursor.getString(0));
176                 mContentResolver.update(Images.CONTENT_URI, values, null, null);
177             } while (mCursor.moveToNext());
178         }
179     }
180 }
181