Fixed initialization of database tracking pending instant uploads
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewMediaFragment.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012-2013 ownCloud Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17 package com.owncloud.android.ui.preview;
18
19 import java.io.File;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import android.accounts.Account;
24 import android.app.Activity;
25 import android.app.AlertDialog;
26 import android.content.ActivityNotFoundException;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.DialogInterface;
30 import android.content.Intent;
31 import android.content.ServiceConnection;
32 import android.content.res.Configuration;
33 import android.media.MediaPlayer;
34 import android.media.MediaPlayer.OnCompletionListener;
35 import android.media.MediaPlayer.OnErrorListener;
36 import android.media.MediaPlayer.OnPreparedListener;
37 import android.net.Uri;
38 import android.os.Build;
39 import android.os.Bundle;
40 import android.os.Handler;
41 import android.os.IBinder;
42 import android.view.LayoutInflater;
43 import android.view.MotionEvent;
44 import android.view.View;
45 import android.view.View.OnTouchListener;
46 import android.view.ViewGroup;
47 import android.webkit.MimeTypeMap;
48 import android.widget.ImageView;
49 import android.widget.Toast;
50 import android.widget.VideoView;
51
52 import com.actionbarsherlock.view.Menu;
53 import com.actionbarsherlock.view.MenuInflater;
54 import com.actionbarsherlock.view.MenuItem;
55 import com.owncloud.android.Log_OC;
56 import com.owncloud.android.R;
57 import com.owncloud.android.datamodel.FileDataStorageManager;
58 import com.owncloud.android.datamodel.OCFile;
59 import com.owncloud.android.media.MediaControlView;
60 import com.owncloud.android.media.MediaService;
61 import com.owncloud.android.media.MediaServiceBinder;
62 import com.owncloud.android.operations.OnRemoteOperationListener;
63 import com.owncloud.android.operations.RemoteOperation;
64 import com.owncloud.android.operations.RemoteOperationResult;
65 import com.owncloud.android.operations.RemoveFileOperation;
66 import com.owncloud.android.ui.activity.FileActivity;
67 import com.owncloud.android.ui.activity.FileDisplayActivity;
68 import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
69 import com.owncloud.android.ui.fragment.FileFragment;
70
71 import eu.alefzero.webdav.WebdavUtils;
72
73 /**
74 * This fragment shows a preview of a downloaded media file (audio or video).
75 *
76 * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will produce an {@link IllegalStateException}.
77 *
78 * By now, if the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
79 *
80 * @author David A. Velasco
81 */
82 public class PreviewMediaFragment extends FileFragment implements
83 OnTouchListener,
84 ConfirmationDialogFragment.ConfirmationDialogFragmentListener, OnRemoteOperationListener {
85
86 public static final String EXTRA_FILE = "FILE";
87 public static final String EXTRA_ACCOUNT = "ACCOUNT";
88 private static final String EXTRA_PLAY_POSITION = "PLAY_POSITION";
89 private static final String EXTRA_PLAYING = "PLAYING";
90
91 private View mView;
92 private Account mAccount;
93 private FileDataStorageManager mStorageManager;
94 private ImageView mImagePreview;
95 private VideoView mVideoPreview;
96 private int mSavedPlaybackPosition;
97
98 private Handler mHandler;
99 private RemoteOperation mLastRemoteOperation;
100
101 private MediaServiceBinder mMediaServiceBinder = null;
102 private MediaControlView mMediaController = null;
103 private MediaServiceConnection mMediaServiceConnection = null;
104 private VideoHelper mVideoHelper;
105 private boolean mAutoplay;
106 public boolean mPrepared;
107
108 private static final String TAG = PreviewMediaFragment.class.getSimpleName();
109
110
111 /**
112 * Creates a fragment to preview a file.
113 *
114 * When 'fileToDetail' or 'ocAccount' are null
115 *
116 * @param fileToDetail An {@link OCFile} to preview in the fragment
117 * @param ocAccount An ownCloud account; needed to start downloads
118 */
119 public PreviewMediaFragment(OCFile fileToDetail, Account ocAccount, int startPlaybackPosition, boolean autoplay) {
120 super(fileToDetail);
121 mAccount = ocAccount;
122 mSavedPlaybackPosition = startPlaybackPosition;
123 mStorageManager = null; // we need a context to init this; the container activity is not available yet at this moment
124 mAutoplay = autoplay;
125 }
126
127
128 /**
129 * Creates an empty fragment for previews.
130 *
131 * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically (for instance, when the device is turned a aside).
132 *
133 * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful construction
134 */
135 public PreviewMediaFragment() {
136 super();
137 mAccount = null;
138 mSavedPlaybackPosition = 0;
139 mStorageManager = null;
140 mAutoplay = true;
141 }
142
143
144 /**
145 * {@inheritDoc}
146 */
147 @Override
148 public void onCreate(Bundle savedInstanceState) {
149 super.onCreate(savedInstanceState);
150 mHandler = new Handler();
151 setHasOptionsMenu(true);
152 }
153
154
155 /**
156 * {@inheritDoc}
157 */
158 @Override
159 public View onCreateView(LayoutInflater inflater, ViewGroup container,
160 Bundle savedInstanceState) {
161 super.onCreateView(inflater, container, savedInstanceState);
162 Log_OC.e(TAG, "onCreateView");
163
164
165 mView = inflater.inflate(R.layout.file_preview, container, false);
166
167 mImagePreview = (ImageView)mView.findViewById(R.id.image_preview);
168 mVideoPreview = (VideoView)mView.findViewById(R.id.video_preview);
169 mVideoPreview.setOnTouchListener(this);
170
171 mMediaController = (MediaControlView)mView.findViewById(R.id.media_controller);
172
173 return mView;
174 }
175
176
177 /**
178 * {@inheritDoc}
179 */
180 @Override
181 public void onAttach(Activity activity) {
182 super.onAttach(activity);
183 Log_OC.e(TAG, "onAttach");
184
185 if (!(activity instanceof FileFragment.ContainerActivity))
186 throw new ClassCastException(activity.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName());
187 }
188
189
190 /**
191 * {@inheritDoc}
192 */
193 @Override
194 public void onActivityCreated(Bundle savedInstanceState) {
195 super.onActivityCreated(savedInstanceState);
196 Log_OC.e(TAG, "onActivityCreated");
197
198 mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
199 if (savedInstanceState != null) {
200 setFile((OCFile)savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE));
201 mAccount = savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_ACCOUNT);
202 mSavedPlaybackPosition = savedInstanceState.getInt(PreviewMediaFragment.EXTRA_PLAY_POSITION);
203 mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING);
204
205 }
206 OCFile file = getFile();
207 if (file == null) {
208 throw new IllegalStateException("Instanced with a NULL OCFile");
209 }
210 if (mAccount == null) {
211 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
212 }
213 if (!file.isDown()) {
214 throw new IllegalStateException("There is no local file to preview");
215 }
216 if (file.isVideo()) {
217 mVideoPreview.setVisibility(View.VISIBLE);
218 mImagePreview.setVisibility(View.GONE);
219 prepareVideo();
220
221 } else {
222 mVideoPreview.setVisibility(View.GONE);
223 mImagePreview.setVisibility(View.VISIBLE);
224 }
225
226 }
227
228
229 /**
230 * {@inheritDoc}
231 */
232 @Override
233 public void onSaveInstanceState(Bundle outState) {
234 super.onSaveInstanceState(outState);
235 Log_OC.e(TAG, "onSaveInstanceState");
236
237 outState.putParcelable(PreviewMediaFragment.EXTRA_FILE, getFile());
238 outState.putParcelable(PreviewMediaFragment.EXTRA_ACCOUNT, mAccount);
239
240 if (getFile().isVideo()) {
241 mSavedPlaybackPosition = mVideoPreview.getCurrentPosition();
242 mAutoplay = mVideoPreview.isPlaying();
243 outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION , mSavedPlaybackPosition);
244 outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING , mAutoplay);
245 } else {
246 outState.putInt(PreviewMediaFragment.EXTRA_PLAY_POSITION , mMediaServiceBinder.getCurrentPosition());
247 outState.putBoolean(PreviewMediaFragment.EXTRA_PLAYING , mMediaServiceBinder.isPlaying());
248 }
249 }
250
251
252 @Override
253 public void onStart() {
254 super.onStart();
255 Log_OC.e(TAG, "onStart");
256
257 OCFile file = getFile();
258 if (file != null) {
259 if (file.isAudio()) {
260 bindMediaService();
261
262 } else if (file.isVideo()) {
263 stopAudio();
264 playVideo();
265 }
266 }
267 }
268
269
270 private void stopAudio() {
271 Intent i = new Intent(getSherlockActivity(), MediaService.class);
272 i.setAction(MediaService.ACTION_STOP_ALL);
273 getSherlockActivity().startService(i);
274 }
275
276
277 /**
278 * {@inheritDoc}
279 */
280 @Override
281 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
282 super.onCreateOptionsMenu(menu, inflater);
283
284 inflater.inflate(R.menu.file_actions_menu, menu);
285 List<Integer> toHide = new ArrayList<Integer>();
286
287 MenuItem item = null;
288 toHide.add(R.id.action_cancel_download);
289 toHide.add(R.id.action_cancel_upload);
290 toHide.add(R.id.action_download_file);
291 toHide.add(R.id.action_sync_file);
292 toHide.add(R.id.action_rename_file); // by now
293
294 for (int i : toHide) {
295 item = menu.findItem(i);
296 if (item != null) {
297 item.setVisible(false);
298 item.setEnabled(false);
299 }
300 }
301
302 }
303
304
305 /**
306 * {@inheritDoc}
307 */
308 @Override
309 public boolean onOptionsItemSelected(MenuItem item) {
310 switch (item.getItemId()) {
311 case R.id.action_open_file_with: {
312 openFile();
313 return true;
314 }
315 case R.id.action_remove_file: {
316 removeFile();
317 return true;
318 }
319 case R.id.action_see_details: {
320 seeDetails();
321 return true;
322 }
323
324 default:
325 return false;
326 }
327 }
328
329
330 private void seeDetails() {
331 stopPreview(false);
332 ((FileFragment.ContainerActivity)getActivity()).showDetails(getFile());
333 }
334
335
336 private void prepareVideo() {
337 // create helper to get more control on the playback
338 mVideoHelper = new VideoHelper();
339 mVideoPreview.setOnPreparedListener(mVideoHelper);
340 mVideoPreview.setOnCompletionListener(mVideoHelper);
341 mVideoPreview.setOnErrorListener(mVideoHelper);
342 }
343
344 private void playVideo() {
345 // create and prepare control panel for the user
346 mMediaController.setMediaPlayer(mVideoPreview);
347
348 // load the video file in the video player ; when done, VideoHelper#onPrepared() will be called
349 mVideoPreview.setVideoPath(getFile().getStoragePath());
350 }
351
352
353 private class VideoHelper implements OnCompletionListener, OnPreparedListener, OnErrorListener {
354
355 /**
356 * Called when the file is ready to be played.
357 *
358 * Just starts the playback.
359 *
360 * @param mp {@link MediaPlayer} instance performing the playback.
361 */
362 @Override
363 public void onPrepared(MediaPlayer vp) {
364 Log_OC.e(TAG, "onPrepared");
365 mVideoPreview.seekTo(mSavedPlaybackPosition);
366 if (mAutoplay) {
367 mVideoPreview.start();
368 }
369 mMediaController.setEnabled(true);
370 mMediaController.updatePausePlay();
371 mPrepared = true;
372 }
373
374
375 /**
376 * Called when the file is finished playing.
377 *
378 * Finishes the activity.
379 *
380 * @param mp {@link MediaPlayer} instance performing the playback.
381 */
382 @Override
383 public void onCompletion(MediaPlayer mp) {
384 Log_OC.e(TAG, "completed");
385 if (mp != null) {
386 mVideoPreview.seekTo(0);
387 // next lines are necessary to work around undesired video loops
388 if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD) {
389 mVideoPreview.pause();
390
391 } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) {
392 // mVideePreview.pause() is not enough
393
394 mMediaController.setEnabled(false);
395 mVideoPreview.stopPlayback();
396 mAutoplay = false;
397 mSavedPlaybackPosition = 0;
398 mVideoPreview.setVideoPath(getFile().getStoragePath());
399 }
400 } // else : called from onError()
401 mMediaController.updatePausePlay();
402 }
403
404
405 /**
406 * Called when an error in playback occurs.
407 *
408 * @param mp {@link MediaPlayer} instance performing the playback.
409 * @param what Type of error
410 * @param extra Extra code specific to the error
411 */
412 @Override
413 public boolean onError(MediaPlayer mp, int what, int extra) {
414 if (mVideoPreview.getWindowToken() != null) {
415 String message = MediaService.getMessageForMediaError(getActivity(), what, extra);
416 new AlertDialog.Builder(getActivity())
417 .setMessage(message)
418 .setPositiveButton(android.R.string.VideoView_error_button,
419 new DialogInterface.OnClickListener() {
420 public void onClick(DialogInterface dialog, int whichButton) {
421 dialog.dismiss();
422 VideoHelper.this.onCompletion(null);
423 }
424 })
425 .setCancelable(false)
426 .show();
427 }
428 return true;
429 }
430
431 }
432
433
434 @Override
435 public void onPause() {
436 super.onPause();
437 Log_OC.e(TAG, "onPause");
438 }
439
440 @Override
441 public void onResume() {
442 super.onResume();
443 Log_OC.e(TAG, "onResume");
444 }
445
446 @Override
447 public void onDestroy() {
448 super.onDestroy();
449 Log_OC.e(TAG, "onDestroy");
450 }
451
452 @Override
453 public void onStop() {
454 Log_OC.e(TAG, "onStop");
455 super.onStop();
456
457 mPrepared = false;
458 if (mMediaServiceConnection != null) {
459 Log_OC.d(TAG, "Unbinding from MediaService ...");
460 if (mMediaServiceBinder != null && mMediaController != null) {
461 mMediaServiceBinder.unregisterMediaController(mMediaController);
462 }
463 getActivity().unbindService(mMediaServiceConnection);
464 mMediaServiceConnection = null;
465 mMediaServiceBinder = null;
466 }
467 }
468
469 @Override
470 public boolean onTouch(View v, MotionEvent event) {
471 if (event.getAction() == MotionEvent.ACTION_DOWN && v == mVideoPreview) {
472 startFullScreenVideo();
473 return true;
474 }
475 return false;
476 }
477
478
479 private void startFullScreenVideo() {
480 Intent i = new Intent(getActivity(), PreviewVideoActivity.class);
481 i.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount);
482 i.putExtra(FileActivity.EXTRA_FILE, getFile());
483 i.putExtra(PreviewVideoActivity.EXTRA_AUTOPLAY, mVideoPreview.isPlaying());
484 mVideoPreview.pause();
485 i.putExtra(PreviewVideoActivity.EXTRA_START_POSITION, mVideoPreview.getCurrentPosition());
486 startActivityForResult(i, 0);
487 }
488
489 @Override
490 public void onConfigurationChanged (Configuration newConfig) {
491 Log_OC.e(TAG, "onConfigurationChanged " + this);
492 }
493
494 @Override
495 public void onActivityResult (int requestCode, int resultCode, Intent data) {
496 Log_OC.e(TAG, "onActivityResult " + this);
497 super.onActivityResult(requestCode, resultCode, data);
498 if (resultCode == Activity.RESULT_OK) {
499 mSavedPlaybackPosition = data.getExtras().getInt(PreviewVideoActivity.EXTRA_START_POSITION);
500 mAutoplay = data.getExtras().getBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY);
501 }
502 }
503
504
505 private void playAudio() {
506 OCFile file = getFile();
507 if (!mMediaServiceBinder.isPlaying(file)) {
508 Log_OC.d(TAG, "starting playback of " + file.getStoragePath());
509 mMediaServiceBinder.start(mAccount, file, mAutoplay, mSavedPlaybackPosition);
510
511 } else {
512 if (!mMediaServiceBinder.isPlaying() && mAutoplay) {
513 mMediaServiceBinder.start();
514 mMediaController.updatePausePlay();
515 }
516 }
517 }
518
519
520 private void bindMediaService() {
521 Log_OC.d(TAG, "Binding to MediaService...");
522 if (mMediaServiceConnection == null) {
523 mMediaServiceConnection = new MediaServiceConnection();
524 }
525 getActivity().bindService( new Intent(getActivity(),
526 MediaService.class),
527 mMediaServiceConnection,
528 Context.BIND_AUTO_CREATE);
529 // follow the flow in MediaServiceConnection#onServiceConnected(...)
530 }
531
532 /** Defines callbacks for service binding, passed to bindService() */
533 private class MediaServiceConnection implements ServiceConnection {
534
535 @Override
536 public void onServiceConnected(ComponentName component, IBinder service) {
537 if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
538 Log_OC.d(TAG, "Media service connected");
539 mMediaServiceBinder = (MediaServiceBinder) service;
540 if (mMediaServiceBinder != null) {
541 prepareMediaController();
542 playAudio(); // do not wait for the touch of nobody to play audio
543
544 Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready");
545
546 } else {
547 Log_OC.e(TAG, "Unexpected response from MediaService while binding");
548 }
549 }
550 }
551
552 private void prepareMediaController() {
553 mMediaServiceBinder.registerMediaController(mMediaController);
554 if (mMediaController != null) {
555 mMediaController.setMediaPlayer(mMediaServiceBinder);
556 mMediaController.setEnabled(true);
557 mMediaController.updatePausePlay();
558 }
559 }
560
561 @Override
562 public void onServiceDisconnected(ComponentName component) {
563 if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
564 Log_OC.e(TAG, "Media service suddenly disconnected");
565 if (mMediaController != null) {
566 mMediaController.setMediaPlayer(null);
567 } else {
568 Toast.makeText(getActivity(), "No media controller to release when disconnected from media service", Toast.LENGTH_SHORT).show();
569 }
570 mMediaServiceBinder = null;
571 mMediaServiceConnection = null;
572 }
573 }
574 }
575
576
577
578 /**
579 * Opens the previewed file with an external application.
580 *
581 * TODO - improve this; instead of prioritize the actions available for the MIME type in the server,
582 * we should get a list of available apps for MIME tpye in the server and join it with the list of
583 * available apps for the MIME type known from the file extension, to let the user choose
584 */
585 private void openFile() {
586 OCFile file = getFile();
587 stopPreview(true);
588 String storagePath = file.getStoragePath();
589 String encodedStoragePath = WebdavUtils.encodePath(storagePath);
590 try {
591 Intent i = new Intent(Intent.ACTION_VIEW);
592 i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
593 i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
594 startActivity(i);
595
596 } catch (Throwable t) {
597 Log_OC.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + file.getMimetype());
598 boolean toastIt = true;
599 String mimeType = "";
600 try {
601 Intent i = new Intent(Intent.ACTION_VIEW);
602 mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
603 if (mimeType == null || !mimeType.equals(file.getMimetype())) {
604 if (mimeType != null) {
605 i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType);
606 } else {
607 // desperate try
608 i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), "*-/*");
609 }
610 i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
611 startActivity(i);
612 toastIt = false;
613 }
614
615 } catch (IndexOutOfBoundsException e) {
616 Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);
617
618 } catch (ActivityNotFoundException e) {
619 Log_OC.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");
620
621 } catch (Throwable th) {
622 Log_OC.e(TAG, "Unexpected problem when opening: " + storagePath, th);
623
624 } finally {
625 if (toastIt) {
626 Toast.makeText(getActivity(), "There is no application to handle file " + file.getFileName(), Toast.LENGTH_SHORT).show();
627 }
628 }
629
630 }
631 finish();
632 }
633
634 /**
635 * Starts a the removal of the previewed file.
636 *
637 * Shows a confirmation dialog. The action continues in {@link #onConfirmation(String)} , {@link #onNeutral(String)} or {@link #onCancel(String)},
638 * depending upon the user selection in the dialog.
639 */
640 private void removeFile() {
641 ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(
642 R.string.confirmation_remove_alert,
643 new String[]{getFile().getFileName()},
644 R.string.confirmation_remove_remote_and_local,
645 R.string.confirmation_remove_local,
646 R.string.common_cancel);
647 confDialog.setOnConfirmationListener(this);
648 confDialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
649 }
650
651
652 /**
653 * Performs the removal of the previewed file, both locally and in the server.
654 */
655 @Override
656 public void onConfirmation(String callerTag) {
657 OCFile file = getFile();
658 if (mStorageManager.getFileById(file.getFileId()) != null) { // check that the file is still there;
659 stopPreview(true);
660 mLastRemoteOperation = new RemoveFileOperation( file, // TODO we need to review the interface with RemoteOperations, and use OCFile IDs instead of OCFile objects as parameters
661 true,
662 mStorageManager);
663 mLastRemoteOperation.execute(mAccount, getSherlockActivity(), this, mHandler, getSherlockActivity());
664
665 ((FileDisplayActivity) getActivity()).showLoadingDialog();
666 }
667 }
668
669
670 /**
671 * Removes the file from local storage
672 */
673 @Override
674 public void onNeutral(String callerTag) {
675 // TODO this code should be made in a secondary thread,
676 OCFile file = getFile();
677 if (file.isDown()) { // checks it is still there
678 stopPreview(true);
679 File f = new File(file.getStoragePath());
680 f.delete();
681 file.setStoragePath(null);
682 mStorageManager.saveFile(file);
683 finish();
684 }
685 }
686
687 /**
688 * User cancelled the removal action.
689 */
690 @Override
691 public void onCancel(String callerTag) {
692 // nothing to do here
693 }
694
695
696 /**
697 * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewMediaFragment} to be previewed.
698 *
699 * @param file File to test if can be previewed.
700 * @return 'True' if the file can be handled by the fragment.
701 */
702 public static boolean canBePreviewed(OCFile file) {
703 return (file != null && (file.isAudio() || file.isVideo()));
704 }
705
706 /**
707 * {@inheritDoc}
708 */
709 @Override
710 public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
711 if (operation.equals(mLastRemoteOperation)) {
712 if (operation instanceof RemoveFileOperation) {
713 onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
714 }
715 }
716 }
717
718 private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) {
719 ((FileDisplayActivity) getActivity()).dismissLoadingDialog();
720 if (result.isSuccess()) {
721 Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG);
722 msg.show();
723 finish();
724
725 } else {
726 Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG);
727 msg.show();
728 if (result.isSslRecoverableException()) {
729 // TODO show the SSL warning dialog
730 }
731 }
732 }
733
734 private void stopPreview(boolean stopAudio) {
735 OCFile file = getFile();
736 if (file.isAudio() && stopAudio) {
737 mMediaServiceBinder.pause();
738
739 } else if (file.isVideo()) {
740 mVideoPreview.stopPlayback();
741 }
742 }
743
744
745
746 /**
747 * Finishes the preview
748 */
749 private void finish() {
750 getActivity().onBackPressed();
751 }
752
753
754 public int getPosition() {
755 if (mPrepared) {
756 mSavedPlaybackPosition = mVideoPreview.getCurrentPosition();
757 }
758 Log_OC.e(TAG, "getting position: " + mSavedPlaybackPosition);
759 return mSavedPlaybackPosition;
760 }
761
762 public boolean isPlaying() {
763 if (mPrepared) {
764 mAutoplay = mVideoPreview.isPlaying();
765 }
766 return mAutoplay;
767 }
768
769 }