Merge branch 'zmatsuo-detailThumbnail' into develop
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewMediaFragment.java
index c5883cf..0dbb1a3 100644 (file)
@@ -21,7 +21,10 @@ package com.owncloud.android.ui.preview;
 
 import android.accounts.Account;
 import android.app.Activity;
-import android.app.AlertDialog;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaMetadataRetriever;
+import android.support.v7.app.AlertDialog;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -64,7 +67,7 @@ import com.owncloud.android.ui.fragment.FileFragment;
 
 /**
  * This fragment shows a preview of a downloaded media file (audio or video).
- * 
+ *
  * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will
  * produce an {@link IllegalStateException}.
  * 
@@ -84,46 +87,46 @@ public class PreviewMediaFragment extends FileFragment implements
     private ImageView mImagePreview;
     private VideoView mVideoPreview;
     private int mSavedPlaybackPosition;
-    
+
     private MediaServiceBinder mMediaServiceBinder = null;
     private MediaControlView mMediaController = null;
     private MediaServiceConnection mMediaServiceConnection = null;
     private VideoHelper mVideoHelper;
     private boolean mAutoplay;
     public boolean mPrepared;
-    
+
     private static final String TAG = PreviewMediaFragment.class.getSimpleName();
 
-    
+
     /**
      * Creates a fragment to preview a file.
-     * 
+     * <p/>
      * When 'fileToDetail' or 'ocAccount' are null
-     * 
-     * @param fileToDetail      An {@link OCFile} to preview in the fragment
-     * @param ocAccount         An ownCloud account; needed to start downloads
+     *
+     * @param fileToDetail An {@link OCFile} to preview in the fragment
+     * @param ocAccount    An ownCloud account; needed to start downloads
      */
     public PreviewMediaFragment(
-            OCFile fileToDetail, 
-            Account ocAccount, 
-            int startPlaybackPosition, 
+            OCFile fileToDetail,
+            Account ocAccount,
+            int startPlaybackPosition,
             boolean autoplay) {
-        
+
         super(fileToDetail);
         mAccount = ocAccount;
         mSavedPlaybackPosition = startPlaybackPosition;
         mAutoplay = autoplay;
     }
-    
-    
+
+
     /**
-     *  Creates an empty fragment for previews.
-     * 
-     *  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 
+     * Creates an empty fragment for previews.
+     * <p/>
+     * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
+     * (for instance, when the device is turned a aside).
+     * <p/>
+     * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
+     * construction
      */
     public PreviewMediaFragment() {
         super();
@@ -131,8 +134,8 @@ public class PreviewMediaFragment extends FileFragment implements
         mSavedPlaybackPosition = 0;
         mAutoplay = true;
     }
-    
-    
+
+
     /**
      * {@inheritDoc}
      */
@@ -141,29 +144,29 @@ public class PreviewMediaFragment extends FileFragment implements
         super.onCreate(savedInstanceState);
         setHasOptionsMenu(true);
     }
-    
+
 
     /**
      * {@inheritDoc}
      */
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
+                             Bundle savedInstanceState) {
         super.onCreateView(inflater, container, savedInstanceState);
         Log_OC.e(TAG, "onCreateView");
 
-        
+
         mView = inflater.inflate(R.layout.file_preview, container, false);
-        
-        mImagePreview = (ImageView)mView.findViewById(R.id.image_preview);
-        mVideoPreview = (VideoView)mView.findViewById(R.id.video_preview);
+
+        mImagePreview = (ImageView) mView.findViewById(R.id.image_preview);
+        mVideoPreview = (VideoView) mView.findViewById(R.id.video_preview);
         mVideoPreview.setOnTouchListener(this);
-        
-        mMediaController = (MediaControlView)mView.findViewById(R.id.media_controller);
-        
+
+        mMediaController = (MediaControlView) mView.findViewById(R.id.media_controller);
+
         return mView;
     }
