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