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