1f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks/*
2f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Copyright (C) 2009 The Android Open Source Project
3f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks *
4f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Licensed under the Apache License, Version 2.0 (the "License");
5f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * you may not use this file except in compliance with the License.
6f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * You may obtain a copy of the License at
7f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks *
8f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks *      http://www.apache.org/licenses/LICENSE-2.0
9f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks *
10f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Unless required by applicable law or agreed to in writing, software
11f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * distributed under the License is distributed on an "AS IS" BASIS,
12f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * See the License for the specific language governing permissions and
14f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * limitations under the License.
15f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks */
16f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
173c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chenpackage com.cooliris.media;
183c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen
19f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.app.AlertDialog;
20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.ContentResolver;
21f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.ContentValues;
22f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context;
23f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.DialogInterface;
24f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Intent;
25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.DialogInterface.OnCancelListener;
26f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.DialogInterface.OnClickListener;
27f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.database.Cursor;
28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.database.sqlite.SQLiteException;
29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.media.MediaPlayer;
30f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.net.Uri;
31f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Handler;
32f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.provider.MediaStore;
33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.provider.MediaStore.Video;
34f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.view.View;
35f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.MediaController;
36f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.VideoView;
37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
3829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Changimport com.cooliris.app.Res;
3929dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang
401bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparkspublic class MovieViewControl implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    @SuppressWarnings("unused")
43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static final String TAG = "MovieViewControl";
44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
45c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang    private static final int HALF_MINUTE = 30 * 1000;
46c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang    private static final int TWO_MINUTES = 4 * HALF_MINUTE;
47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    // Copied from MediaPlaybackService in the Music Player app. Should be
49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    // public, but isn't.
501bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks    private static final String SERVICECMD = "com.android.music.musicservicecommand";
51f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static final String CMDNAME = "command";
52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static final String CMDPAUSE = "pause";
53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
54f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private final VideoView mVideoView;
55f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private final View mProgressView;
56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private final Uri mUri;
57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private final ContentResolver mContentResolver;
58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    Handler mHandler = new Handler();
60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
61f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    Runnable mPlayingChecker = new Runnable() {
62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        public void run() {
63f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (mVideoView.isPlaying()) {
64f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mProgressView.setVisibility(View.GONE);
65f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            } else {
66f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mHandler.postDelayed(mPlayingChecker, 250);
67f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
68f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
69f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    };
701bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks
711bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks    public static String formatDuration(final Context context, int durationMs) {
72f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int duration = durationMs / 1000;
73f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int h = duration / 3600;
74f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int m = (duration - h * 3600) / 60;
75f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int s = duration - (h * 3600 + m * 60);
76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        String durationValue;
77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (h == 0) {
7829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang            durationValue = String.format(context.getString(Res.string.details_ms), m, s);
79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } else {
8029dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang            durationValue = String.format(context.getString(Res.string.details_hms), h, m, s);
81f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
82f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return durationValue;
83f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
84f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
85f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MovieViewControl(View rootView, Context context, Uri videoUri) {
86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mContentResolver = context.getContentResolver();
8729dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang        mVideoView = (VideoView) rootView.findViewById(Res.id.surface_view);
8829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang        mProgressView = rootView.findViewById(Res.id.progress_indicator);
89f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
90f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mUri = videoUri;
91f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
92f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        // For streams that we expect to be slow to start up, show a
93f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        // progress spinner until playback starts.
94f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        String scheme = mUri.getScheme();
951bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks        if ("http".equalsIgnoreCase(scheme) || "rtsp".equalsIgnoreCase(scheme)) {
96f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mHandler.postDelayed(mPlayingChecker, 250);
97f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } else {
98f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mProgressView.setVisibility(View.GONE);
99f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
100f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
101f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mVideoView.setOnErrorListener(this);
102f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mVideoView.setOnCompletionListener(this);
103f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mVideoView.setVideoURI(mUri);
104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mVideoView.setMediaController(new MediaController(context));
105f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        // make the video view handle keys for seeking and pausing
107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mVideoView.requestFocus();
108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
109f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        Intent i = new Intent(SERVICECMD);
110f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        i.putExtra(CMDNAME, CMDPAUSE);
111f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        context.sendBroadcast(i);
112f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
113f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        final Integer bookmark = getBookmark();
114f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (bookmark != null) {
115f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            AlertDialog.Builder builder = new AlertDialog.Builder(context);
11629dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang            builder.setTitle(Res.string.resume_playing_title);
1171bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            builder
1181bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                    .setMessage(String
11929dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang                            .format(context.getString(Res.string.resume_playing_message), formatDuration(context, bookmark)));
120f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            builder.setOnCancelListener(new OnCancelListener() {
121f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                public void onCancel(DialogInterface dialog) {
122f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    onCompletion();
1231bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                }
1241bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            });
12529dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang            builder.setPositiveButton(Res.string.resume_playing_resume, new OnClickListener() {
126f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                public void onClick(DialogInterface dialog, int which) {
127f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mVideoView.seekTo(bookmark);
128f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mVideoView.start();
1291bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                }
1301bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            });
13129dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang            builder.setNegativeButton(Res.string.resume_playing_restart, new OnClickListener() {
132f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                public void onClick(DialogInterface dialog, int which) {
133f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mVideoView.start();
1341bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                }
1351bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            });
136f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            builder.show();
137f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } else {
138f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mVideoView.start();
139f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
140f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
141f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
142f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static boolean uriSupportsBookmarks(Uri uri) {
143f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        String scheme = uri.getScheme();
144f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        String authority = uri.getAuthority();
1451bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks        return ("content".equalsIgnoreCase(scheme) && MediaStore.AUTHORITY.equalsIgnoreCase(authority));
146f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
147f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
148f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private Integer getBookmark() {
149f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (!uriSupportsBookmarks(mUri)) {
150f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return null;
151f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
152f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
1531bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks        String[] projection = new String[] { Video.VideoColumns.DURATION, Video.VideoColumns.BOOKMARK };
154f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
155f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        try {
1561bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            Cursor cursor = mContentResolver.query(mUri, projection, null, null, null);
157f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (cursor != null) {
158f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                try {
159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (cursor.moveToFirst()) {
160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        int duration = getCursorInteger(cursor, 0);
161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        int bookmark = getCursorInteger(cursor, 1);
162c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang                        if ((bookmark < HALF_MINUTE) || (duration < TWO_MINUTES)
163c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang                                || (bookmark > (duration - HALF_MINUTE))) {
164f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            return null;
165f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
166f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        return Integer.valueOf(bookmark);
167f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
168f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                } finally {
169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    cursor.close();
170f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
171f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
172f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (SQLiteException e) {
173f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // ignore
174f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
175f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
176f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return null;
177f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
178f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
179f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static int getCursorInteger(Cursor cursor, int index) {
180f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        try {
181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return cursor.getInt(index);
182f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (SQLiteException e) {
183f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return 0;
184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (NumberFormatException e) {
185f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return 0;
186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
187f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
188f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
190c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang    private void setBookmark(int bookmark, int duration) {
191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (!uriSupportsBookmarks(mUri)) {
192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return;
193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        ContentValues values = new ContentValues();
196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark));
197c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang        values.put(Video.VideoColumns.DURATION, Integer.toString(duration));
198f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        try {
199f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mContentResolver.update(mUri, values, null, null);
200f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (SecurityException ex) {
201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // Ignore, can happen if we try to set the bookmark on a read-only
202f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // resource such as a video attached to GMail.
203f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (SQLiteException e) {
204f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // ignore. can happen if the content doesn't support a bookmark
205f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // column.
206f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } catch (UnsupportedOperationException e) {
207f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // ignore. can happen if the external volume is already detached.
208f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
209f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
210f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
211f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void onPause() {
212f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mHandler.removeCallbacksAndMessages(null);
213c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang        setBookmark(mVideoView.getCurrentPosition(), mVideoView.getDuration());
214f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
215c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang        mVideoView.suspend();
216f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
217f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
218f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void onResume() {
219c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang        mVideoView.resume();
220c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang    }
221c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang
222c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang    public void onDestroy() {
223c3dd916a0861b6284b64b96755865fc94b1e3d9eGloria Wang        mVideoView.stopPlayback();
224f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
225f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
226f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean onError(MediaPlayer player, int arg1, int arg2) {
227f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mHandler.removeCallbacksAndMessages(null);
228f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mProgressView.setVisibility(View.GONE);
229f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return false;
230f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
231f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
232f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void onCompletion(MediaPlayer mp) {
233f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        onCompletion();
234f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
235f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
236f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void onCompletion() {
237f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
238f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks}
239