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