-    
+
 
     /**
      * {@inheritDoc}
@@ -184,30 +187,56 @@ public class PreviewMediaFragment extends FileFragment implements
             if (!file.isDown()) {
                 throw new IllegalStateException("There is no local file to preview");
             }
-            
-        } else {
-            file = (OCFile)savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE);
+
+        }
+        else {
+            file = (OCFile) savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE);
             setFile(file);
             mAccount = savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_ACCOUNT);
-            mSavedPlaybackPosition = 
+            mSavedPlaybackPosition =
                     savedInstanceState.getInt(PreviewMediaFragment.EXTRA_PLAY_POSITION);
             mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING);
-            
+
         }
         if (file != null && file.isDown()) {
             if (file.isVideo()) {
                 mVideoPreview.setVisibility(View.VISIBLE);
                 mImagePreview.setVisibility(View.GONE);
                 prepareVideo();
-            
-            } else {
+
+            }
+            else {
                 mVideoPreview.setVisibility(View.GONE);
                 mImagePreview.setVisibility(View.VISIBLE);
+                extractAndSetCoverArt(file);
             }
         }
-        
+
     }
-        
+
+    /**
+     * tries to read the cover art from the audio file and sets it as cover art.
+     *
+     * @param file audio file with potential cover art
+     */
+    private void extractAndSetCoverArt(OCFile file) {
+        if (file.isAudio()) {
+            try {
+                MediaMetadataRetriever mmr = new MediaMetadataRetriever();
+                mmr.setDataSource(file.getStoragePath());
+                byte[] data = mmr.getEmbeddedPicture();
+                if (data != null) {
+                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                    mImagePreview.setImageBitmap(bitmap); //associated cover art in bitmap
+                } else {
+                    mImagePreview.setImageResource(R.drawable.logo);
+                }
+            } catch (Throwable t) {
+                mImagePreview.setImageResource(R.drawable.logo);
+            }
+        }
+    }
+
 
     /**
      * {@inheritDoc}
@@ -216,24 +245,25 @@ public class PreviewMediaFragment extends FileFragment implements
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         Log_OC.e(TAG, "onSaveInstanceState");
-        
+
         outState.putParcelable(PreviewMediaFragment.EXTRA_FILE, getFile());
         outState.putParcelable(PreviewMediaFragment.EXTRA_ACCOUNT, mAccount);
-        
+
         if (getFile().isVideo()) {
             mSavedPlaybackPosition = mVideoPreview.getCurrentPosition();
             mAutoplay = mVideoPreview.isPlaying();
-            outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION , mSavedPlaybackPosition);
-            outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING , mAutoplay);
-        } else {
+            outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION, mSavedPlaybackPosition);
+            outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING, mAutoplay);
+        }
+        else {
             outState.putInt(
-                    PreviewMediaFragment.EXTRA_PLAY_POSITION , 
+                    PreviewMediaFragment.EXTRA_PLAY_POSITION,
                     mMediaServiceBinder.getCurrentPosition());
             outState.putBoolean(
-                    PreviewMediaFragment.EXTRA_PLAYING , mMediaServiceBinder.isPlaying());
+                    PreviewMediaFragment.EXTRA_PLAYING, mMediaServiceBinder.isPlaying());
         }
     }
-    
+
 
     @Override
     public void onStart() {
@@ -242,17 +272,20 @@ public class PreviewMediaFragment extends FileFragment implements
 
         OCFile file = getFile();
         if (file != null && file.isDown()) {
-           if (file.isAudio()) {
-               bindMediaService();
-               
-           } else if (file.isVideo()) {
-               stopAudio();
-               playVideo(); 
-           }
+            if (file.isAudio()) {
+                bindMediaService();
+
+            }
+            else {
+                if (file.isVideo()) {
+                    stopAudio();
+                    playVideo();
+                }
+            }
         }
     }
-    
-    
+
+
     private void stopAudio() {
         Intent i = new Intent(getActivity(), MediaService.class);
         i.setAction(MediaService.ACTION_STOP_ALL);
@@ -276,7 +309,7 @@ public class PreviewMediaFragment extends FileFragment implements
     @Override
     public void onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
-        
+
         if (mContainerActivity.getStorageManager() != null) {
             FileMenuFilter mf = new FileMenuFilter(
                 getFile(),
@@ -301,9 +334,16 @@ public class PreviewMediaFragment extends FileFragment implements
             item.setVisible(false);
             item.setEnabled(false);
         }
+
+        // additional restriction for this fragment
+        item = menu.findItem(R.id.action_copy);
+        if (item != null) {
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
     }
-    
-    
+
+
     /**
      * {@inheritDoc}
      */
@@ -341,31 +381,38 @@ public class PreviewMediaFragment extends FileFragment implements
                 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
                 return true;
             }
-
+            case R.id.action_favorite_file:{
+                mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), true);
+                return true;
+            }
+            case R.id.action_unfavorite_file:{
+                mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false);
+                return true;
+            }
             default:
                 return false;
         }
     }
