/* * 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 java.io.File; import org.xbmc.android.util.Crc32; import org.xbmc.android.util.ImportUtilities; import org.xbmc.api.business.DataResponse; import org.xbmc.api.object.ICoverArt; import org.xbmc.api.presentation.INotifiableController; import org.xbmc.api.type.MediaType; import android.graphics.Bitmap; import android.graphics.BitmapFactory; /** * This thread asynchronously delivers sdcard-cached bitmaps. * * The sdcard cache keeps thumb bitmaps in three sizes (small, medium, * original). This thread is directly accessed by the original HttpApi thread, * through one of its wrappers. * * @author Team XBMC */ class DiskCacheThread extends AbstractThread { /** * Singleton instance of this thread */ protected static DiskCacheThread sHttpApiThread; /** * Constructor is protected, use get(). */ protected DiskCacheThread() { super("HTTP API Disk Cache Thread"); } /** * Asynchronously returns a thumb from the disk cache, or null if * not available. Accessed covers get automatically added to the * memory cache. * * @param response Response object * @param cover Which cover to return * @param thumbSize Which size to return */ public void getCover(final DataResponse<Bitmap> response, final ICoverArt cover, final int thumbSize, final INotifiableController controller) { mHandler.post(new Runnable() { public void run() { if (cover != null) { final File file = ImportUtilities.getCacheFile(MediaType.getArtFolder(cover.getMediaType()), thumbSize, Crc32.formatAsHexLowerCase(cover.getCrc())); if (file.exists()) { final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); if (bitmap == null) { // file is available but obviously corruped, so delete it. file.delete(); response.value = null; } else { MemCacheThread.addCoverToCache(cover, bitmap, thumbSize); response.value = bitmap; } } } done(controller, response); } }); } /** * Synchronously returns a thumb from the disk cache, or null if not * available. * * @param cover Which cover to return * @return Bitmap or null if not available. */ public static Bitmap getCover(ICoverArt cover, int thumbSize) { final File file = ImportUtilities.getCacheFile(MediaType.getArtFolder(cover.getMediaType()), thumbSize, Crc32.formatAsHexLowerCase(cover.getCrc())); if (file.exists()) { final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); MemCacheThread.addCoverToCache(cover, bitmap, thumbSize); return bitmap; } else return null; } /** * Checks if a thumb is in the disk cache. * @param cover * @return True if thumb is in disk cache, false otherwise. */ public static boolean isInCache(ICoverArt cover, int thumbSize) { final File file = ImportUtilities.getCacheFile(MediaType.getArtFolder(cover.getMediaType()), thumbSize, Crc32.formatAsHexLowerCase(cover.getCrc()).toLowerCase()); // TODO sometimes the filesize is zero return file.exists() && file.length() > 0; } /** * Adds a cover to the disk cache * @param cover Which cover to add * @param bitmap Bitmap data, original size. */ public static Bitmap addCoverToCache(ICoverArt cover, Bitmap bitmap, int size) { return ImportUtilities.addCoverToCache(cover, bitmap, size); } /** * Returns an instance of this thread. Spawns if necessary. * @return */ public static DiskCacheThread get() { if (sHttpApiThread == null) { sHttpApiThread = new DiskCacheThread(); 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; } } }