From: jabarros Date: Fri, 24 Oct 2014 11:38:03 +0000 (+0200) Subject: Merge branch 'thumbnails_from_server' of https://github.com/tobiasKaminsky/android... X-Git-Tag: oc-android-1.7.0_signed~121^2~7 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/2e47071c9c44d687b0c69a393807ea32fde08184?ds=inline;hp=-c Merge branch 'thumbnails_from_server' of https://github.com/tobiasKaminsky/android into thumbnails_from_server Conflicts: src/com/owncloud/android/ui/adapter/FileListListAdapter.java --- 2e47071c9c44d687b0c69a393807ea32fde08184 diff --combined src/com/owncloud/android/MainApp.java index e04239df,08efe342..37a3e6ff --- a/src/com/owncloud/android/MainApp.java +++ b/src/com/owncloud/android/MainApp.java @@@ -16,13 -16,11 +16,14 @@@ */ package com.owncloud.android; -import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; -import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; - import android.app.Application; import android.content.Context; + ++import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; +import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy; +import com.owncloud.android.lib.common.utils.Log_OC; /** * Main Application of the project * @@@ -55,20 -53,7 +56,21 @@@ public class MainApp extends Applicatio } else { OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT); } - ++ + // initialise thumbnails cache on background thread - new ThumbnailsCacheManager.InitDiskCacheTask().execute(); ++ new ThumbnailsCacheManager.InitDiskCacheTask(AccountUtils.getCurrentOwnCloudAccount(mContext), ++ mContext).execute(); + if (BuildConfig.DEBUG) { + + String dataFolder = getDataFolder(); + + // Set folder for store logs + Log_OC.setLogDataFolder(dataFolder); + + Log_OC.startLogging(); + Log_OC.d("Debug", "start logging"); + } } public static Context getAppContext() { @@@ -81,7 -66,7 +83,7 @@@ public static String getAccountType() { return getAppContext().getResources().getString(R.string.account_type); } - + // From AccountAuthenticator // public static final String AUTHORITY = "org.owncloud"; public static String getAuthority() { diff --combined src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index e75404ef,00000000..2cedcb41 mode 100644,000000..100644 --- a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@@ -1,265 -1,0 +1,329 @@@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 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, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +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.content.res.Resources; +import android.graphics.Bitmap; - import android.graphics.BitmapFactory; +import android.graphics.Bitmap.CompressFormat; ++import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +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.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.utils.Log_OC; +import com.owncloud.android.ui.adapter.DiskLruImageCache; +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 + */ +public class ThumbnailsCacheManager { + + private static final String TAG = ThumbnailsCacheManager.class.getSimpleName(); + + private static final String CACHE_FOLDER = "thumbnailCache"; + + private static final Object mThumbnailsDiskCacheLock = new Object(); + private static DiskLruImageCache mThumbnailCache = null; + private static boolean mThumbnailCacheStarting = true; + + 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; ++ + public static Bitmap mDefaultImg = + BitmapFactory.decodeResource( + MainApp.getAppContext().getResources(), + DisplayUtils.getResourceId("image/png", "default.png") + ); + + + 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) { + synchronized (mThumbnailsDiskCacheLock) { + mThumbnailCacheStarting = true; ++ + 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 = + MainApp.getAppContext().getExternalCacheDir().getPath() + + File.separator + CACHE_FOLDER; + Log_OC.d(TAG, "create dir: " + cachePath); + final File diskCacheDir = new File(cachePath); + mThumbnailCache = new DiskLruImageCache( + diskCacheDir, + DISK_CACHE_SIZE, + mCompressFormat, + mCompressQuality + ); + } catch (Exception e) { + Log_OC.d(TAG, "Thumbnail cache could not be opened ", e); + mThumbnailCache = null; + } + } + mThumbnailCacheStarting = false; // Finished initialization + mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads + } + return null; + } + } + + + public static void addBitmapToCache(String key, Bitmap bitmap) { + synchronized (mThumbnailsDiskCacheLock) { + if (mThumbnailCache != null) { + mThumbnailCache.put(key, bitmap); + } + } + } + + + public static Bitmap getBitmapFromDiskCache(String key) { + synchronized (mThumbnailsDiskCacheLock) { + // Wait while disk cache is started from background thread + while (mThumbnailCacheStarting) { + try { + mThumbnailsDiskCacheLock.wait(); + } catch (InterruptedException e) {} + } + if (mThumbnailCache != null) { + return (Bitmap) 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 { + private final WeakReference mImageViewReference; + private OCFile mFile; + private FileDataStorageManager mStorageManager; + + public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager) { + // 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; + } + + // Decode image in background. + @Override + protected Bitmap doInBackground(OCFile... params) { + Bitmap thumbnail = null; + + try { + 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(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 ++ 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 (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); + if (this == bitmapWorkerTask && imageView != null) { + if (imageView.getTag().equals(mFile.getFileId())) { + imageView.setImageBitmap(bitmap); + } + } + } + } + } + + + 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); + } + + 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 + } + } + +} diff --combined src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 0d10e7fa,64a2b579..d74bbc5b --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@@ -17,11 -17,28 +17,11 @@@ */ package com.owncloud.android.ui.adapter; -import java.io.File; -import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.Vector; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.http.HttpStatus; - import android.accounts.Account; -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.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.media.ThumbnailUtils; -import android.net.Uri; -import android.os.AsyncTask; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@@ -35,49 -52,208 +35,50 @@@ import com.owncloud.android.R import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; +import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; -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.ui.activity.ComponentsGetter; import com.owncloud.android.utils.DisplayUtils; -import com.owncloud.android.utils.Log_OC; + /** * This Adapter populates a ListView with all files and folders in an ownCloud * instance. * * @author Bartek Przybylski - * @Author Tobias Kaminsky - * + * @author Tobias Kaminsky + * @author David A. Velasco */ public class FileListListAdapter extends BaseAdapter implements ListAdapter { private final static String PERMISSION_SHARED_WITH_ME = "S"; - - private final Context mContext; + + private Context mContext; private OCFile mFile = null; private Vector mFiles = null; - private final boolean mJustFolders; - - private FileDataStorageManager mStorageManager; - private Account mAccount; - private final ComponentsGetter mTransferServiceGetter; - - private final Object thumbnailDiskCacheLock = new Object(); - private DiskLruImageCache mThumbnailCache; - private boolean mThumbnailCacheStarting = true; - 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 final Bitmap defaultImg; - private OwnCloudClient client; - - public FileListListAdapter(boolean justFolders, Context context, ComponentsGetter transferServiceGetter) { + private boolean mJustFolders; + + private FileDataStorageManager mStorageManager; + private Account mAccount; + private ComponentsGetter mTransferServiceGetter; + + public FileListListAdapter( + boolean justFolders, + Context context, + ComponentsGetter transferServiceGetter + ) { - + mJustFolders = justFolders; mContext = context; mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); mTransferServiceGetter = transferServiceGetter; - - defaultImg = BitmapFactory.decodeResource(mContext.getResources(), - DisplayUtils.getResourceId("image/png", "default.png")); - - // Initialise disk cache on background thread - new InitDiskCacheTask().execute(); - - } - - class InitDiskCacheTask extends AsyncTask { - @Override - protected Void doInBackground(File... params) { - synchronized (thumbnailDiskCacheLock) { - OwnCloudAccount ocAccount; - try { - ocAccount = new OwnCloudAccount(mAccount, mContext); - client = 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(); - } - - mThumbnailCache = new DiskLruImageCache(mContext, "thumbnailCache", DISK_CACHE_SIZE, mCompressFormat, - mCompressQuality); - - mThumbnailCacheStarting = false; // Finished initialization - thumbnailDiskCacheLock.notifyAll(); // Wake any waiting threads - } - return null; - } - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference(bitmapWorkerTask); - } - - public ThumbnailGenerationTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } - - class ThumbnailGenerationTask extends AsyncTask { - private final WeakReference imageViewReference; - private OCFile file; - - public ThumbnailGenerationTask(ImageView imageView) { - // Use a WeakReference to ensure the ImageView can be garbage - // collected - imageViewReference = new WeakReference(imageView); - } - - // Decode image in background. - @Override - protected Bitmap doInBackground(OCFile... params) { - file = params[0]; - final String imageKey = String.valueOf(file.getRemoteId().hashCode()); - Log_OC.d("Thumbnail", imageKey); - - // Check disk cache in background thread - Bitmap thumbnail = getBitmapFromDiskCache(imageKey); - - // Not found in disk cache - if (thumbnail == null) { - // Converts dp to pixel - Resources r = mContext.getResources(); - int px = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, r.getDisplayMetrics())); - - if (file.isDown()) { - Bitmap bitmap = BitmapFactory.decodeFile(file.getStoragePath()); - - if (bitmap != null) { - thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); - - // Add thumbnail to cache - addBitmapToCache(imageKey, thumbnail); - } - - } else { - // Download thumbnail from server - try { - int status = -1; - - String uri = client.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 = client.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(); - } - } - } - return thumbnail; - } + - @Override - protected void onPostExecute(Bitmap bitmap) { - if (isCancelled()) { - bitmap = null; - } + // initialise thumbnails cache on background thread - new ThumbnailsCacheManager.InitDiskCacheTask().execute(); ++ new ThumbnailsCacheManager.InitDiskCacheTask(mAccount, mContext).execute(); + - if (imageViewReference != null && bitmap != null) { - final ImageView imageView = imageViewReference.get(); - final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - if (this == bitmapWorkerTask && imageView != null) { - imageView.setImageBitmap(bitmap); - } - } - } } - - public void addBitmapToCache(String key, Bitmap bitmap) { - synchronized (thumbnailDiskCacheLock) { - if (mThumbnailCache != null && mThumbnailCache.getBitmap(key) == null) { - mThumbnailCache.put(key, bitmap); - } - } - } - - public Bitmap getBitmapFromDiskCache(String key) { - synchronized (thumbnailDiskCacheLock) { - // Wait while disk cache is started from background thread - while (mThumbnailCacheStarting) { - try { - thumbnailDiskCacheLock.wait(); - } catch (InterruptedException e) { - } - } - if (mThumbnailCache != null) { - return mThumbnailCache.getBitmap(key); - } - } - return null; - } - + @Override public boolean areAllItemsEnabled() { return true; @@@ -116,27 -292,24 +117,27 @@@ public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { - LayoutInflater inflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflator = (LayoutInflater) mContext + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflator.inflate(R.layout.list_item, null); } - + if (mFiles != null && mFiles.size() > position) { OCFile file = mFiles.get(position); - TextView fileName = (TextView) view.findViewById(R.id.Filename); + TextView fileName = (TextView) view.findViewById(R.id.Filename); String name = file.getFileName(); fileName.setText(name); ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1); + fileIcon.setTag(file.getFileId()); ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon); sharedWithMeIconV.setVisibility(View.GONE); ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2); localStateView.bringToFront(); - FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder(); + FileDownloaderBinder downloaderBinder = + mTransferServiceGetter.getFileDownloaderBinder(); FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) { localStateView.setImageResource(R.drawable.downloading_file_indicator); @@@ -150,28 -323,27 +151,28 @@@ } else { localStateView.setVisibility(View.INVISIBLE); } - + TextView fileSizeV = (TextView) view.findViewById(R.id.file_size); TextView lastModV = (TextView) view.findViewById(R.id.last_mod); ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox); - + if (!file.isFolder()) { fileSizeV.setVisibility(View.VISIBLE); fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); lastModV.setVisibility(View.VISIBLE); - lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())); - // this if-else is needed even thoe fav icon is visible by - // default + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); + // this if-else is needed even thoe fav icon is visible by default // because android reuses views in listview if (!file.keepInSync()) { view.findViewById(R.id.imageView3).setVisibility(View.GONE); } else { view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE); } - - ListView parentList = (ListView) parent; - if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { + + ListView parentList = (ListView)parent; + if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) { checkBoxV.setVisibility(View.GONE); } else { if (parentList.isItemChecked(position)) { @@@ -180,52 -352,36 +181,52 @@@ checkBoxV.setImageResource(android.R.drawable.checkbox_off_background); } checkBoxV.setVisibility(View.VISIBLE); - } - + } + // get Thumbnail if file is image - if (file.isImage()) { - // Thumbnail in Cache? - Bitmap thumbnail = getBitmapFromDiskCache(String.valueOf(file.getRemoteId().hashCode())); - if (thumbnail != null) { + if (file.isImage() && file.getRemoteId() != null){ + // Thumbnail in Cache? + Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( + String.valueOf(file.getRemoteId()) + ); + if (thumbnail != null && !file.needsUpdateThumbnail()){ fileIcon.setImageBitmap(thumbnail); } else { // generate new Thumbnail - if (cancelPotentialWork(file, fileIcon)) { - final ThumbnailGenerationTask task = new ThumbnailGenerationTask(fileIcon); - final AsyncDrawable asyncDrawable = new AsyncDrawable(mContext.getResources(), defaultImg, - task); + if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) { + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask( + fileIcon, mStorageManager + ); + if (thumbnail == null) { + thumbnail = ThumbnailsCacheManager.mDefaultImg; + } + final AsyncDrawable asyncDrawable = new AsyncDrawable( + mContext.getResources(), + thumbnail, + task + ); fileIcon.setImageDrawable(asyncDrawable); task.execute(file); } } } else { - fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); } - + if (checkIfFileIsSharedWithMe(file)) { sharedWithMeIconV.setVisibility(View.VISIBLE); } - } else { + } + else { fileSizeV.setVisibility(View.INVISIBLE); - // fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); + //fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength())); lastModV.setVisibility(View.VISIBLE); - lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp())); + lastModV.setText( + DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()) + ); checkBoxV.setVisibility(View.GONE); view.findViewById(R.id.imageView3).setVisibility(View.GONE); @@@ -233,9 -389,7 +234,9 @@@ fileIcon.setImageResource(R.drawable.shared_with_me_folder); sharedWithMeIconV.setVisibility(View.VISIBLE); } else { - fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())); + fileIcon.setImageResource( + DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()) + ); } // If folder is sharedByLink, icon folder must be changed to @@@ -254,7 -408,37 +255,7 @@@ return view; } - - public static boolean cancelPotentialWork(OCFile file, ImageView imageView) { - final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final OCFile bitmapData = bitmapWorkerTask.file; - // 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; - } - - private 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; - } - + @Override public int getViewTypeCount() { return 1; @@@ -272,10 -456,11 +273,10 @@@ /** * Change the adapted directory for a new one - * - * @param directory New file to adapt. Can be NULL, meaning - * "no content to adapt". - * @param updatedStorageManager Optional updated storage manager; used to - * replace mStorageManager if is different (and not NULL) + * @param directory New file to adapt. Can be NULL, meaning + * "no content to adapt". + * @param updatedStorageManager Optional updated storage manager; used to replace + * mStorageManager if is different (and not NULL) */ public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager) { mFile = directory; @@@ -293,17 -478,17 +294,17 @@@ } notifyDataSetChanged(); } - + + /** * Filter for getting only the folders - * * @param files * @return Vector */ public Vector getFolders(Vector files) { - Vector ret = new Vector(); - OCFile current = null; - for (int i = 0; i < files.size(); i++) { + Vector ret = new Vector(); + OCFile current = null; + for (int i=0; i