Merge branch 'develop' into navigation_drawer
authormasensio <masensio@solidgear.es>
Thu, 21 May 2015 07:46:59 +0000 (09:46 +0200)
committermasensio <masensio@solidgear.es>
Thu, 21 May 2015 07:46:59 +0000 (09:46 +0200)
Conflicts:
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

1  2 
src/com/owncloud/android/ui/preview/PreviewImageActivity.java
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@@ -63,9 -63,9 +63,9 @@@ import com.owncloud.android.utils.Displ
  /**
   *  Holds a swiping galley where image files contained in an ownCloud directory are shown
   */
--public class PreviewImageActivity extends FileActivity implements 
-- FileFragment.ContainerActivity,
--ViewPager.OnPageChangeListener, OnRemoteOperationListener {
++public class PreviewImageActivity extends FileActivity implements
++        FileFragment.ContainerActivity,
++        ViewPager.OnPageChangeListener, OnRemoteOperationListener {
      
      public static final int DIALOG_SHORT_WAIT = 0;
  
@@@ -37,11 -29,7 +29,10 @@@ import android.graphics.Point
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.support.v4.app.FragmentStatePagerAdapter;
- import android.view.Display;
  import android.view.LayoutInflater;
 +import android.view.Menu;
 +import android.view.MenuInflater;
 +import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.view.ViewGroup;
@@@ -63,12 -55,10 +55,12 @@@ import third_parties.michaelOrtiz.Touch
  
  /**
   * This fragment shows a preview of a downloaded image.
-  * 
-  * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will
-  * produce an {@link IllegalStateException}.
++ *
++ * Trying to get an instance with a NULL {@link OCFile} will produce an
++ * {@link IllegalStateException}.
   * 
 - * Trying to get an instance with a NULL {@link OCFile} will produce an {@link IllegalStateException}.
 - * 
 - * If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
 + * If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on
 + * instantiation too.
   */
  public class PreviewImageFragment extends FileFragment {
  
      
      private LoadBitmapTask mLoadBitmapTask = null;
  
-     
      /**
-      * Creates a fragment to preview an image.
-      * 
-      * When 'imageFile' or 'ocAccount' are null
-      * 
-      * @param fileToDetail                 An {@link OCFile} to preview as an image in the fragment
-      * @param ocAccount                 An ownCloud account; needed to start downloads
+      * Public factory method to create a new fragment that previews an image.
+      *
 -     * Android strongly recommends keep the empty constructor of fragments as the only public constructor, and
++     * Android strongly recommends keep the empty constructor of fragments as the only public
++     * constructor, and
+      * use {@link #setArguments(Bundle)} to set the needed arguments.
+      *
+      * This method hides to client objects the need of doing the construction in two steps.
+      *
+      * @param imageFile                 An {@link OCFile} to preview as an image in the fragment
 -     * @param ignoreFirstSavedState     Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter}
 +     * @param ignoreFirstSavedState     Flag to work around an unexpected behaviour of
-      *                                  {@link FragmentStatePagerAdapter}; TODO better solution
++     *                                  {@link FragmentStatePagerAdapter}
+      *                                  ; TODO better solution
       */
-     public PreviewImageFragment(OCFile fileToDetail, Account ocAccount,
-                                 boolean ignoreFirstSavedState) {
-         super(fileToDetail);
-         mAccount = ocAccount;
-         mIgnoreFirstSavedState = ignoreFirstSavedState;
 -    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState) {
++    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){
+         PreviewImageFragment frag = new PreviewImageFragment();
+         Bundle args = new Bundle();
+         args.putParcelable(ARG_FILE, imageFile);
+         args.putBoolean(ARG_IGNORE_FIRST, ignoreFirstSavedState);
+         frag.setArguments(args);
+         return frag;
      }
      
      
      /**
       *  MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
       *  (for instance, when the device is turned a aside).
       * 
 -     *  DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful construction 
 +     *  DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
 +     *  construction
       */
      public PreviewImageFragment() {
-         super();
-         mAccount = null;
          mIgnoreFirstSavedState = false;
      }
      
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
 -            // TODO better in super, but needs to check ALL the class extending FileFragment; not right now
+         Bundle args = getArguments();
+         setFile((OCFile)args.getParcelable(ARG_FILE));
++            // TODO better in super, but needs to check ALL the class extending FileFragment;
++            // not right now
+         mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST);
          setHasOptionsMenu(true);
      }
      
          if (mBitmap != null) {
              mBitmap.recycle();
              System.gc();
 -                // {@link FragmentStatePagerAdapter} when the fragment in swiped further than the valid offscreen
 -                // distance, and onStop() is never called before than that
+                 // putting this in onStop() is just the same; the fragment is always destroyed by
++                // {@link FragmentStatePagerAdapter} when the fragment in swiped further than the
++                // valid offscreen distance, and onStop() is never called before than that
          }
          super.onDestroy();
      }
  
          /**
           * Weak reference to the target {@link ImageView} where the bitmap will be loaded into.
--         * 
 -         * Using a weak reference will avoid memory leaks if the target ImageView is retired from memory before
 -         * the load finishes.
++         *
 +         * Using a weak reference will avoid memory leaks if the target ImageView is retired from
 +         * memory before the load finishes.
           */
          private final WeakReference<ImageViewCustom> mImageViewRef;
  
          /**
           * Weak reference to the target {@link TextView} where error messages will be written.
--         * 
 -         * Using a weak reference will avoid memory leaks if the target ImageView is retired from memory before the
 -         * load finishes.
++         *
 +         * Using a weak reference will avoid memory leaks if the target ImageView is retired from
 +         * memory before the load finishes.
           */
          private final WeakReference<TextView> mMessageViewRef;
  
              String storagePath = params[0];
              try {
  
-                 if (isCancelled()) return result;
-                 
-                 File picture = new File(storagePath);
-                 if (picture != null) {
-                     // Decode file into a bitmap in real size for being able to make zoom on 
-                     // the image
-                     result = BitmapFactory.decodeStream(new FlushedInputStream
-                             (new BufferedInputStream(new FileInputStream(picture))));
+                 int maxDownScale = 3;   // could be a parameter passed to doInBackground(...)
+                 Point screenSize = DisplayUtils.getScreenSize(getActivity());
+                 int minWidth = screenSize.x;
+                 int minHeight = screenSize.y;
+                 for (int i = 0; i < maxDownScale && result == null; i++) {
+                     if (isCancelled()) return null;
+                     try {
 -                        result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth, minHeight);
++                        result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth,
++                                minHeight);
+                         if (isCancelled()) return result;
+                         if (result == null) {
+                             mErrorMessageId = R.string.preview_image_error_unknown_format;
+                             Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+                             break;
+                         } else {
+                             // Rotate image, obeying exif tag.
+                             result = BitmapUtils.rotateImage(result, storagePath);
+                         }
+                     } catch (OutOfMemoryError e) {
+                         mErrorMessageId = R.string.common_error_out_memory;
+                         if (i < maxDownScale - 1) {
 -                            Log_OC.w(TAG, "Out of memory rendering file " + storagePath + " ; scaling down");
++                            Log_OC.w(TAG, "Out of memory rendering file " + storagePath +
++                                    " ; scaling down");
+                             minWidth = minWidth / 2;
+                             minHeight = minHeight / 2;
+                         } else {
 -                            Log_OC.w(TAG, "Out of memory rendering file " + storagePath + " ; failing");
++                            Log_OC.w(TAG, "Out of memory rendering file " + storagePath +
++                                    " ; failing");
+                         }
+                         if (result != null) {
+                             result.recycle();
+                         }
+                         result = null;
+                     }
                  }
  
