X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/7f6c5bd3b2d0396a838168cd5e3f622b16239e67..1998cc68d6586c6a0b4bc4c9be42b48d17fa5ba7:/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 edab29d4..56c9063d 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,6 +22,7 @@ package com.owncloud.android.datamodel; import java.io.File; +import java.io.InputStream; import java.lang.ref.WeakReference; import org.apache.commons.httpclient.HttpStatus; @@ -25,23 +30,31 @@ import org.apache.commons.httpclient.methods.GetMethod; import android.accounts.Account; import android.accounts.AccountManager; +import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.ThumbnailUtils; import android.net.Uri; import android.os.AsyncTask; +import android.view.Display; +import android.view.View; +import android.view.WindowManager; import android.widget.ImageView; +import android.widget.ProgressBar; 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 +62,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 +78,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.getFileTypeIconId("image/png", "default.png") + MainApp.getAppContext().getResources(), + R.drawable.file_image ); @@ -128,23 +136,49 @@ 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; } + /** + * Sets max size of cache + * @param maxSize in MB + * @return + */ + public static boolean setMaxSize(long maxSize){ + if (mThumbnailCache != null){ + mThumbnailCache.setMaxSize(maxSize * 1024 * 1024); + return true; + } else { + return false; + } + } + + public static long getMaxSize(){ + if (mThumbnailCache != null) { + return mThumbnailCache.getMaxSize(); + } else { + return -1l; + } + } + public static class ThumbnailGenerationTask extends AsyncTask { private final WeakReference mImageViewReference; + private WeakReference mProgressWheelRef; private static Account mAccount; private Object mFile; + private Boolean mIsThumbnail; 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 mImageViewReference = new WeakReference(imageView); if (storageManager == null) @@ -153,6 +187,12 @@ public class ThumbnailsCacheManager { mAccount = account; } + public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, + Account account, ProgressBar progressWheel) { + this(imageView, storageManager, account); + mProgressWheelRef = new WeakReference(progressWheel); + } + public ThumbnailGenerationTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected mImageViewReference = new WeakReference(imageView); @@ -164,20 +204,20 @@ public class ThumbnailsCacheManager { 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]; + mIsThumbnail = (Boolean) params[1]; + if (mFile instanceof OCFile) { - thumbnail = doOCFileInBackground(); + thumbnail = doOCFileInBackground(mIsThumbnail); } else if (mFile instanceof File) { - thumbnail = doFileInBackground(); + thumbnail = doFileInBackground(mIsThumbnail); } else { // do nothing } @@ -194,22 +234,25 @@ public class ThumbnailsCacheManager { } 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 (this == bitmapWorkerTask) { String tagId = ""; if (mFile instanceof OCFile){ tagId = String.valueOf(((OCFile)mFile).getFileId()); } else if (mFile instanceof File){ - tagId = String.valueOf(((File)mFile).hashCode()); + tagId = String.valueOf(mFile.hashCode()); } if (String.valueOf(imageView.getTag()).equals(tagId)) { + if (mProgressWheelRef != null) { + final ProgressBar progressWheel = mProgressWheelRef.get(); + if (progressWheel != null) { + progressWheel.setVisibility(View.GONE); + } + } imageView.setImageBitmap(bitmap); + imageView.setVisibility(View.VISIBLE); } } } @@ -220,12 +263,13 @@ public class ThumbnailsCacheManager { * @param imageKey: thumb key * @param bitmap: image for extracting thumbnail * @param path: image path - * @param px: thumbnail dp + * @param pxW: thumbnail width + * @param pxH: thumbnail height * @return Bitmap */ - private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){ + private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int pxW, int pxH){ - Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH); // Rotate image, obeying exif tag thumbnail = BitmapUtils.rotateImage(thumbnail,path); @@ -243,29 +287,59 @@ public class ThumbnailsCacheManager { private int getThumbnailDimension(){ // Converts dp to pixel Resources r = MainApp.getAppContext().getResources(); - return (int) Math.round(r.getDimension(R.dimen.file_icon_size)); + return Math.round(r.getDimension(R.dimen.file_icon_size_grid)); + } + + private Point getScreenDimension(){ + WindowManager wm = (WindowManager) MainApp.getAppContext().getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + Point test = new Point(); + display.getSize(test); + return test; } - private Bitmap doOCFileInBackground() { + private Bitmap doOCFileInBackground(Boolean isThumbnail) { Bitmap thumbnail = null; OCFile file = (OCFile)mFile; - final String imageKey = String.valueOf(file.getRemoteId()); + // distinguish between thumbnail and resized image + String temp = String.valueOf(file.getRemoteId()); + if (isThumbnail){ + temp = "t" + temp; + } else { + temp = "r" + temp; + } + + final String imageKey = temp; // Check disk cache in background thread thumbnail = getBitmapFromDiskCache(imageKey); // Not found in disk cache if (thumbnail == null || file.needsUpdateThumbnail()) { - - int px = getThumbnailDimension(); + int pxW = 0; + int pxH = 0; + if (mIsThumbnail) { + pxW = pxH = getThumbnailDimension(); + } else { + Point p = getScreenDimension(); + pxW = p.x; + pxH = p.y; + } if (file.isDown()) { - Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( - file.getStoragePath(), px, px); + Bitmap tempBitmap = BitmapUtils.decodeSampledBitmapFromFile( + file.getStoragePath(), pxW, pxH); + Bitmap bitmap = ThumbnailUtils.extractThumbnail(tempBitmap, pxW, pxH); if (bitmap != null) { - thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px); + // Handle PNG + if (file.getMimetype().equalsIgnoreCase("image/png")) { + bitmap = handlePNG(bitmap, pxW); + } + + thumbnail = addThumbnailToCache(imageKey, bitmap, + file.getStoragePath(), pxW, pxH); file.setNeedsUpdateThumbnail(false); mStorageManager.saveFile(file); @@ -273,26 +347,54 @@ public class ThumbnailsCacheManager { } 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) { + OwnCloudVersion serverOCVersion = AccountUtils.getServerVersion(mAccount); + if (mClient != null && serverOCVersion != null) { + if (serverOCVersion.supportsRemoteThumbnails()) { 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); + if (mIsThumbnail) { + String uri = mClient.getBaseUri() + "" + + "/index.php/apps/files/api/v1/thumbnail/" + + pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/"); + Log_OC.d("Thumbnail", "Download URI: " + uri); + GetMethod get = new GetMethod(uri); + int status = mClient.executeMethod(get); + if (status == HttpStatus.SC_OK) { + InputStream inputStream = get.getResponseBodyAsStream(); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH); + } else { + Log_OC.d(TAG, "Status: " + status); + } + } else { + String gallery = ""; + if (serverOCVersion.supportsNativeGallery()){ + gallery = "gallery"; + } else { + gallery = "galleryplus"; } + + String uri = mClient.getBaseUri() + + "/index.php/apps/" + gallery + "/api/preview/" + Integer.parseInt(file.getRemoteId().substring(0,8)) + + "/" + pxW + "/" + pxH; + Log_OC.d("Thumbnail", "FileName: " + file.getFileName() + " Download URI: " + uri); + GetMethod get = new GetMethod(uri); + int status = mClient.executeMethod(get); + if (status == HttpStatus.SC_OK) { + InputStream inputStream = get.getResponseBodyAsStream(); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + // Download via gallery app + thumbnail = bitmap; + } + } + + // Handle PNG + if (thumbnail != null && file.getMimetype().equalsIgnoreCase("image/png")) { + thumbnail = handlePNG(thumbnail, pxW); + } + + // Add thumbnail to cache + if (thumbnail != null) { + addBitmapToCache(imageKey, thumbnail); } } catch (Exception e) { e.printStackTrace(); @@ -308,25 +410,52 @@ public class ThumbnailsCacheManager { } - private Bitmap doFileInBackground() { - Bitmap thumbnail = null; + private Bitmap handlePNG(Bitmap bitmap, int px){ + Bitmap resultBitmap = Bitmap.createBitmap(px, + px, + Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(resultBitmap); + + c.drawColor(MainApp.getAppContext().getResources(). + getColor(R.color.background_color)); + c.drawBitmap(bitmap, 0, 0, null); + + return resultBitmap; + } + + private Bitmap doFileInBackground(Boolean mIsThumbnail) { File file = (File)mFile; - final String imageKey = String.valueOf(file.hashCode()); + // distinguish between thumbnail and resized image + String temp = String.valueOf(file.hashCode()); + if (mIsThumbnail){ + temp = "t" + temp; + } else { + temp = "r" + temp; + } + + final String imageKey = temp; // Check disk cache in background thread - thumbnail = getBitmapFromDiskCache(imageKey); + Bitmap thumbnail = getBitmapFromDiskCache(imageKey); // Not found in disk cache if (thumbnail == null) { - - int px = getThumbnailDimension(); + int pxW = 0; + int pxH = 0; + if (mIsThumbnail) { + pxW = pxH = getThumbnailDimension(); + } else { + Point p = getScreenDimension(); + pxW = p.x; + pxH = p.y; + } Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( - file.getAbsolutePath(), px, px); + file.getAbsolutePath(), pxW, pxH); if (bitmap != null) { - thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px); + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), pxW, pxH); } } return thumbnail; @@ -343,6 +472,7 @@ public class ThumbnailsCacheManager { if (bitmapData == null || bitmapData != file) { // Cancel previous task bitmapWorkerTask.cancel(true); + Log_OC.v(TAG, "Cancelled generation of thumbnail for a reused imageView"); } else { // The same work is already in progress return false;