blob: 99925dc0667bf5353c38501aef3b319289419294 [file] [log] [blame]
Patrick Scott3918d442009-08-04 13:22:29 -04001/*
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
17package com.android.browser;
18
19import android.content.ContentResolver;
20import android.content.ContentUris;
21import android.content.ContentValues;
22import android.database.Cursor;
23import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
Dianne Hackborn385effd2010-02-24 20:03:04 -080025import android.net.http.AndroidHttpClient;
Patrick Scott3918d442009-08-04 13:22:29 -040026import android.os.AsyncTask;
Ben Murdoche322f562010-07-01 12:21:19 +010027import android.os.Bundle;
28import android.os.Message;
Patrick Scott3918d442009-08-04 13:22:29 -040029import android.provider.Browser;
30import android.webkit.WebView;
31
32import org.apache.http.HttpEntity;
33import org.apache.http.HttpResponse;
34import org.apache.http.client.methods.HttpGet;
35import org.apache.http.client.params.HttpClientParams;
36
37import java.io.ByteArrayOutputStream;
38import java.io.IOException;
39import java.io.InputStream;
40
Patrick Scotta74f6962009-11-10 13:06:47 -050041class DownloadTouchIcon extends AsyncTask<String, Void, Void> {
Patrick Scott3918d442009-08-04 13:22:29 -040042 private final ContentResolver mContentResolver;
Leon Scrogginsc8393d92010-04-23 14:58:16 -040043 private Cursor mCursor;
Patrick Scott3918d442009-08-04 13:22:29 -040044 private final String mOriginalUrl;
45 private final String mUrl;
Ben Murdoche322f562010-07-01 12:21:19 +010046 private final String mUserAgent; // Sites may serve a different icon to different UAs
47 private Message mMessage;
48
Grace Kloba22ac16e2009-10-07 18:00:23 -070049 /* package */ Tab mTab;
Patrick Scott3918d442009-08-04 13:22:29 -040050
Ben Murdoche322f562010-07-01 12:21:19 +010051 /**
52 * Use this ctor to store the touch icon in the bookmarks database for
53 * the originalUrl so we take account of redirects. Used when the user
54 * bookmarks a page from outside the bookmarks activity.
55 */
Leon Scrogginsc8393d92010-04-23 14:58:16 -040056 public DownloadTouchIcon(Tab tab, ContentResolver cr, WebView view) {
Grace Kloba22ac16e2009-10-07 18:00:23 -070057 mTab = tab;
Patrick Scott3918d442009-08-04 13:22:29 -040058 mContentResolver = cr;
Patrick Scott3918d442009-08-04 13:22:29 -040059 // Store these in case they change.
60 mOriginalUrl = view.getOriginalUrl();
61 mUrl = view.getUrl();
62 mUserAgent = view.getSettings().getUserAgentString();
63 }
64
Ben Murdoche322f562010-07-01 12:21:19 +010065 /**
66 * Use this ctor to download the touch icon and update the bookmarks database
67 * entry for the given url. Used when the user creates a bookmark from
68 * within the bookmarks activity and there haven't been any redirects.
69 * TODO: Would be nice to set the user agent here so that there is no
70 * potential for the three different ctors here to return different icons.
71 */
Leon Scrogginsc8393d92010-04-23 14:58:16 -040072 public DownloadTouchIcon(ContentResolver cr, String url) {
Grace Kloba22ac16e2009-10-07 18:00:23 -070073 mTab = null;
Patrick Scott3918d442009-08-04 13:22:29 -040074 mContentResolver = cr;
Patrick Scott3918d442009-08-04 13:22:29 -040075 mOriginalUrl = null;
76 mUrl = url;
77 mUserAgent = null;
78 }
79
Ben Murdoche322f562010-07-01 12:21:19 +010080 /**
81 * Use this ctor to not store the touch icon in a database, rather add it to
82 * the passed Message's data bundle with the key "touchIcon" and then send
83 * the message.
84 */
85 public DownloadTouchIcon(Message msg, String userAgent) {
86 mMessage = msg;
87 mContentResolver = null;
88 mOriginalUrl = null;
89 mUrl = null;
90 mUserAgent = userAgent;
91 }
92
Patrick Scott3918d442009-08-04 13:22:29 -040093 @Override
Patrick Scotta74f6962009-11-10 13:06:47 -050094 public Void doInBackground(String... values) {
Ben Murdoche322f562010-07-01 12:21:19 +010095 if (mContentResolver != null) {
96 mCursor = BrowserBookmarksAdapter.queryBookmarksForUrl(mContentResolver,
97 mOriginalUrl, mUrl, true);
98 }
Patrick Scott3918d442009-08-04 13:22:29 -040099
Ben Murdoche322f562010-07-01 12:21:19 +0100100 boolean inBookmarksDatabase = mCursor != null && mCursor.getCount() > 0;
101
102 String url = values[0];
103
104 if (inBookmarksDatabase || mMessage != null) {
105 AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent);
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400106 HttpGet request = new HttpGet(url);
Patrick Scott3918d442009-08-04 13:22:29 -0400107
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400108 // Follow redirects
109 HttpClientParams.setRedirecting(client.getParams(), true);
Patrick Scott3918d442009-08-04 13:22:29 -0400110
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400111 try {
112 HttpResponse response = client.execute(request);
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400113 if (response.getStatusLine().getStatusCode() == 200) {
114 HttpEntity entity = response.getEntity();
115 if (entity != null) {
116 InputStream content = entity.getContent();
117 if (content != null) {
118 Bitmap icon = BitmapFactory.decodeStream(
119 content, null, null);
Ben Murdoche322f562010-07-01 12:21:19 +0100120 if (inBookmarksDatabase) {
121 storeIcon(icon);
122 } else if (mMessage != null) {
123 Bundle b = mMessage.getData();
124 b.putParcelable("touchIcon", icon);
125 }
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400126 }
Patrick Scott3918d442009-08-04 13:22:29 -0400127 }
128 }
Leon Scrogginsc8393d92010-04-23 14:58:16 -0400129 } catch (IllegalArgumentException ex) {
130 request.abort();
131 } catch (IOException ex) {
132 request.abort();
133 } finally {
134 client.close();
Patrick Scott3918d442009-08-04 13:22:29 -0400135 }
Patrick Scott3918d442009-08-04 13:22:29 -0400136 }
Ben Murdoche322f562010-07-01 12:21:19 +0100137
Patrick Scott8e9fe322010-03-04 14:29:31 -0500138 if (mCursor != null) {
139 mCursor.close();
140 }
Ben Murdoche322f562010-07-01 12:21:19 +0100141
142 if (mMessage != null) {
143 mMessage.sendToTarget();
144 }
145
Patrick Scott3918d442009-08-04 13:22:29 -0400146 return null;
147 }
148
149 @Override
Patrick Scott59ce8302009-09-18 16:29:38 -0400150 protected void onCancelled() {
151 if (mCursor != null) {
152 mCursor.close();
153 }
154 }
155
Patrick Scotta74f6962009-11-10 13:06:47 -0500156 private void storeIcon(Bitmap icon) {
Patrick Scott59ce8302009-09-18 16:29:38 -0400157 // Do this first in case the download failed.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700158 if (mTab != null) {
Patrick Scott59ce8302009-09-18 16:29:38 -0400159 // Remove the touch icon loader from the BrowserActivity.
Grace Kloba22ac16e2009-10-07 18:00:23 -0700160 mTab.mTouchIconLoader = null;
Patrick Scott59ce8302009-09-18 16:29:38 -0400161 }
162
163 if (icon == null || mCursor == null || isCancelled()) {
Patrick Scott3918d442009-08-04 13:22:29 -0400164 return;
165 }
Patrick Scott59ce8302009-09-18 16:29:38 -0400166
Patrick Scott3918d442009-08-04 13:22:29 -0400167 final ByteArrayOutputStream os = new ByteArrayOutputStream();
168 icon.compress(Bitmap.CompressFormat.PNG, 100, os);
169 ContentValues values = new ContentValues();
170 values.put(Browser.BookmarkColumns.TOUCH_ICON,
171 os.toByteArray());
172
173 if (mCursor.moveToFirst()) {
174 do {
175 mContentResolver.update(ContentUris.withAppendedId(
176 Browser.BOOKMARKS_URI, mCursor.getInt(0)),
177 values, null, null);
178 } while (mCursor.moveToNext());
179 }
Patrick Scott3918d442009-08-04 13:22:29 -0400180 }
181}