@ -1,69 +1,91 @@
@@ -1,69 +1,91 @@
package acr.browser.lightning.async ;
package acr.browser.lightning.view ;
import android.app.Application ;
import android.graphics.Bitmap ;
import android.graphics.BitmapFactory ;
import android.net.Uri ;
import android.os.AsyncTask ;
import android.support.annotation.NonNull ;
import android.support.annotation.Nullable ;
import android.util.Log ;
import android.widget.ImageView ;
import com.anthonycr.bonsai.Schedulers ;
import com.anthonycr.bonsai.Single ;
import com.anthonycr.bonsai.SingleAction ;
import com.anthonycr.bonsai.SingleSubscriber ;
import java.io.File ;
import java.io.FileOutputStream ;
import java.io.InputStream ;
import java.lang.ref.WeakReference ;
import java.net.HttpURLConnection ;
import java.net.URL ;
import javax.inject.Inject ;
import acr.browser.lightning.app.BrowserApp ;
import acr.browser.lightning.constant.Constants ;
import acr.browser.lightning.database.HistoryItem ;
import acr.browser.lightning.utils.Utils ;
public class ImageDownloadTask extends AsyncTask < Void , Void , Bitmap > {
private static final String TAG = ImageDownloadTask . class . getSimpleName ( ) ;
@NonNull private final WeakReference < ImageView > mFaviconImage ;
@NonNull private final Application mContext ;
@NonNull private final HistoryItem mWeb ;
private final String mUrl ;
@NonNull private final Bitmap mDefaultBitmap ;
public ImageDownloadTask ( @NonNull ImageView bmImage ,
@NonNull HistoryItem web ,
@NonNull Bitmap defaultBitmap ,
@NonNull Application context ) {
// Set a tag on the ImageView so we know if the view
// has gone out of scope and should not be used
bmImage . setTag ( web . getUrl ( ) . hashCode ( ) ) ;
this . mFaviconImage = new WeakReference < > ( bmImage ) ;
this . mWeb = web ;
this . mUrl = web . getUrl ( ) ;
this . mDefaultBitmap = defaultBitmap ;
this . mContext = context ;
/ * *
* An ImageDownloader that creates image
* loading requests on demand .
* /
public class ImageDownloader {
private static final String TAG = "ImageDownloader" ;
@Inject Application mApp ;
@NonNull private Bitmap mDefaultBitmap ;
public ImageDownloader ( @NonNull Bitmap defaultBitmap ) {
mDefaultBitmap = defaultBitmap ;
BrowserApp . getAppComponent ( ) . inject ( this ) ;
}
/ * *
* Creates a new image request for the given url .
* Emits the bitmap associated with that url , or
* the default bitmap if none was found .
*
* @param url the url for which to retrieve the bitmap .
* @return a single that emits the bitmap that was found .
* /
@NonNull
public Single < Bitmap > newImageRequest ( @Nullable final String url ) {
return Single . create ( new SingleAction < Bitmap > ( ) {
@Override
public void onSubscribe ( @NonNull SingleSubscriber < Bitmap > subscriber ) {
Bitmap favicon = retrieveBitmap ( mApp , mDefaultBitmap , url ) ;
Bitmap paddedFavicon = Utils . padFavicon ( favicon ) ;
subscriber . onItem ( paddedFavicon ) ;
subscriber . onComplete ( ) ;
}
} ) ;
}
@NonNull
@Override
protected Bitmap doInBackground ( Void . . . params ) {
Bitmap mIcon = null ;
private static Bitmap retrieveBitmap ( @NonNull Application app ,
@NonNull Bitmap defaultBitmap ,
@Nullable String url ) {
// unique path for each url that is bookmarked.
if ( mUrl = = null ) {
return mDefaultBitmap ;
if ( u rl = = null ) {
return d efaultBitmap;
}
File cache = mContext . getCacheDir ( ) ;
final Uri uri = Uri . parse ( mUrl ) ;
if ( uri . getHost ( ) = = null | | uri . getScheme ( ) = = null ) {
return mDefaultBitmap ;
Bitmap icon = null ;
File cache = app . getCacheDir ( ) ;
final Uri uri = Uri . parse ( url ) ;
if ( uri . getHost ( ) = = null | | uri . getScheme ( ) = = null | | Constants . FILE . startsWith ( uri . getScheme ( ) ) ) {
return defaultBitmap ;
}
final String hash = String . valueOf ( uri . getHost ( ) . hashCode ( ) ) ;
final File image = new File ( cache , hash + ".png" ) ;
final String urlDisplay = uri . getScheme ( ) + "://" + uri . getHost ( ) + "/favicon.ico" ;
if ( Constants . FILE . startsWith ( uri . getScheme ( ) ) ) {
return mDefaultBitmap ;
}
// checks to see if the image exists
if ( ! image . exists ( ) ) {
FileOutputStream fos = null ;
@ -79,12 +101,12 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
@@ -79,12 +101,12 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
in = connection . getInputStream ( ) ;
if ( in ! = null ) {
mI con = BitmapFactory . decodeStream ( in ) ;
i con = BitmapFactory . decodeStream ( in ) ;
}
// ...and cache it
if ( mI con ! = null ) {
if ( i con ! = null ) {
fos = new FileOutputStream ( image ) ;
mI con. compress ( Bitmap . CompressFormat . PNG , 100 , fos ) ;
i con. compress ( Bitmap . CompressFormat . PNG , 100 , fos ) ;
fos . flush ( ) ;
Log . d ( Constants . TAG , "Downloaded: " + urlDisplay ) ;
}
@ -97,9 +119,10 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
@@ -97,9 +119,10 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
}
} else {
// if it exists, retrieve it from the cache
mI con = BitmapFactory . decodeFile ( image . getPath ( ) ) ;
i con = BitmapFactory . decodeFile ( image . getPath ( ) ) ;
}
if ( mIcon = = null ) {
if ( icon = = null ) {
InputStream in = null ;
FileOutputStream fos = null ;
try {
@ -113,12 +136,12 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
@@ -113,12 +136,12 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
in = connection . getInputStream ( ) ;
if ( in ! = null ) {
mI con = BitmapFactory . decodeStream ( in ) ;
i con = BitmapFactory . decodeStream ( in ) ;
}
// ...and cache it
if ( mI con ! = null ) {
if ( i con ! = null ) {
fos = new FileOutputStream ( image ) ;
mI con. compress ( Bitmap . CompressFormat . PNG , 100 , fos ) ;
i con. compress ( Bitmap . CompressFormat . PNG , 100 , fos ) ;
fos . flush ( ) ;
}
@ -129,28 +152,11 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
@@ -129,28 +152,11 @@ public class ImageDownloadTask extends AsyncTask<Void, Void, Bitmap> {
Utils . close ( fos ) ;
}
}
if ( mIcon = = null ) {
return mDefaultBitmap ;
} else {
return mIcon ;
}
}
@Override
protected void onPostExecute ( Bitmap bitmap ) {
super . onPostExecute ( bitmap ) ;
AsyncExecutor . getInstance ( ) . notifyThreadFinish ( ) ;
final Bitmap fav = Utils . padFavicon ( bitmap ) ;
final ImageView view = mFaviconImage . get ( ) ;
if ( view ! = null & & view . getTag ( ) . equals ( mWeb . getUrl ( ) . hashCode ( ) ) ) {
Schedulers . main ( ) . execute ( new Runnable ( ) {
@Override
public void run ( ) {
view . setImageBitmap ( fav ) ;
}
} ) ;
if ( icon = = null ) {
return defaultBitmap ;
} else {
return icon ;
}
mWeb . setBitmap ( fav ) ;
}
}