X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/79cb6106fd3fc83aa84d18fb472788833b980ea8..00482b6dcb1e98da39df54374f7098b51d66bee5:/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 1d2cda8c..0e59a834 100644 --- a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -1,5 +1,9 @@ -/* ownCloud Android client application - * Copyright (C) 2012-2014 ownCloud Inc. +/** + * ownCloud Android client application + * + * @author Tobias Kaminsky + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -18,13 +22,13 @@ package com.owncloud.android.datamodel; import java.io.File; +import java.io.InputStream; 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.AccountManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; @@ -38,10 +42,10 @@ import android.widget.ImageView; import com.owncloud.android.MainApp; import com.owncloud.android.R; +import com.owncloud.android.authentication.AccountUtils; 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.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; @@ -49,18 +53,14 @@ import com.owncloud.android.utils.BitmapUtils; import com.owncloud.android.utils.DisplayUtils; /** - * Manager for concurrent access to thumbnails cache. - * - * @author Tobias Kaminsky - * @author David A. Velasco + * Manager for concurrent access to thumbnails cache. */ public class ThumbnailsCacheManager { private static final String TAG = ThumbnailsCacheManager.class.getSimpleName(); 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; private static boolean mThumbnailCacheStarting = true; @@ -69,12 +69,11 @@ public class ThumbnailsCacheManager { private static final CompressFormat mCompressFormat = CompressFormat.JPEG; private static final int mCompressQuality = 70; private static OwnCloudClient mClient = null; - private static String mServerVersion = null; public static Bitmap mDefaultImg = BitmapFactory.decodeResource( MainApp.getAppContext().getResources(), - DisplayUtils.getResourceId("image/png", "default.png") + DisplayUtils.getFileTypeIconId("image/png", "default.png") ); @@ -128,53 +127,27 @@ public class ThumbnailsCacheManager { while (mThumbnailCacheStarting) { try { mThumbnailsDiskCacheLock.wait(); - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + Log_OC.e(TAG, "Wait in mThumbnailsDiskCacheLock was interrupted", e); + } } if (mThumbnailCache != null) { - return (Bitmap) mThumbnailCache.getBitmap(key); + return mThumbnailCache.getBitmap(key); } } return null; } - - public static boolean cancelPotentialWork(OCFile file, ImageView imageView) { - final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final OCFile 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(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - public static class ThumbnailGenerationTask extends AsyncTask { + public static class ThumbnailGenerationTask extends AsyncTask { private final WeakReference mImageViewReference; private static Account mAccount; - private OCFile mFile; + private Object mFile; private FileDataStorageManager mStorageManager; - - public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) { - // Use a WeakReference to ensure the ImageView can be garbage collected + + + 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"); @@ -182,140 +155,227 @@ public class ThumbnailsCacheManager { mAccount = account; } - // Decode image in background. + public ThumbnailGenerationTask(ImageView imageView) { + // Use a WeakReference to ensure the ImageView can be garbage collected + mImageViewReference = new WeakReference(imageView); + } + @Override - protected Bitmap doInBackground(OCFile... params) { + protected Bitmap doInBackground(Object... params) { 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()); + OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, + MainApp.getAppContext()); mClient = OwnCloudClientManagerFactory.getDefaultSingleton(). getClientFor(ocAccount, MainApp.getAppContext()); } - + mFile = params[0]; - final String imageKey = String.valueOf(mFile.getRemoteId()); - - // Check disk cache in background thread - thumbnail = getBitmapFromDiskCache(imageKey); - - // Not found in disk cache - if (thumbnail == null || mFile.needsUpdateThumbnail()) { - // Converts dp to pixel - Resources r = MainApp.getAppContext().getResources(); - - int px = (int) Math.round(r.getDimension(R.dimen.file_icon_size)); - - if (mFile.isDown()){ - Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( - mFile.getStoragePath(), px, px); - - if (bitmap != null) { - thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); - - // Add thumbnail to cache - addBitmapToCache(imageKey, thumbnail); + + if (mFile instanceof OCFile) { + thumbnail = doOCFileInBackground(); + } else if (mFile instanceof File) { + thumbnail = doFileInBackground(); + //} else { do nothing + } - mFile.setNeedsUpdateThumbnail(false); - mStorageManager.saveFile(mFile); - } - - } else { - // Download thumbnail from server - 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); - - // Add thumbnail to cache - if (thumbnail != null) { - addBitmapToCache(imageKey, thumbnail); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } else { - Log_OC.d(TAG, "Server too old"); - } - } + }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(); } } - - } 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 (mImageViewReference != null && bitmap != null) { + if (bitmap != null) { final ImageView imageView = mImageViewReference.get(); - final ThumbnailGenerationTask bitmapWorkerTask = - getBitmapWorkerTask(imageView); - if (this == bitmapWorkerTask && imageView != null) { - if (imageView.getTag().equals(mFile.getFileId())) { + final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + if (this == bitmapWorkerTask) { + String tagId = ""; + if (mFile instanceof OCFile){ + tagId = String.valueOf(((OCFile)mFile).getFileId()); + } else if (mFile instanceof File){ + tagId = String.valueOf(mFile.hashCode()); + } + if (String.valueOf(imageView.getTag()).equals(tagId)) { imageView.setImageBitmap(bitmap); } } } } + + /** + * Add thumbnail to cache + * @param imageKey: thumb key + * @param bitmap: image for extracting thumbnail + * @param path: image path + * @param px: thumbnail dp + * @return Bitmap + */ + private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){ + + Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + + // Rotate image, obeying exif tag + thumbnail = BitmapUtils.rotateImage(thumbnail,path); + + // Add thumbnail to cache + addBitmapToCache(imageKey, thumbnail); + + return thumbnail; + } + + /** + * Converts size of file icon from dp to pixel + * @return int + */ + private int getThumbnailDimension(){ + // Converts dp to pixel + Resources r = MainApp.getAppContext().getResources(); + return Math.round(r.getDimension(R.dimen.file_icon_size_grid)); + } + + private Bitmap doOCFileInBackground() { + OCFile file = (OCFile)mFile; + + final String imageKey = String.valueOf(file.getRemoteId()); + + // Check disk cache in background thread + Bitmap thumbnail = getBitmapFromDiskCache(imageKey); + + // Not found in disk cache + if (thumbnail == null || file.needsUpdateThumbnail()) { + + int px = getThumbnailDimension(); + + if (file.isDown()) { + Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + file.getStoragePath(), px, px); + + if (bitmap != null) { + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px); + + file.setNeedsUpdateThumbnail(false); + mStorageManager.saveFile(file); + } + + } else { + // Download thumbnail from server + OwnCloudVersion serverOCVersion = AccountUtils.getServerVersion(mAccount); + if (mClient != null && serverOCVersion != null) { + if (serverOCVersion.supportsRemoteThumbnails()) { + try { + String uri = mClient.getBaseUri() + "" + + "/index.php/apps/files/api/v1/thumbnail/" + + px + "/" + px + Uri.encode(file.getRemotePath(), "/"); + Log_OC.d("Thumbnail", "URI: " + uri); + GetMethod get = new GetMethod(uri); + int status = mClient.executeMethod(get); + if (status == HttpStatus.SC_OK) { +// byte[] bytes = get.getResponseBody(); +// Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, +// bytes.length); + InputStream inputStream = get.getResponseBodyAsStream(); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + + // Add thumbnail to cache + if (thumbnail != null) { + addBitmapToCache(imageKey, thumbnail); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } else { + Log_OC.d(TAG, "Server too old"); + } + } + } + } + + return thumbnail; + + } + + private Bitmap doFileInBackground() { + File file = (File)mFile; + + final String imageKey = String.valueOf(file.hashCode()); + + // Check disk cache in background thread + Bitmap thumbnail = getBitmapFromDiskCache(imageKey); + + // Not found in disk cache + if (thumbnail == null) { + + int px = getThumbnailDimension(); + + Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + file.getAbsolutePath(), px, px); + + if (bitmap != null) { + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px); + } + } + return thumbnail; + } + } - - + + public static boolean cancelPotentialWork(Object file, ImageView imageView) { + final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final Object 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(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + public static class AsyncDrawable extends BitmapDrawable { private final WeakReference bitmapWorkerTaskReference; public AsyncDrawable( Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask - ) { - + ) { + super(res, bitmap); bitmapWorkerTaskReference = - new WeakReference(bitmapWorkerTask); + new WeakReference(bitmapWorkerTask); } public ThumbnailGenerationTask getBitmapWorkerTask() { return bitmapWorkerTaskReference.get(); } } - - - /** - * Remove from cache the remoteId passed - * @param fileRemoteId: remote id of mFile passed - */ - public static void removeFileFromCache(String fileRemoteId){ - synchronized (mThumbnailsDiskCacheLock) { - if (mThumbnailCache != null) { - mThumbnailCache.removeKey(fileRemoteId); - } - mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads - } - } - }