VideoModel.java revision 02277c6b787e8e29ee22b1df745eb8549d3ff023
1/*
2 * Copyright (C) 2008 Esmertec AG.
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.model;
19
20import com.android.mms.ContentRestrictionException;
21import com.android.mms.LogTag;
22import com.android.mms.dom.events.EventImpl;
23import com.android.mms.dom.smil.SmilMediaElementImpl;
24import com.android.mms.drm.DrmWrapper;
25import com.google.android.mms.MmsException;
26import android.database.sqlite.SqliteWrapper;
27
28import org.w3c.dom.events.Event;
29import org.w3c.dom.smil.ElementTime;
30
31import android.content.ContentResolver;
32import android.content.Context;
33import android.database.Cursor;
34import android.net.Uri;
35import android.provider.MediaStore.Images;
36import android.text.TextUtils;
37import android.util.Log;
38
39import com.google.android.mms.ContentType;
40import java.io.IOException;
41
42public class VideoModel extends RegionMediaModel {
43    private static final String TAG = MediaModel.TAG;
44    private static final boolean DEBUG = true;
45    private static final boolean LOCAL_LOGV = false;
46
47    public VideoModel(Context context, Uri uri, RegionModel region)
48            throws MmsException {
49        this(context, null, null, uri, region);
50        initModelFromUri(uri);
51        checkContentRestriction();
52    }
53
54    public VideoModel(Context context, String contentType, String src,
55            Uri uri, RegionModel region) throws MmsException {
56        super(context, SmilHelper.ELEMENT_TAG_VIDEO, contentType, src, uri, region);
57    }
58
59    public VideoModel(Context context, String contentType, String src,
60            DrmWrapper wrapper, RegionModel regionModel) throws IOException {
61        super(context, SmilHelper.ELEMENT_TAG_VIDEO, contentType, src, wrapper, regionModel);
62    }
63
64    private void initModelFromUri(Uri uri) throws MmsException {
65        ContentResolver cr = mContext.getContentResolver();
66        Cursor c = SqliteWrapper.query(mContext, cr, uri, null, null, null, null);
67
68        if (c != null) {
69            try {
70                if (c.moveToFirst()) {
71                    String path;
72                    try {
73                        // Local videos will have a data column
74                        path = c.getString(c.getColumnIndexOrThrow(Images.Media.DATA));
75                    } catch (IllegalArgumentException e) {
76                        // For non-local videos, the path is the uri
77                        path = uri.toString();
78                    }
79                    mSrc = path.substring(path.lastIndexOf('/') + 1);
80                    mContentType = c.getString(c.getColumnIndexOrThrow(
81                            Images.Media.MIME_TYPE));
82                    if (TextUtils.isEmpty(mContentType)) {
83                        throw new MmsException("Type of media is unknown.");
84                    }
85
86                    if (mContentType.equals(ContentType.VIDEO_MP4) && !(TextUtils.isEmpty(mSrc))) {
87                        int index = mSrc.lastIndexOf(".");
88                        if (index != -1) {
89                            try {
90                                String extension = mSrc.substring(index + 1);
91                                if (!(TextUtils.isEmpty(extension)) &&
92                                        (extension.equalsIgnoreCase("3gp") ||
93                                        extension.equalsIgnoreCase("3gpp") ||
94                                        extension.equalsIgnoreCase("3g2"))) {
95                                    mContentType = ContentType.VIDEO_3GPP;
96                                }
97                            } catch(IndexOutOfBoundsException ex) {
98                                if (LOCAL_LOGV) {
99                                    Log.v(TAG, "Media extension is unknown.");
100                                }
101                            }
102                        }
103                    }
104
105                    if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
106                        Log.v(TAG, "New VideoModel created:"
107                                + " mSrc=" + mSrc
108                                + " mContentType=" + mContentType
109                                + " mUri=" + uri);
110                    }
111                } else {
112                    throw new MmsException("Nothing found: " + uri);
113                }
114            } finally {
115                c.close();
116            }
117        } else {
118            throw new MmsException("Bad URI: " + uri);
119        }
120
121        initMediaDuration();
122    }
123
124    // EventListener Interface
125    public void handleEvent(Event evt) {
126        String evtType = evt.getType();
127        if (LOCAL_LOGV || Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
128            Log.v(TAG, "[VideoModel] handleEvent " + evt.getType() + " on " + this);
129        }
130
131        MediaAction action = MediaAction.NO_ACTIVE_ACTION;
132        if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_START_EVENT)) {
133            action = MediaAction.START;
134
135            // if the Music player app is playing audio, we should pause that so it won't
136            // interfere with us playing video here.
137            pauseMusicPlayer();
138
139            mVisible = true;
140        } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_END_EVENT)) {
141            action = MediaAction.STOP;
142            if (mFill != ElementTime.FILL_FREEZE) {
143                mVisible = false;
144            }
145        } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_PAUSE_EVENT)) {
146            action = MediaAction.PAUSE;
147            mVisible = true;
148        } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_SEEK_EVENT)) {
149            action = MediaAction.SEEK;
150            mSeekTo = ((EventImpl) evt).getSeekTo();
151            mVisible = true;
152        }
153
154        appendAction(action);
155        notifyModelChanged(false);
156    }
157
158    protected void checkContentRestriction() throws ContentRestrictionException {
159        ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
160        cr.checkVideoContentType(mContentType);
161    }
162
163    @Override
164    protected boolean isPlayable() {
165        return true;
166    }
167}
168