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.ContentRestrictionException; 21 import com.android.mms.dom.events.EventImpl; 22 import com.android.mms.dom.smil.SmilMediaElementImpl; 23 import com.android.mms.drm.DrmWrapper; 24 import com.google.android.mms.MmsException; 25 import android.database.sqlite.SqliteWrapper; 26 27 import org.w3c.dom.events.Event; 28 29 import android.content.ContentResolver; 30 import android.content.Context; 31 import android.database.Cursor; 32 import android.net.Uri; 33 import android.provider.MediaStore.Audio; 34 import android.provider.Telephony.Mms.Part; 35 import android.text.TextUtils; 36 import android.util.Log; 37 38 import java.io.IOException; 39 import java.util.HashMap; 40 import java.util.Map; 41 42 public class AudioModel extends MediaModel { 43 private static final String TAG = MediaModel.TAG; 44 private static final boolean DEBUG = false; 45 private static final boolean LOCAL_LOGV = false; 46 47 private final HashMap<String, String> mExtras; 48 49 public AudioModel(Context context, Uri uri) throws MmsException { 50 this(context, null, null, uri); 51 initModelFromUri(uri); 52 checkContentRestriction(); 53 } 54 55 public AudioModel(Context context, String contentType, String src, Uri uri) throws MmsException { 56 super(context, SmilHelper.ELEMENT_TAG_AUDIO, contentType, src, uri); 57 mExtras = new HashMap<String, String>(); 58 } 59 60 public AudioModel(Context context, String contentType, String src, 61 DrmWrapper wrapper) throws IOException { 62 super(context, SmilHelper.ELEMENT_TAG_AUDIO, contentType, src, wrapper); 63 mExtras = new HashMap<String, String>(); 64 } 65 66 private void initModelFromUri(Uri uri) throws MmsException { 67 ContentResolver cr = mContext.getContentResolver(); 68 Cursor c = SqliteWrapper.query(mContext, cr, uri, null, null, null, null); 69 70 if (c != null) { 71 try { 72 if (c.moveToFirst()) { 73 String path; 74 boolean isFromMms = isMmsUri(uri); 75 76 // FIXME We suppose that there should be only two sources 77 // of the audio, one is the media store, the other is 78 // our MMS database. 79 if (isFromMms) { 80 path = c.getString(c.getColumnIndexOrThrow(Part._DATA)); 81 mContentType = c.getString(c.getColumnIndexOrThrow(Part.CONTENT_TYPE)); 82 } else { 83 path = c.getString(c.getColumnIndexOrThrow(Audio.Media.DATA)); 84 mContentType = c.getString(c.getColumnIndexOrThrow( 85 Audio.Media.MIME_TYPE)); 86 // Get more extras information which would be useful 87 // to the user. 88 String album = c.getString(c.getColumnIndexOrThrow("album")); 89 if (!TextUtils.isEmpty(album)) { 90 mExtras.put("album", album); 91 } 92 93 String artist = c.getString(c.getColumnIndexOrThrow("artist")); 94 if (!TextUtils.isEmpty(artist)) { 95 mExtras.put("artist", artist); 96 } 97 } 98 mSrc = path.substring(path.lastIndexOf('/') + 1); 99 100 if (TextUtils.isEmpty(mContentType)) { 101 throw new MmsException("Type of media is unknown."); 102 } 103 104 if (LOCAL_LOGV) { 105 Log.v(TAG, "New AudioModel created:" 106 + " mSrc=" + mSrc 107 + " mContentType=" + mContentType 108 + " mUri=" + uri 109 + " mExtras=" + mExtras); 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 public void stop() { 125 appendAction(MediaAction.STOP); 126 notifyModelChanged(false); 127 } 128 129 public void handleEvent(Event evt) { 130 String evtType = evt.getType(); 131 if (LOCAL_LOGV) { 132 Log.v(TAG, "Handling event: " + evtType + " on " + this); 133 } 134 135 MediaAction action = MediaAction.NO_ACTIVE_ACTION; 136 if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_START_EVENT)) { 137 action = MediaAction.START; 138 // if the Music player app is playing audio, we should pause that so it won't 139 // interfere with us playing audio here. 140 pauseMusicPlayer(); 141 } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_END_EVENT)) { 142 action = MediaAction.STOP; 143 } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_PAUSE_EVENT)) { 144 action = MediaAction.PAUSE; 145 } else if (evtType.equals(SmilMediaElementImpl.SMIL_MEDIA_SEEK_EVENT)) { 146 action = MediaAction.SEEK; 147 mSeekTo = ((EventImpl) evt).getSeekTo(); 148 } 149 150 appendAction(action); 151 notifyModelChanged(false); 152 } 153 154 public Map<String, ?> getExtras() { 155 return mExtras; 156 } 157 158 protected void checkContentRestriction() throws ContentRestrictionException { 159 ContentRestriction cr = ContentRestrictionFactory.getContentRestriction(); 160 cr.checkAudioContentType(mContentType); 161 } 162 163 @Override 164 protected boolean isPlayable() { 165 return true; 166 } 167 } 168