| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.browser; |
| |
| import org.apache.http.HttpEntity; |
| import org.apache.http.HttpHost; |
| import org.apache.http.HttpResponse; |
| import org.apache.http.client.methods.HttpGet; |
| import org.apache.http.client.params.HttpClientParams; |
| import org.apache.http.conn.params.ConnRouteParams; |
| |
| import android.content.ContentResolver; |
| import android.content.ContentValues; |
| import android.content.Context; |
| import android.database.Cursor; |
| import android.graphics.Bitmap; |
| import android.graphics.BitmapFactory; |
| import android.net.Proxy; |
| import android.net.http.AndroidHttpClient; |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.os.Message; |
| import android.provider.BrowserContract; |
| import android.provider.BrowserContract.Images; |
| import android.webkit.WebView; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.InputStream; |
| |
| class DownloadTouchIcon extends AsyncTask<String, Void, Void> { |
| |
| private final ContentResolver mContentResolver; |
| private Cursor mCursor; |
| private final String mOriginalUrl; |
| private final String mUrl; |
| private final String mUserAgent; // Sites may serve a different icon to different UAs |
| private Message mMessage; |
| |
| private final Context mContext; |
| /* package */ Tab mTab; |
| |
| /** |
| * Use this ctor to store the touch icon in the bookmarks database for |
| * the originalUrl so we take account of redirects. Used when the user |
| * bookmarks a page from outside the bookmarks activity. |
| */ |
| public DownloadTouchIcon(Tab tab, Context ctx, ContentResolver cr, WebView view) { |
| mTab = tab; |
| mContext = ctx.getApplicationContext(); |
| mContentResolver = cr; |
| // Store these in case they change. |
| mOriginalUrl = view.getOriginalUrl(); |
| mUrl = view.getUrl(); |
| mUserAgent = view.getSettings().getUserAgentString(); |
| } |
| |
| /** |
| * Use this ctor to download the touch icon and update the bookmarks database |
| * entry for the given url. Used when the user creates a bookmark from |
| * within the bookmarks activity and there haven't been any redirects. |
| * TODO: Would be nice to set the user agent here so that there is no |
| * potential for the three different ctors here to return different icons. |
| */ |
| public DownloadTouchIcon(Context ctx, ContentResolver cr, String url) { |
| mTab = null; |
| mContext = ctx.getApplicationContext(); |
| mContentResolver = cr; |
| mOriginalUrl = null; |
| mUrl = url; |
| mUserAgent = null; |
| } |
| |
| /** |
| * Use this ctor to not store the touch icon in a database, rather add it to |
| * the passed Message's data bundle with the key |
| * {@link BrowserContract.Bookmarks#TOUCH_ICON} and then send the message. |
| */ |
| public DownloadTouchIcon(Context context, Message msg, String userAgent) { |
| mMessage = msg; |
| mContext = context.getApplicationContext(); |
| mContentResolver = null; |
| mOriginalUrl = null; |
| mUrl = null; |
| mUserAgent = userAgent; |
| } |
| |
| @Override |
| public Void doInBackground(String... values) { |
| if (mContentResolver != null) { |
| mCursor = Bookmarks.queryCombinedForUrl(mContentResolver, |
| mOriginalUrl, mUrl); |
| } |
| |
| boolean inDatabase = mCursor != null && mCursor.getCount() > 0; |
| |
| String url = values[0]; |
| |
| if (inDatabase || mMessage != null) { |
| AndroidHttpClient client = null; |
| HttpGet request = null; |
| |
| try { |
| client = AndroidHttpClient.newInstance(mUserAgent); |
| HttpHost httpHost = Proxy.getPreferredHttpHost(mContext, url); |
| if (httpHost != null) { |
| ConnRouteParams.setDefaultProxy(client.getParams(), httpHost); |
| } |
| |
| request = new HttpGet(url); |
| |
| // Follow redirects |
| HttpClientParams.setRedirecting(client.getParams(), true); |
| |
| HttpResponse response = client.execute(request); |
| if (response.getStatusLine().getStatusCode() == 200) { |
| HttpEntity entity = response.getEntity(); |
| if (entity != null) { |
| InputStream content = entity.getContent(); |
| if (content != null) { |
| Bitmap icon = BitmapFactory.decodeStream( |
| content, null, null); |
| if (inDatabase) { |
| storeIcon(icon); |
| } else if (mMessage != null) { |
| Bundle b = mMessage.getData(); |
| b.putParcelable(BrowserContract.Bookmarks.TOUCH_ICON, icon); |
| } |
| } |
| } |
| } |
| } catch (Exception ex) { |
| if (request != null) { |
| request.abort(); |
| } |
| } finally { |
| if (client != null) { |
| client.close(); |
| } |
| } |
| } |
| |
| if (mCursor != null) { |
| mCursor.close(); |
| } |
| |
| if (mMessage != null) { |
| mMessage.sendToTarget(); |
| } |
| |
| return null; |
| } |
| |
| @Override |
| protected void onCancelled() { |
| if (mCursor != null) { |
| mCursor.close(); |
| } |
| } |
| |
| private void storeIcon(Bitmap icon) { |
| // Do this first in case the download failed. |
| if (mTab != null) { |
| // Remove the touch icon loader from the BrowserActivity. |
| mTab.mTouchIconLoader = null; |
| } |
| |
| if (icon == null || mCursor == null || isCancelled()) { |
| return; |
| } |
| |
| if (mCursor.moveToFirst()) { |
| final ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| icon.compress(Bitmap.CompressFormat.PNG, 100, os); |
| |
| ContentValues values = new ContentValues(); |
| values.put(Images.TOUCH_ICON, os.toByteArray()); |
| |
| do { |
| values.put(Images.URL, mCursor.getString(0)); |
| mContentResolver.update(Images.CONTENT_URI, values, null, null); |
| } while (mCursor.moveToNext()); |
| } |
| } |
| } |