-    
 
 
     /**
      * Update the file of the fragment with file value
+     *
      * @param file
      */
-    public void updateFile(OCFile file){
+    public void updateFile(OCFile file) {
         setFile(file);
     }
-    
+
     private void sendFile() {
         stopPreview(false);
         mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
-        
+
     }
 
     private void seeDetails() {
         stopPreview(false);
-        mContainerActivity.showDetails(getFile());        
+        mContainerActivity.showDetails(getFile());
     }
 
 
@@ -376,77 +423,80 @@ public class PreviewMediaFragment extends FileFragment implements
         mVideoPreview.setOnCompletionListener(mVideoHelper);
         mVideoPreview.setOnErrorListener(mVideoHelper);
     }
-    
+
     @SuppressWarnings("static-access")
     private void playVideo() {
         // create and prepare control panel for the user
         mMediaController.setMediaPlayer(mVideoPreview);
-        
+
         // load the video file in the video player ; 
         // when done, VideoHelper#onPrepared() will be called
         Uri uri = Uri.parse(getFile().getStoragePath());
         mVideoPreview.setVideoPath(uri.encode(getFile().getStoragePath()));
     }
-    
+
 
     private class VideoHelper implements OnCompletionListener, OnPreparedListener, OnErrorListener {
-        
-        /** 
+
+        /**
          * Called when the file is ready to be played.
-         * 
+         * <p/>
          * Just starts the playback.
-         * 
+         *
          * @param   vp    {@link MediaPlayer} instance performing the playback.
          */
         @Override
         public void onPrepared(MediaPlayer vp) {
             Log_OC.e(TAG, "onPrepared");
             mVideoPreview.seekTo(mSavedPlaybackPosition);
-            if (mAutoplay) { 
+            if (mAutoplay) {
                 mVideoPreview.start();
             }
             mMediaController.setEnabled(true);
             mMediaController.updatePausePlay();
             mPrepared = true;
         }
-        
-        
+
+
         /**
          * Called when the file is finished playing.
-         *  
+         * <p/>
          * Finishes the activity.
-         * 
-         * @param   mp    {@link MediaPlayer} instance performing the playback.
+         *
+         * @param mp {@link MediaPlayer} instance performing the playback.
          */
         @Override
-        public void onCompletion(MediaPlayer  mp) {
+        public void onCompletion(MediaPlayer mp) {
             Log_OC.e(TAG, "completed");
             if (mp != null) {
                 mVideoPreview.seekTo(0);
                 // next lines are necessary to work around undesired video loops
                 if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD) {
-                    mVideoPreview.pause();   
-                    
-                } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) {
-                    // mVideePreview.pause() is not enough
-                    
-                    mMediaController.setEnabled(false);
-                    mVideoPreview.stopPlayback();
-                    mAutoplay = false;
-                    mSavedPlaybackPosition = 0;
-                    mVideoPreview.setVideoPath(getFile().getStoragePath());
+                    mVideoPreview.pause();
+
+                }
+                else {
+                    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) {
+                        // mVideePreview.pause() is not enough
+
+                        mMediaController.setEnabled(false);
+                        mVideoPreview.stopPlayback();
+                        mAutoplay = false;
+                        mSavedPlaybackPosition = 0;
+                        mVideoPreview.setVideoPath(getFile().getStoragePath());
+                    }
                 }
             } // else : called from onError()
             mMediaController.updatePausePlay();
         }
-        
-        
+
+
         /**
          * Called when an error in playback occurs.
-         * 
-         * @param   mp      {@link MediaPlayer} instance performing the playback.
-         * @param   what    Type of error
-         * @param   extra   Extra code specific to the error
+         *
+         * @param mp    {@link MediaPlayer} instance performing the playback.
+         * @param what  Type of error
+         * @param extra Extra code specific to the error
          */
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
@@ -467,28 +517,28 @@ public class PreviewMediaFragment extends FileFragment implements
             }
             return true;
         }
-        
+
     }
 
-    
+
     @Override
     public void onPause() {
         Log_OC.e(TAG, "onPause");
         super.onPause();
     }
-    
+
     @Override
     public void onResume() {
         super.onResume();
         Log_OC.e(TAG, "onResume");
     }
-    
+
     @Override
     public void onDestroy() {
         Log_OC.e(TAG, "onDestroy");
         super.onDestroy();
     }
-    
+
     @Override
     public void onStop() {
         Log_OC.e(TAG, "onStop");
@@ -503,10 +553,10 @@ public class PreviewMediaFragment extends FileFragment implements
             mMediaServiceConnection = null;
             mMediaServiceBinder = null;
         }
