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 android.accounts.Account;
import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
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;
public static class InitDiskCacheTask extends AsyncTask<File, Void, Void> {
- private static Context mContext;
-
- public InitDiskCacheTask(Context context) {
- mContext = context;
- }
@Override
protected Void doInBackground(File... params) {
return null;
}
-
- public static boolean cancelPotentialWork(OCFile file, ImageView imageView) {
- final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+ public interface AsyncTaskFile {
+ public String getId();
+ public String getTagId();
+ public String getPath();
+ public String getRemotePath();
+ public boolean getNeedsUpdateThumbnail();
+ public void setNeedsUpdateThumbnail(boolean needsUpdate);
+ public boolean getIsDown();
+ public Object getFile();
+ }
- 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;
- }
+ public static class AsyncTaskFileLocal implements AsyncTaskFile{
+
+ private File mFile;
+ private boolean mNeedsUpdate;
+
+ public AsyncTaskFileLocal(File file){
+ mFile = file;
+ mNeedsUpdate = false;
+ }
+
+ @Override
+ public String getId() {
+ return String.valueOf(mFile.hashCode());
+ }
+
+ @Override
+ public String getTagId() {
+ return String.valueOf(mFile.hashCode());
+ }
+
+ @Override
+ public String getPath() {
+ return mFile.getAbsolutePath();
+ }
+
+ @Override
+ public String getRemotePath() {
+ return null;
+ }
+
+ @Override
+ public boolean getNeedsUpdateThumbnail() {
+ return mNeedsUpdate;
+ }
+
+ @Override
+ public void setNeedsUpdateThumbnail(boolean needsUpdate) {
+ mNeedsUpdate = needsUpdate;
+ }
+
+ @Override
+ public boolean getIsDown() {
+ return false;
+ }
+
+ @Override
+ public Object getFile() {
+ return mFile;
}
- // 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<OCFile, Void, Bitmap> {
+ public static class AsyncTaskOCFile implements AsyncTaskFile{
+
+ private OCFile mFile;
+
+ public AsyncTaskOCFile(OCFile file){
+ mFile = file;
+ }
+
+ @Override
+ public String getId() {
+ return mFile.getRemoteId();
+ }
+
+ @Override
+ public String getTagId() {
+ return String.valueOf(mFile.getFileId());
+ }
+
+ @Override
+ public String getPath() {
+ return mFile.getStoragePath();
+ }
+
+ @Override
+ public String getRemotePath() {
+ return mFile.getRemotePath();
+ }
+
+ @Override
+ public boolean getNeedsUpdateThumbnail() {
+ return mFile.needsUpdateThumbnail();
+ }
+
+ @Override
+ public void setNeedsUpdateThumbnail(boolean needsUpdate) {
+ mFile.setNeedsUpdateThumbnail(needsUpdate);
+ }
+
+ @Override
+ public boolean getIsDown() {
+ return mFile.isDown();
+ }
+
+ @Override
+ public Object getFile() {
+ return mFile;
+ }
+ }
+
+ public static class ThumbnailGenerationGlobalTask extends AsyncTask<AsyncTaskFile, Void, Bitmap> {
private final WeakReference<ImageView> mImageViewReference;
private static Account mAccount;
- private OCFile mFile;
+ private AsyncTaskFile mFile;
private FileDataStorageManager mStorageManager;
-
- public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
- // Use a WeakReference to ensure the ImageView can be garbage collected
+
+
+ public ThumbnailGenerationGlobalTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
+ // Use a WeakReference to ensure the ImageView can be garbage collected
mImageViewReference = new WeakReference<ImageView>(imageView);
if (storageManager == null)
throw new IllegalArgumentException("storageManager must not be NULL");
mAccount = account;
}
- // Decode image in background.
+ public ThumbnailGenerationGlobalTask(ImageView imageView) {
+ // Use a WeakReference to ensure the ImageView can be garbage collected
+ mImageViewReference = new WeakReference<ImageView>(imageView);
+ }
+
@Override
- protected Bitmap doInBackground(OCFile... params) {
+ protected Bitmap doInBackground(AsyncTaskFile... 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());
- mClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, MainApp.getAppContext());
+ mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, MainApp.getAppContext());
}
-
+
mFile = params[0];
- final String imageKey = String.valueOf(mFile.getRemoteId());
-
+
+ final String imageKey = String.valueOf(mFile.getId());
+
// 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(TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics()
- ));
-
- 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);
- 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);
+ // Check if mFile passed is an OCFile (for OCFile thumbs)
+ if (mFile instanceof AsyncTaskOCFile) {
+
+ // Not found in disk cache
+ if (thumbnail == null || mFile.getNeedsUpdateThumbnail()) {
+
+ int px = getThumbnailDimension();
+
+ if (mFile.getIsDown()) {
+ Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+ mFile.getPath(), px, px);
+
+ if (bitmap != null) {
+ thumbnail = addThumbnailToCache(imageKey, bitmap, mFile.getPath(), px);
+
+ mFile.setNeedsUpdateThumbnail(false);
+ mStorageManager.saveFile((OCFile) mFile.getFile());
+ }
+
+ } 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();
}
- } catch (Exception e) {
- e.printStackTrace();
+ } else {
+ Log_OC.d(TAG, "Server too old");
}
- } else {
- Log_OC.d(TAG, "Server too old");
}
}
}
+ // Check if mFile passed is a File (for local thumbs)
+ } else if (mFile instanceof AsyncTaskFileLocal) {
+
+ // Not found in disk cache
+ if (thumbnail == null) {
+
+ int px = getThumbnailDimension();
+
+ Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+ mFile.getPath(), px, px);
+
+ if (bitmap != null) {
+ thumbnail = addThumbnailToCache(imageKey, bitmap, mFile.getPath(), px);
+ }
+ }
+
}
-
- } 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) {
final ImageView imageView = mImageViewReference.get();
- final ThumbnailGenerationTask bitmapWorkerTask =
- getBitmapWorkerTask(imageView);
+ final ThumbnailGenerationGlobalTask bitmapWorkerTask = getBitmapGlobalWorkerTask(imageView);
if (this == bitmapWorkerTask && imageView != null) {
- if (imageView.getTag().equals(mFile.getFileId())) {
+ if (String.valueOf(imageView.getTag()).equals(mFile.getTagId())) {
imageView.setImageBitmap(bitmap);
}
}
}
}
- }
-
-
- public static class AsyncDrawable extends BitmapDrawable {
- private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
- public AsyncDrawable(
- Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask
- ) {
-
- super(res, bitmap);
- bitmapWorkerTaskReference =
- new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
+ /**
+ * 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;
}
- public ThumbnailGenerationTask getBitmapWorkerTask() {
- return bitmapWorkerTaskReference.get();
+ /**
+ * Converts size of file icon from dp to pixel
+ * @return int
+ */
+ private int getThumbnailDimension(){
+ // Converts dp to pixel
+ Resources r = MainApp.getAppContext().getResources();
+ return (int) Math.round(r.getDimension(R.dimen.file_icon_size));
}
}
-
- /**
- * 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);
+ public static boolean cancelPotentialGlobalWork(AsyncTaskFile file, ImageView imageView) {
+ final ThumbnailGenerationGlobalTask bitmapWorkerTask = getBitmapGlobalWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final AsyncTaskFile 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;
}
- mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
}
+ // No task associated with the ImageView, or an existing task was cancelled
+ return true;
+ }
+
+ public static ThumbnailGenerationGlobalTask getBitmapGlobalWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncGlobalDrawable) {
+ final AsyncGlobalDrawable asyncDrawable = (AsyncGlobalDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
}
+ public static class AsyncGlobalDrawable extends BitmapDrawable {
+ private final WeakReference<ThumbnailGenerationGlobalTask> bitmapWorkerTaskReference;
+
+ public AsyncGlobalDrawable(
+ Resources res, Bitmap bitmap, ThumbnailGenerationGlobalTask bitmapWorkerTask
+ ) {
+
+ super(res, bitmap);
+ bitmapWorkerTaskReference =
+ new WeakReference<ThumbnailGenerationGlobalTask>(bitmapWorkerTask);
+ }
+
+ public ThumbnailGenerationGlobalTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
}