/*
* Copyright (C) 2005-2009 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC Remote; see the file license. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
package org.xbmc.android.remote.business;
import org.xbmc.api.business.DataResponse;
import org.xbmc.api.business.INotifiableManager;
import org.xbmc.api.object.ICoverArt;
import org.xbmc.api.presentation.INotifiableController;
import org.xbmc.api.type.MediaType;
import org.xbmc.api.type.ThumbSize;
import org.xbmc.httpapi.WifiStateException;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
/**
* This thread asynchronously downloads thumbs from XBMC and returns them as
* Bitmap.
*
* When downloaded, the thumb is automatically saved to the memory- and disk-
* cache for further usage.
*
* @author Team XBMC
*/
public class DownloadThread extends AbstractThread {
/**
* Singleton instance of this thread
*/
protected static DownloadThread sHttpApiThread;
private static final String TAG = "DownloadThread";
private static final boolean DEBUG = AbstractManager.DEBUG;
/**
* Constructor is protected, use get().
*/
protected DownloadThread() {
super("HTTP API Network Thread");
}
/**
* Asynchronously downloads a thumb from XBMC and stores it locally.
*
* @param response
* Response object
* @param cover
* Which cover to download
* @param thumbSize
* Which size to return
*/
public void getCover(final DataResponse<Bitmap> response,
final ICoverArt cover, final int thumbSize,
final INotifiableController controller,
final INotifiableManager manager, final Context context) {
mHandler.post(new Runnable() {
public void run() {
if (cover != null) {
if (DEBUG)
Log.i(TAG, "Downloading cover " + cover);
/*
* it can happen that the same cover is queued consecutively
* several times. that's why we check both the disk cache
* and memory cache if the cover is not already available
* from a previously queued download.
*/
if (thumbSize < ThumbSize.BIG
&& MemCacheThread.isInCache(cover, thumbSize)) { // we're
// optimistic,
// let's
// check
// the
// memory
// first.
if (DEBUG)
Log.i(TAG,
"Cover is now already in mem cache, directly returning...");
response.value = MemCacheThread.getCover(cover,
thumbSize);
done(controller, response);
} else if (thumbSize < ThumbSize.BIG
&& DiskCacheThread.isInCache(cover, thumbSize)) {
if (DEBUG)
Log.i(TAG,
"Cover is not in mem cache anymore but still on disk, directly returning...");
response.value = DiskCacheThread.getCover(cover,
thumbSize);
done(controller, response);
} else {
download(response, cover, thumbSize, controller,
manager, context, true);
}
} else {
done(controller, response);
}
}
});
}
/**
* Synchonously downloads a thumb from XBMC and stores it locally.
*
* @param response
* Response object, can be null.
* @param cover
* Cover to download
* @param thumbSize
* Size to return to response object
* @param controller
* Controller to be announced, can be null.
* @param manager
* Manager is needed to obtain different managers for cache
* access
* @param context
* Context is needed for obtaining other manager instances
* @return True if cover was downloaded successfully, false otherwise.
*/
public static boolean download(final DataResponse<Bitmap> response,
final ICoverArt cover, final int thumbSize,
final INotifiableController controller,
final INotifiableManager manager, final Context context,
final boolean addToMemCache) {
if (DEBUG)
Log.i(TAG, "Download START..");
Bitmap bitmap = null;
final boolean success;
switch (cover.getMediaType()) {
case MediaType.MUSIC:
try {
ManagerFactory.getMusicManager(controller).downloadCover(response,
cover, thumbSize, context);
bitmap = response.value;
} catch (WifiStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case MediaType.VIDEO_MOVIE:
case MediaType.VIDEO:
try {
ManagerFactory.getVideoManager(controller).downloadCover(response, cover, thumbSize, context);
bitmap = response.value;
} catch (WifiStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case MediaType.VIDEO_TVEPISODE:
case MediaType.VIDEO_TVSEASON:
case MediaType.VIDEO_TVSHOW:
try {
ManagerFactory.getTvManager(controller).downloadCover(response, cover, thumbSize, context);
bitmap = response.value;
} catch (WifiStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case MediaType.PICTURES:
done(controller, response);
break;
default:
done(controller, response);
break;
}
if (DEBUG)
Log.i(TAG, "Download END.");
if (bitmap != null) {
// add to disk cache
final Bitmap v = DiskCacheThread.addCoverToCache(cover, bitmap,
thumbSize);
// add to mem cache
if (addToMemCache) {
MemCacheThread.addCoverToCache(cover, v, thumbSize);
}
if (response != null) {
response.value = v;
}
if (DEBUG)
Log.i(TAG, "Done");
success = true;
} else {
if (addToMemCache) {
// still add null value to mem cache so we don't try to fetch it
// again
if (DEBUG)
Log.i(TAG,
"Adding null-value ("
+ cover.getCrc()
+ ") to mem cache in order to block future downloads");
MemCacheThread.addCoverToCache(cover, null, 0);
}
success = false;
}
done(controller, response);
return success;
}
/**
* Returns an instance of this thread. Spawns if necessary.
*
* @return
*/
public static DownloadThread get() {
if (sHttpApiThread == null) {
sHttpApiThread = new DownloadThread();
sHttpApiThread.start();
// thread must be entirely started
waitForStartup(sHttpApiThread);
}
return sHttpApiThread;
}
public static synchronized void quit() {
if (sHttpApiThread != null) {
sHttpApiThread.mHandler.getLooper().quit();
sHttpApiThread = null;
}
}
}