X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/2e47071c9c44d687b0c69a393807ea32fde08184..0d6320aa792b7e49b410f5582b84acbce2fc362a:/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java diff --git a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index 2cedcb41..bf62a23c 100644 --- a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -18,34 +18,34 @@ package com.owncloud.android.datamodel; import java.io.File; -import java.io.IOException; import java.lang.ref.WeakReference; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import android.accounts.Account; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.content.Context; +import android.accounts.AccountManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; +import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.media.ExifInterface; import android.media.ThumbnailUtils; import android.net.Uri; import android.os.AsyncTask; -import android.util.TypedValue; import android.widget.ImageView; import com.owncloud.android.MainApp; +import com.owncloud.android.R; import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; -import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; +import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; import com.owncloud.android.ui.adapter.DiskLruImageCache; import com.owncloud.android.utils.BitmapUtils; import com.owncloud.android.utils.DisplayUtils; @@ -60,7 +60,8 @@ public class ThumbnailsCacheManager { private static final String TAG = ThumbnailsCacheManager.class.getSimpleName(); - private static final String CACHE_FOLDER = "thumbnailCache"; + private static final String CACHE_FOLDER = "thumbnailCache"; + private static final String MINOR_SERVER_VERSION_FOR_THUMBS = "7.8.0"; private static final Object mThumbnailsDiskCacheLock = new Object(); private static DiskLruImageCache mThumbnailCache = null; @@ -69,7 +70,8 @@ public class ThumbnailsCacheManager { private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB private static final CompressFormat mCompressFormat = CompressFormat.JPEG; private static final int mCompressQuality = 70; - private static OwnCloudClient mClient; + private static OwnCloudClient mClient = null; + private static String mServerVersion = null; public static Bitmap mDefaultImg = BitmapFactory.decodeResource( @@ -79,13 +81,6 @@ public class ThumbnailsCacheManager { public static class InitDiskCacheTask extends AsyncTask { - private static Account mAccount; - private static Context mContext; - - public InitDiskCacheTask(Account account, Context context) { - mAccount = account; - mContext = context; - } @Override protected Void doInBackground(File... params) { @@ -94,24 +89,6 @@ public class ThumbnailsCacheManager { if (mThumbnailCache == null) { try { - OwnCloudAccount ocAccount; - try { - ocAccount = new OwnCloudAccount(mAccount, mContext); - mClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, mContext); - } catch (AccountNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (AuthenticatorException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (OperationCanceledException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // Check if media is mounted or storage is built-in, if so, // try and use external cache dir; otherwise use internal cache dir final String cachePath = @@ -181,6 +158,24 @@ public class ThumbnailsCacheManager { return true; } + public static boolean cancelPotentialWork(File file, ImageView imageView) { + final ThumbnailLocalGenerationTask bitmapWorkerTask = getBitmapLocalWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final File bitmapData = bitmapWorkerTask.mFile; + // If bitmapData is not yet set or it differs from the new data + if (bitmapData == null || bitmapData != file) { + // Cancel previous task + bitmapWorkerTask.cancel(true); + } else { + // The same work is already in progress + return false; + } + } + // No task associated with the ImageView, or an existing task was cancelled + return true; + } + public static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) { if (imageView != null) { final Drawable drawable = imageView.getDrawable(); @@ -191,18 +186,98 @@ public class ThumbnailsCacheManager { } return null; } + + public static ThumbnailLocalGenerationTask getBitmapLocalWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncLocalDrawable) { + final AsyncLocalDrawable asyncDrawable = (AsyncLocalDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + + public static class ThumbnailLocalGenerationTask extends AsyncTask { + private final WeakReference mImageViewLocalReference; + private File mFile; + + public ThumbnailLocalGenerationTask(ImageView imageView) { + // Use a WeakReference to ensure the ImageView can be garbage collected + mImageViewLocalReference = new WeakReference(imageView); + } + + // Decode image in background. + @Override + protected Bitmap doInBackground(File... params) { + Bitmap thumbnail = null; + + try { + mFile = params[0]; + final String imageKey = String.valueOf(mFile.hashCode()); + + // Check disk cache in background thread + thumbnail = getBitmapFromDiskCache(imageKey); + + // Not found in disk cache + if (thumbnail == null) { + // Converts dp to pixel + Resources r = MainApp.getAppContext().getResources(); + + int px = (int) Math.round(r.getDimension(R.dimen.file_icon_size)); + + Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + mFile.getAbsolutePath(), px, px); + + if (bitmap != null) { + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + + // Add thumbnail to cache + addBitmapToCache(imageKey, thumbnail); + } + } + + } catch (Throwable t) { + // the app should never break due to a problem with thumbnails + Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t); + if (t instanceof OutOfMemoryError) { + System.gc(); + } + } + + return thumbnail; + } + + protected void onPostExecute(Bitmap bitmap){ + if (isCancelled()) { + bitmap = null; + } + + if (mImageViewLocalReference != null && bitmap != null) { + final ImageView imageView = mImageViewLocalReference.get(); + final ThumbnailLocalGenerationTask bitmapWorkerTask = getBitmapLocalWorkerTask(imageView); + if (this == bitmapWorkerTask && imageView != null) { + if (imageView.getTag().equals(mFile.hashCode())) { + imageView.setImageBitmap(bitmap); + } + } + } + } + } public static class ThumbnailGenerationTask extends AsyncTask { private final WeakReference mImageViewReference; + private static Account mAccount; private OCFile mFile; private FileDataStorageManager mStorageManager; - public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager) { + public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) { // Use a WeakReference to ensure the ImageView can be garbage collected mImageViewReference = new WeakReference(imageView); if (storageManager == null) throw new IllegalArgumentException("storageManager must not be NULL"); mStorageManager = storageManager; + mAccount = account; } // Decode image in background. @@ -211,6 +286,15 @@ public class ThumbnailsCacheManager { Bitmap thumbnail = null; try { + if (mAccount != null) { + AccountManager accountMgr = AccountManager.get(MainApp.getAppContext()); + + mServerVersion = accountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION); + OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, MainApp.getAppContext()); + mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, MainApp.getAppContext()); + } + mFile = params[0]; final String imageKey = String.valueOf(mFile.getRemoteId()); @@ -221,9 +305,8 @@ public class ThumbnailsCacheManager { if (thumbnail == null || mFile.needsUpdateThumbnail()) { // Converts dp to pixel Resources r = MainApp.getAppContext().getResources(); - int px = (int) Math.round(TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics() - )); + + int px = (int) Math.round(r.getDimension(R.dimen.file_icon_size)); if (mFile.isDown()){ Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( @@ -231,6 +314,9 @@ public class ThumbnailsCacheManager { if (bitmap != null) { thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + + // Rotate image, obeying exif tag + thumbnail = BitmapUtils.rotateImage(thumbnail, mFile.getStoragePath()); // Add thumbnail to cache addBitmapToCache(imageKey, thumbnail); @@ -241,26 +327,33 @@ public class ThumbnailsCacheManager { } else { // Download thumbnail from server - try { - int status = -1; + if (mClient != null && mServerVersion != null) { + OwnCloudVersion serverOCVersion = new OwnCloudVersion(mServerVersion); + if (serverOCVersion.compareTo(new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) { + try { + int status = -1; - String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + px + "/" + px - + Uri.encode(mFile.getRemotePath(), "/"); - Log_OC.d("Thumbnail", "URI: " + uri); - GetMethod get = new GetMethod(uri); - status = mClient.executeMethod(get); - if (status == HttpStatus.SC_OK) { - byte[] bytes = get.getResponseBody(); - Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); - thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" + + px + "/" + px + Uri.encode(mFile.getRemotePath(), "/"); + Log_OC.d("Thumbnail", "URI: " + uri); + GetMethod get = new GetMethod(uri); + status = mClient.executeMethod(get); + if (status == HttpStatus.SC_OK) { + byte[] bytes = get.getResponseBody(); + Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); - // Add thumbnail to cache - if (thumbnail != null) { - addBitmapToCache(imageKey, thumbnail); + // Add thumbnail to cache + if (thumbnail != null) { + addBitmapToCache(imageKey, thumbnail); + } + } + } catch (Exception e) { + e.printStackTrace(); } + } else { + Log_OC.d(TAG, "Server too old"); } - } catch (Exception e) { - e.printStackTrace(); } } } @@ -311,6 +404,20 @@ public class ThumbnailsCacheManager { return bitmapWorkerTaskReference.get(); } } + + public static class AsyncLocalDrawable extends BitmapDrawable { + private final WeakReference bitmapWorkerLocalTaskReference; + + public AsyncLocalDrawable(Resources res, Bitmap bitmap, ThumbnailLocalGenerationTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerLocalTaskReference = + new WeakReference(bitmapWorkerTask); + } + + public ThumbnailLocalGenerationTask getBitmapWorkerTask() { + return bitmapWorkerLocalTaskReference.get(); + } + } /** @@ -325,5 +432,5 @@ public class ThumbnailsCacheManager { mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads } } - + }