• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 package com.android.mms.model;
19 
20 import com.android.mms.R;
21 import com.android.mms.drm.DrmUtils;
22 import com.android.mms.drm.DrmWrapper;
23 import com.google.android.mms.MmsException;
24 
25 import org.w3c.dom.events.EventListener;
26 
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.drm.mobile1.DrmException;
30 import android.media.MediaPlayer;
31 import android.net.Uri;
32 import android.util.Log;
33 
34 import java.io.FileInputStream;
35 import java.io.FileNotFoundException;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.util.ArrayList;
39 
40 public abstract class MediaModel extends Model implements EventListener {
41     private static final String TAG = "MediaModel";
42 
43     protected Context mContext;
44     protected int mBegin;
45     protected int mDuration;
46     protected String mTag;
47     protected String mSrc;
48     protected String mContentType;
49     private Uri mUri;
50     private byte[] mData;
51     protected short mFill;
52     protected int mSize;
53     protected int mSeekTo;
54     protected DrmWrapper mDrmObjectWrapper;
55 
56     private final ArrayList<MediaAction> mMediaActions;
57     public static enum MediaAction {
58         NO_ACTIVE_ACTION,
59         START,
60         STOP,
61         PAUSE,
62         SEEK,
63     }
64 
MediaModel(Context context, String tag, Uri uri)65     public MediaModel(Context context, String tag, Uri uri) throws MmsException{
66         this(context, tag, null, null, uri);
67     }
68 
MediaModel(Context context, String tag, String contentType, String src, Uri uri)69     public MediaModel(Context context, String tag, String contentType,
70             String src, Uri uri) throws MmsException {
71         mContext = context;
72         mTag = tag;
73         mContentType = contentType;
74         mSrc = src;
75         mUri = uri;
76         initMediaSize();
77         mMediaActions = new ArrayList<MediaAction>();
78     }
79 
MediaModel(Context context, String tag, String contentType, String src, byte[] data)80     public MediaModel(Context context, String tag, String contentType,
81             String src, byte[] data) {
82         if (data == null) {
83             throw new IllegalArgumentException("data may not be null.");
84         }
85 
86         mContext = context;
87         mTag = tag;
88         mContentType = contentType;
89         mSrc = src;
90         mData = data;
91         mSize = data.length;
92         mMediaActions = new ArrayList<MediaAction>();
93     }
94 
MediaModel(Context context, String tag, String contentType, String src, DrmWrapper wrapper)95     public MediaModel(Context context, String tag, String contentType,
96             String src, DrmWrapper wrapper) throws IOException {
97         mContext = context;
98         mTag = tag;
99         mContentType = contentType;
100         mSrc = src;
101         mDrmObjectWrapper = wrapper;
102         mUri = DrmUtils.insert(context, wrapper);
103         mSize = wrapper.getOriginalData().length;
104         mMediaActions = new ArrayList<MediaAction>();
105     }
106 
getBegin()107     public int getBegin() {
108         return mBegin;
109     }
110 
setBegin(int begin)111     public void setBegin(int begin) {
112         mBegin = begin;
113         notifyModelChanged(true);
114     }
115 
getDuration()116     public int getDuration() {
117         return mDuration;
118     }
119 
setDuration(int duration)120     public void setDuration(int duration) {
121         if (isPlayable() && (duration < 0)) {
122             // 'indefinite' duration, we should try to find its exact value;
123             try {
124                 initMediaDuration();
125             } catch (MmsException e) {
126                 // On error, keep default duration.
127                 Log.e(TAG, e.getMessage(), e);
128                 return;
129             }
130         } else {
131             mDuration = duration;
132         }
133         notifyModelChanged(true);
134     }
135 
getTag()136     public String getTag() {
137         return mTag;
138     }
139 
getContentType()140     public String getContentType() {
141         return mContentType;
142     }
143 
144     /**
145      * Get the URI of the media without checking DRM rights. Use this method
146      * only if the media is NOT DRM protected.
147      *
148      * @return The URI of the media.
149      */
getUri()150     public Uri getUri() {
151         return mUri;
152     }
153 
154     /**
155      * Get the URI of the media with checking DRM rights. Use this method
156      * if the media is probably DRM protected.
157      *
158      * @return The URI of the media.
159      * @throws DrmException Insufficient DRM rights detected.
160      */
getUriWithDrmCheck()161     public Uri getUriWithDrmCheck() throws DrmException {
162         if (mUri != null) {
163             if (isDrmProtected() && !mDrmObjectWrapper.consumeRights()) {
164                 throw new DrmException("Insufficient DRM rights.");
165             }
166         }
167         return mUri;
168     }
169 
getData()170     public byte[] getData() throws DrmException {
171         if (mData != null) {
172             if (isDrmProtected() && !mDrmObjectWrapper.consumeRights()) {
173                 throw new DrmException(
174                         mContext.getString(R.string.insufficient_drm_rights));
175             }
176 
177             byte[] data = new byte[mData.length];
178             System.arraycopy(mData, 0, data, 0, mData.length);
179             return data;
180         }
181         return null;
182     }
183 
184     /**
185      * @param uri the mUri to set
186      */
setUri(Uri uri)187     void setUri(Uri uri) {
188         mUri = uri;
189     }
190 
191     /**
192      * @return the mSrc
193      */
getSrc()194     public String getSrc() {
195         return mSrc;
196     }
197 
198     /**
199      * @return the mFill
200      */
getFill()201     public short getFill() {
202         return mFill;
203     }
204 
205     /**
206      * @param fill the mFill to set
207      */
setFill(short fill)208     public void setFill(short fill) {
209         mFill = fill;
210         notifyModelChanged(true);
211     }
212 
getMediaSize()213     public int getMediaSize() {
214         return mSize;
215     }
216 
isText()217     public boolean isText() {
218         return mTag.equals(SmilHelper.ELEMENT_TAG_TEXT);
219     }
220 
isImage()221     public boolean isImage() {
222         return mTag.equals(SmilHelper.ELEMENT_TAG_IMAGE);
223     }
224 
isVideo()225     public boolean isVideo() {
226         return mTag.equals(SmilHelper.ELEMENT_TAG_VIDEO);
227     }
228 
isAudio()229     public boolean isAudio() {
230         return mTag.equals(SmilHelper.ELEMENT_TAG_AUDIO);
231     }
232 
isDrmProtected()233     public boolean isDrmProtected() {
234         return mDrmObjectWrapper != null;
235     }
236 
isAllowedToForward()237     public boolean isAllowedToForward() {
238         return mDrmObjectWrapper.isAllowedToForward();
239     }
240 
initMediaDuration()241     protected void initMediaDuration() throws MmsException {
242         if (mUri == null) {
243             throw new IllegalArgumentException("Uri may not be null.");
244         }
245 
246         MediaPlayer mediaPlayer = new MediaPlayer();
247         try {
248             mediaPlayer.setDataSource(mContext, mUri);
249             mediaPlayer.prepare();
250             mDuration = mediaPlayer.getDuration();
251         } catch (IOException e) {
252             Log.e(TAG, "Unexpected IOException.", e);
253             throw new MmsException(e);
254         } finally {
255             mediaPlayer.release();
256         }
257     }
258 
initMediaSize()259     private void initMediaSize() throws MmsException {
260         ContentResolver cr = mContext.getContentResolver();
261         InputStream input = null;
262         try {
263             input = cr.openInputStream(mUri);
264             if (input instanceof FileInputStream) {
265                 // avoid reading the whole stream to get its length
266                 FileInputStream f = (FileInputStream) input;
267                 mSize = (int) f.getChannel().size();
268             } else {
269                 while (-1 != input.read()) {
270                     mSize++;
271                 }
272             }
273 
274         } catch (IOException e) {
275             // Ignore
276             Log.e(TAG, "IOException caught while opening or reading stream", e);
277             if (e instanceof FileNotFoundException) {
278                 throw new MmsException(e.getMessage());
279             }
280         } finally {
281             if (null != input) {
282                 try {
283                     input.close();
284                 } catch (IOException e) {
285                     // Ignore
286                     Log.e(TAG, "IOException caught while closing stream", e);
287                 }
288             }
289         }
290     }
291 
isMmsUri(Uri uri)292     public static boolean isMmsUri(Uri uri) {
293         return uri.getAuthority().startsWith("mms");
294     }
295 
getSeekTo()296     public int getSeekTo() {
297         return mSeekTo;
298     }
299 
appendAction(MediaAction action)300     public void appendAction(MediaAction action) {
301         mMediaActions.add(action);
302     }
303 
getCurrentAction()304     public MediaAction getCurrentAction() {
305         if (0 == mMediaActions.size()) {
306             return MediaAction.NO_ACTIVE_ACTION;
307         }
308         return mMediaActions.remove(0);
309     }
310 
isPlayable()311     protected boolean isPlayable() {
312         return false;
313     }
314 
getDrmObject()315     public DrmWrapper getDrmObject() {
316         return mDrmObjectWrapper;
317     }
318 }
319