/* * Copyright (C) 2014 Fastboot Mobile, LLC. * * 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 3 of * the License, 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 this program; * if not, see <http://www.gnu.org/licenses>. */ package com.fastbootmobile.encore.art; import android.content.res.Resources; import android.os.AsyncTask; import android.os.Process; import android.util.Log; import com.fastbootmobile.encore.model.BoundEntity; import java.util.concurrent.RejectedExecutionException; /** * AsyncTask downloading the album art */ public class AlbumArtTask extends AsyncTask<AlbumArtHelper.AlbumArtRequest, Void, AlbumArtHelper.BackgroundResult> { private static final String TAG = "AlbumArtTask"; private static final int DELAY_BEFORE_RETRY = 500; private static final Object sPauseWorkLock = new Object(); private static boolean sPauseWork = false; private RecyclingBitmapDrawable mArtBitmap; private AlbumArtCache.IAlbumArtCacheListener mCacheListener = new AlbumArtCache.IAlbumArtCacheListener() { @Override public void onArtLoaded(BoundEntity ent, RecyclingBitmapDrawable result) { synchronized (AlbumArtTask.this) { if (!isCancelled()) { mArtBitmap = result; } AlbumArtTask.this.notify(); } } }; @Override protected AlbumArtHelper.BackgroundResult doInBackground(AlbumArtHelper.AlbumArtRequest... params) { android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); AlbumArtHelper.AlbumArtRequest request = params[0]; // Wait here if work is paused and the task is not cancelled synchronized (sPauseWorkLock) { while (sPauseWork && !isCancelled()) { try { sPauseWorkLock.wait(); } catch (InterruptedException ignored) {} } } if (request.entity == null || isCancelled()) { return null; } AlbumArtHelper.BackgroundResult output = new AlbumArtHelper.BackgroundResult(); output.request = request.entity; output.listener = request.listener; output.size = request.requestedSize; final AlbumArtCache artCache = AlbumArtCache.getDefault(); if (artCache.isQueryRunning(request.entity)) { output.retry = true; } else { // Notify other potential tasks we're processing this entity artCache.notifyQueryRunning(request.entity); // Get from the cache synchronized (this) { if (AlbumArtCache.getDefault().getArt(request.res, request.entity, request.requestedSize, mCacheListener)) { // Wait for the result if (mArtBitmap == null) { try { wait(6000); } catch (InterruptedException e) { // Interrupted, cancel cancel(true); return output; } } } } // In all cases, we tell that this entity is loaded artCache.notifyQueryStopped(request.entity); // We now have a bitmap to display, so let's put it! if (mArtBitmap != null) { output.bitmap = mArtBitmap; output.retry = false; } else { output.bitmap = null; output.retry = false; } } return output; } @Override protected void onCancelled(AlbumArtHelper.BackgroundResult result) { final AlbumArtCache artCache = AlbumArtCache.getDefault(); if (result != null) { artCache.notifyQueryStopped(result.request); if (result.listener != null) { result.listener.onArtLoaded(null, result.request); } } } @Override protected void onPostExecute(final AlbumArtHelper.BackgroundResult result) { super.onPostExecute(result); if (!isCancelled() && result != null && result.listener != null) { if (result.retry) { // We retry to get it in a bit final AlbumArtTask task = new AlbumArtTask(); AlbumArtHelper.AlbumArtRequest request = new AlbumArtHelper.AlbumArtRequest(); request.listener = result.listener; request.entity = result.request; request.requestedSize = result.size; request.res = Resources.getSystem(); try { task.executeOnExecutor(AlbumArtHelper.ART_POOL_EXECUTOR, request); } catch (RejectedExecutionException e) { Log.w(TAG, "Request restart has been denied", e); } } else { result.listener.onArtLoaded(result.bitmap, result.request); } } } public static void setPauseWork(boolean pause) { synchronized (sPauseWorkLock) { sPauseWork = pause; if (!sPauseWork) { sPauseWorkLock.notifyAll(); } } } }