-        
+
         super.onStop();
     }
-    
+
     @Override
     public boolean onTouch(View v, MotionEvent event) {
         if (event.getAction() == MotionEvent.ACTION_DOWN && v == mVideoPreview) {
@@ -519,7 +569,7 @@ public class PreviewMediaFragment extends FileFragment implements
         return false;
     }
 
-    
+
     private void startFullScreenVideo() {
         Intent i = new Intent(getActivity(), PreviewVideoActivity.class);
         i.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount);
@@ -531,29 +581,30 @@ public class PreviewMediaFragment extends FileFragment implements
     }
 
     @Override
-    public void onConfigurationChanged (Configuration newConfig) {
+    public void onConfigurationChanged(Configuration newConfig) {
         Log_OC.e(TAG, "onConfigurationChanged " + this);
     }
-    
+
     @Override
-    public void onActivityResult (int requestCode, int resultCode, Intent data) {
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         Log_OC.e(TAG, "onActivityResult " + this);
         super.onActivityResult(requestCode, resultCode, data);
         if (resultCode == Activity.RESULT_OK) {
             mSavedPlaybackPosition = data.getExtras().getInt(
                     PreviewVideoActivity.EXTRA_START_POSITION);
-            mAutoplay = data.getExtras().getBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY); 
+            mAutoplay = data.getExtras().getBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY);
         }
     }
-    
+
 
     private void playAudio() {
         OCFile file = getFile();
         if (!mMediaServiceBinder.isPlaying(file)) {
             Log_OC.d(TAG, "starting playback of " + file.getStoragePath());
             mMediaServiceBinder.start(mAccount, file, mAutoplay, mSavedPlaybackPosition);
-            
-        } else {
+
+        }
+        else {
             if (!mMediaServiceBinder.isPlaying() && mAutoplay) {
                 mMediaServiceBinder.start();
                 mMediaController.updatePausePlay();
@@ -590,7 +641,8 @@ public class PreviewMediaFragment extends FileFragment implements
 
                         Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready");
 
-                    } else {
+                    }
+                    else {
                         Log_OC.e(TAG, "Unexpected response from MediaService while binding");
                     }
                 }
@@ -612,7 +664,8 @@ public class PreviewMediaFragment extends FileFragment implements
                 Log_OC.e(TAG, "Media service suddenly disconnected");
                 if (mMediaController != null) {
                     mMediaController.setMediaPlayer(null);
-                } else {
+                }
+                else {
                     Toast.makeText(
                             getActivity(),
                             "No media controller to release when disconnected from media service", 
@@ -622,9 +675,8 @@ public class PreviewMediaFragment extends FileFragment implements
                 mMediaServiceConnection = null;
             }
         }
-    }    
+    }
 
-    
 
     /**
      * Opens the previewed file with an external application.
@@ -634,31 +686,33 @@ public class PreviewMediaFragment extends FileFragment implements
         mContainerActivity.getFileOperationsHelper().openFile(getFile());
         finish();
     }
-    
+
     /**
      * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewMediaFragment}
-     *  to be previewed.
-     * 
-     * @param file      File to test if can be previewed.
-     * @return          'True' if the file can be handled by the fragment.
+     * to be previewed.
+     *
+     * @param file File to test if can be previewed.
+     * @return 'True' if the file can be handled by the fragment.
      */
     public static boolean canBePreviewed(OCFile file) {
         return (file != null && (file.isAudio() || file.isVideo()));
     }
-    
+
 
     public void stopPreview(boolean stopAudio) {
         OCFile file = getFile();
         if (file.isAudio() && stopAudio) {
             mMediaServiceBinder.pause();
-            
-        } else if (file.isVideo()) {
-            mVideoPreview.stopPlayback();
+
+        }
+        else {
+            if (file.isVideo()) {
+                mVideoPreview.stopPlayback();
+            }
         }
     }
 
 
-
     /**
      * Finishes the preview
      */
@@ -674,12 +728,12 @@ public class PreviewMediaFragment extends FileFragment implements
         Log_OC.e(TAG, "getting position: " + mSavedPlaybackPosition);
         return mSavedPlaybackPosition;
     }
-    
+
     public boolean isPlaying() {
         if (mPrepared) {
             mAutoplay = mVideoPreview.isPlaying();
         }
         return mAutoplay;
     }
-    
+
 }