|
@@ -29,10 +29,8 @@ import android.content.res.Resources;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Bitmap.CompressFormat;
|
|
import android.graphics.Bitmap.CompressFormat;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.BitmapFactory;
|
|
-import android.graphics.Matrix;
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.graphics.drawable.Drawable;
|
|
-import android.media.ExifInterface;
|
|
|
|
import android.media.ThumbnailUtils;
|
|
import android.media.ThumbnailUtils;
|
|
import android.net.Uri;
|
|
import android.net.Uri;
|
|
import android.os.AsyncTask;
|
|
import android.os.AsyncTask;
|
|
@@ -76,7 +74,7 @@ public class ThumbnailsCacheManager {
|
|
public static Bitmap mDefaultImg =
|
|
public static Bitmap mDefaultImg =
|
|
BitmapFactory.decodeResource(
|
|
BitmapFactory.decodeResource(
|
|
MainApp.getAppContext().getResources(),
|
|
MainApp.getAppContext().getResources(),
|
|
- DisplayUtils.getResourceId("image/png", "default.png")
|
|
|
|
|
|
+ DisplayUtils.getFileTypeIconId("image/png", "default.png")
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
@@ -139,44 +137,15 @@ public class ThumbnailsCacheManager {
|
|
return null;
|
|
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<OCFile, Void, Bitmap> {
|
|
|
|
|
|
+ public static class ThumbnailGenerationTask extends AsyncTask<Object, Void, Bitmap> {
|
|
private final WeakReference<ImageView> mImageViewReference;
|
|
private final WeakReference<ImageView> mImageViewReference;
|
|
private static Account mAccount;
|
|
private static Account mAccount;
|
|
- private OCFile mFile;
|
|
|
|
|
|
+ private Object mFile;
|
|
private FileDataStorageManager mStorageManager;
|
|
private FileDataStorageManager mStorageManager;
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
|
|
public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
|
|
- // Use a WeakReference to ensure the ImageView can be garbage collected
|
|
|
|
|
|
+ // Use a WeakReference to ensure the ImageView can be garbage collected
|
|
mImageViewReference = new WeakReference<ImageView>(imageView);
|
|
mImageViewReference = new WeakReference<ImageView>(imageView);
|
|
if (storageManager == null)
|
|
if (storageManager == null)
|
|
throw new IllegalArgumentException("storageManager must not be NULL");
|
|
throw new IllegalArgumentException("storageManager must not be NULL");
|
|
@@ -184,95 +153,46 @@ public class ThumbnailsCacheManager {
|
|
mAccount = account;
|
|
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>(imageView);
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
- protected Bitmap doInBackground(OCFile... params) {
|
|
|
|
|
|
+ protected Bitmap doInBackground(Object... params) {
|
|
Bitmap thumbnail = null;
|
|
Bitmap thumbnail = null;
|
|
-
|
|
|
|
|
|
+
|
|
try {
|
|
try {
|
|
if (mAccount != null) {
|
|
if (mAccount != null) {
|
|
AccountManager accountMgr = AccountManager.get(MainApp.getAppContext());
|
|
AccountManager accountMgr = AccountManager.get(MainApp.getAppContext());
|
|
-
|
|
|
|
|
|
+
|
|
mServerVersion = accountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);
|
|
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().
|
|
mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
|
|
getClientFor(ocAccount, MainApp.getAppContext());
|
|
getClientFor(ocAccount, MainApp.getAppContext());
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
mFile = params[0];
|
|
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);
|
|
|
|
-
|
|
|
|
- // Rotate image, obeying exif tag
|
|
|
|
- thumbnail = BitmapUtils.rotateImage(thumbnail, mFile.getStoragePath());
|
|
|
|
-
|
|
|
|
- // 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);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- Log_OC.d(TAG, "Server too old");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (mFile instanceof OCFile) {
|
|
|
|
+ thumbnail = doOCFileInBackground();
|
|
|
|
+ } else if (mFile instanceof File) {
|
|
|
|
+ thumbnail = doFileInBackground();
|
|
|
|
+ } else {
|
|
|
|
+ // do nothing
|
|
}
|
|
}
|
|
-
|
|
|
|
- } 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;
|
|
return thumbnail;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
protected void onPostExecute(Bitmap bitmap){
|
|
protected void onPostExecute(Bitmap bitmap){
|
|
if (isCancelled()) {
|
|
if (isCancelled()) {
|
|
bitmap = null;
|
|
bitmap = null;
|
|
@@ -280,47 +200,183 @@ public class ThumbnailsCacheManager {
|
|
|
|
|
|
if (mImageViewReference != null && bitmap != null) {
|
|
if (mImageViewReference != null && bitmap != null) {
|
|
final ImageView imageView = mImageViewReference.get();
|
|
final ImageView imageView = mImageViewReference.get();
|
|
- final ThumbnailGenerationTask bitmapWorkerTask =
|
|
|
|
- getBitmapWorkerTask(imageView);
|
|
|
|
|
|
+ final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
|
if (this == bitmapWorkerTask && imageView != null) {
|
|
if (this == bitmapWorkerTask && imageView != null) {
|
|
- if (imageView.getTag().equals(mFile.getFileId())) {
|
|
|
|
|
|
+ String tagId = "";
|
|
|
|
+ if (mFile instanceof OCFile){
|
|
|
|
+ tagId = String.valueOf(((OCFile)mFile).getFileId());
|
|
|
|
+ } else if (mFile instanceof File){
|
|
|
|
+ tagId = String.valueOf(((File)mFile).hashCode());
|
|
|
|
+ }
|
|
|
|
+ if (String.valueOf(imageView.getTag()).equals(tagId)) {
|
|
imageView.setImageBitmap(bitmap);
|
|
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 (int) Math.round(r.getDimension(R.dimen.file_icon_size));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Bitmap doOCFileInBackground() {
|
|
|
|
+ Bitmap thumbnail = null;
|
|
|
|
+ OCFile file = (OCFile)mFile;
|
|
|
|
+
|
|
|
|
+ final String imageKey = String.valueOf(file.getRemoteId());
|
|
|
|
+
|
|
|
|
+ // Check disk cache in background thread
|
|
|
|
+ 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
|
|
|
|
+ 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(file.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");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return thumbnail;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Bitmap doFileInBackground() {
|
|
|
|
+ Bitmap thumbnail = null;
|
|
|
|
+ File file = (File)mFile;
|
|
|
|
+
|
|
|
|
+ final String imageKey = String.valueOf(file.hashCode());
|
|
|
|
+
|
|
|
|
+ // Check disk cache in background thread
|
|
|
|
+ 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 {
|
|
public static class AsyncDrawable extends BitmapDrawable {
|
|
private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
|
|
private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
|
|
|
|
|
|
public AsyncDrawable(
|
|
public AsyncDrawable(
|
|
Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask
|
|
Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask
|
|
- ) {
|
|
|
|
-
|
|
|
|
|
|
+ ) {
|
|
|
|
+
|
|
super(res, bitmap);
|
|
super(res, bitmap);
|
|
bitmapWorkerTaskReference =
|
|
bitmapWorkerTaskReference =
|
|
- new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
|
|
|
|
|
|
+ new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
|
|
}
|
|
}
|
|
|
|
|
|
public ThumbnailGenerationTask getBitmapWorkerTask() {
|
|
public ThumbnailGenerationTask getBitmapWorkerTask() {
|
|
return bitmapWorkerTaskReference.get();
|
|
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
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
}
|
|
}
|