Merge branch 'develop' into setup_buttons
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewVideoActivity.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
18 package com.owncloud.android.ui.preview;
19
20 import com.owncloud.android.Log_OC;
21 import com.owncloud.android.R;
22 import com.owncloud.android.authentication.AccountUtils;
23 import com.owncloud.android.authentication.AccountUtils.AccountNotFoundException;
24 import com.owncloud.android.datamodel.DataStorageManager;
25 import com.owncloud.android.datamodel.FileDataStorageManager;
26 import com.owncloud.android.datamodel.OCFile;
27 import com.owncloud.android.media.MediaService;
28 import com.owncloud.android.ui.activity.FileActivity;
29
30 import android.accounts.Account;
31 import android.app.AlertDialog;
32 import android.content.DialogInterface;
33 import android.content.Intent;
34 import android.media.MediaPlayer;
35 import android.media.MediaPlayer.OnCompletionListener;
36 import android.media.MediaPlayer.OnErrorListener;
37 import android.media.MediaPlayer.OnPreparedListener;
38 import android.net.Uri;
39 import android.os.Bundle;
40 import android.widget.MediaController;
41 import android.widget.VideoView;
42
43
44 /**
45 * Activity implementing a basic video player.
46 *
47 * Used as an utility to preview video files contained in an ownCloud account.
48 *
49 * Currently, it always plays in landscape mode, full screen. When the playback ends,
50 * the activity is finished.
51 *
52 * @author David A. Velasco
53 */
54 public class PreviewVideoActivity extends FileActivity implements OnCompletionListener, OnPreparedListener, OnErrorListener {
55
56 /** Key to receive a flag signaling if the video should be started immediately */
57 public static final String EXTRA_AUTOPLAY = "AUTOPLAY";
58
59 /** Key to receive the position of the playback where the video should be put at start */
60 public static final String EXTRA_START_POSITION = "START_POSITION";
61
62 private static final String TAG = PreviewVideoActivity.class.getSimpleName();
63
64 private DataStorageManager mStorageManager;
65
66 private int mSavedPlaybackPosition; // in the unit time handled by MediaPlayer.getCurrentPosition()
67 private boolean mAutoplay; // when 'true', the playback starts immediately with the activity
68 private VideoView mVideoPlayer; // view to play the file; both performs and show the playback
69 private MediaController mMediaController; // panel control used by the user to control the playback
70
71 /**
72 * Called when the activity is first created.
73 *
74 * Searches for an {@link OCFile} and ownCloud {@link Account} holding it in the starting {@link Intent}.
75 *
76 * The {@link Account} is unnecessary if the file is downloaded; else, the {@link Account} is used to
77 * try to stream the remote file - TODO get the streaming works
78 *
79 * {@inheritDoc}
80 */
81 @Override
82 public void onCreate(Bundle savedInstanceState) {
83 super.onCreate(savedInstanceState);
84 Log_OC.e(TAG, "ACTIVITY\t\tonCreate");
85
86 setContentView(R.layout.video_layout);
87
88 if (savedInstanceState == null) {
89 Bundle extras = getIntent().getExtras();
90 mSavedPlaybackPosition = extras.getInt(EXTRA_START_POSITION);
91 mAutoplay = extras.getBoolean(EXTRA_AUTOPLAY);
92
93 } else {
94 mSavedPlaybackPosition = savedInstanceState.getInt(EXTRA_START_POSITION);
95 mAutoplay = savedInstanceState.getBoolean(EXTRA_AUTOPLAY);
96 }
97
98 mVideoPlayer = (VideoView) findViewById(R.id.videoPlayer);
99
100 // set listeners to get more contol on the playback
101 mVideoPlayer.setOnPreparedListener(this);
102 mVideoPlayer.setOnCompletionListener(this);
103 mVideoPlayer.setOnErrorListener(this);
104
105 // keep the screen on while the playback is performed (prevents screen off by battery save)
106 mVideoPlayer.setKeepScreenOn(true);
107 }
108
109
110 /**
111 * {@inheritDoc}
112 */
113 @Override
114 public void onSaveInstanceState(Bundle outState) {
115 super.onSaveInstanceState(outState);
116 Log_OC.e(TAG, "ACTIVITY\t\tonSaveInstanceState");
117 outState.putInt(PreviewVideoActivity.EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
118 outState.putBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY , mVideoPlayer.isPlaying());
119 }
120
121
122 @Override
123 public void onBackPressed() {
124 Log_OC.e(TAG, "ACTIVTIY\t\tonBackPressed");
125 Intent i = new Intent();
126 i.putExtra(EXTRA_AUTOPLAY, mVideoPlayer.isPlaying());
127 i.putExtra(EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
128 setResult(RESULT_OK, i);
129 super.onBackPressed();
130 }
131
132
133 /**
134 * Called when the file is ready to be played.
135 *
136 * Just starts the playback.
137 *
138 * @param mp {@link MediaPlayer} instance performing the playback.
139 */
140 @Override
141 public void onPrepared(MediaPlayer mp) {
142 Log_OC.e(TAG, "ACTIVITY\t\tonPrepare");
143 mVideoPlayer.seekTo(mSavedPlaybackPosition);
144 if (mAutoplay) {
145 mVideoPlayer.start();
146 }
147 mMediaController.show(5000);
148 }
149
150
151 /**
152 * Called when the file is finished playing.
153 *
154 * Rewinds the video
155 *
156 * @param mp {@link MediaPlayer} instance performing the playback.
157 */
158 @Override
159 public void onCompletion(MediaPlayer mp) {
160 mVideoPlayer.seekTo(0);
161 }
162
163
164 /**
165 * Called when an error in playback occurs.
166 *
167 * @param mp {@link MediaPlayer} instance performing the playback.
168 * @param what Type of error
169 * @param extra Extra code specific to the error
170 */
171 @Override
172 public boolean onError(MediaPlayer mp, int what, int extra) {
173 Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
174
175 if (mMediaController != null) {
176 mMediaController.hide();
177 }
178
179 if (mVideoPlayer.getWindowToken() != null) {
180 String message = MediaService.getMessageForMediaError(this, what, extra);
181 new AlertDialog.Builder(this)
182 .setMessage(message)
183 .setPositiveButton(android.R.string.VideoView_error_button,
184 new DialogInterface.OnClickListener() {
185 public void onClick(DialogInterface dialog, int whichButton) {
186 PreviewVideoActivity.this.onCompletion(null);
187 }
188 })
189 .setCancelable(false)
190 .show();
191 }
192 return true;
193 }
194
195
196 @Override
197 protected void onAccountSet(boolean stateWasRecovered) {
198 if (getAccount() != null) {
199 OCFile file = getFile();
200 /// Validate handled file (first image to preview)
201 if (file == null) {
202 throw new IllegalStateException("Instanced with a NULL OCFile");
203 }
204 if (!file.isVideo()) {
205 throw new IllegalArgumentException("Non-video file passed as argument");
206 }
207 mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
208 file = mStorageManager.getFileById(file.getFileId());
209 if (file != null) {
210 if (file.isDown()) {
211 mVideoPlayer.setVideoPath(file.getStoragePath());
212
213 } else {
214 // not working yet
215 String url;
216 try {
217 url = AccountUtils.constructFullURLForAccount(this, getAccount()) + file.getRemotePath();
218 mVideoPlayer.setVideoURI(Uri.parse(url));
219 } catch (AccountNotFoundException e) {
220 onError(null, MediaService.OC_MEDIA_ERROR, R.string.media_err_no_account);
221 }
222 }
223
224 // create and prepare control panel for the user
225 mMediaController = new MediaController(this);
226 mMediaController.setMediaPlayer(mVideoPlayer);
227 mMediaController.setAnchorView(mVideoPlayer);
228 mVideoPlayer.setMediaController(mMediaController);
229
230 } else {
231 finish();
232 }
233 } else {
234 Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
235 finish();
236 }
237 }
238
239
240 }