-                 if (isCancelled()) return result;
-                 
-                 if (result == null) {
-                     mErrorMessageId = R.string.preview_image_error_unknown_format;
-                     Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
-                 } else {
-                     // Rotate image, obeying exif tag.
-                     result = BitmapUtils.rotateImage(result, storagePath);
-                 }
-                 
-             } catch (OutOfMemoryError e) {
-                 Log_OC.e(TAG, "Out of memory occured for file " + storagePath, e);
-                 if (isCancelled()) return result;
-                 
-                 // If out of memory error when loading or rotating image, try to load it scaled
-                 result = loadScaledImage(storagePath);
-                 if (result == null) {
-                     mErrorMessageId = R.string.preview_image_error_unknown_format;
-                     Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
-                 } else {
-                     // Rotate scaled image, obeying exif tag
-                     result = BitmapUtils.rotateImage(result, storagePath);
-                 }
-                     
              } catch (NoSuchFieldError e) {
                  mErrorMessageId = R.string.common_error_unknown;
                  Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " 
          
          @SuppressLint("InlinedApi")
          private void showLoadedImage(Bitmap result) {
-             if (mImageViewRef != null) {
-                 final ImageViewCustom imageView = mImageViewRef.get();
-                 if (imageView != null) {
-                     imageView.setBitmap(result);
-                     imageView.setImageBitmap(result);
-                     imageView.setVisibility(View.VISIBLE);
-                     mBitmap  = result;
-                 } // else , silently finish, the fragment was destroyed
-             }
-             if (mMessageViewRef != null) {
-                 final TextView messageView = mMessageViewRef.get();
-                 if (messageView != null) {
-                     messageView.setVisibility(View.GONE);
-                 } // else , silently finish, the fragment was destroyed
+             final ImageViewCustom imageView = mImageViewRef.get();
+             if (imageView != null) {
 -                Log_OC.d(TAG, "Showing image with resolution " + result.getWidth() + "x" + result.getHeight());
++                Log_OC.d(TAG, "Showing image with resolution " + result.getWidth() + "x" +
++                        result.getHeight());
+                 imageView.setImageBitmap(result);
+                 imageView.setVisibility(View.VISIBLE);
+                 mBitmap  = result;  // needs to be kept for recycling when not useful
              }
+             final TextView messageView = mMessageViewRef.get();
+             if (messageView != null) {
+                 messageView.setVisibility(View.GONE);
+             } // else , silently finish, the fragment was destroyed
          }
          
          private void showErrorMessage() {