/*
* 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
*/
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 {
bitmap = music(manager, context).getCover(manager, cover, thumbSize);
} catch (WifiStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case MediaType.VIDEO_MOVIE:
case MediaType.VIDEO:
try {
bitmap = video(manager, context).getCover(manager, cover, thumbSize);
} catch (WifiStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
break;
case MediaType.VIDEO_TVEPISODE:
case MediaType.VIDEO_TVSEASON:
case MediaType.VIDEO_TVSHOW:
try {
bitmap = tvshow(manager, context).getCover(manager, cover, thumbSize);
} 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;
}
}
}