ImageModel.java revision 9242286c35743422051d439d7460cd0a1426899c
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.ContentRestrictionException; 21import com.android.mms.LogTag; 22import com.android.mms.dom.smil.SmilMediaElementImpl; 23import com.android.mms.drm.DrmWrapper; 24import com.android.mms.ui.UriImage; 25import com.android.mms.ui.MessageUtils; 26import com.google.android.mms.MmsException; 27 28import org.w3c.dom.events.Event; 29import org.w3c.dom.smil.ElementTime; 30 31import android.content.Context; 32import android.drm.mobile1.DrmException; 33import android.graphics.Bitmap; 34import android.graphics.BitmapFactory; 35import android.net.Uri; 36import android.text.TextUtils; 37import android.util.Config; 38import android.util.Log; 39 40import java.io.FileNotFoundException; 41import java.io.IOException; 42import java.io.InputStream; 43import java.lang.ref.SoftReference; 44 45 46public class ImageModel extends RegionMediaModel { 47 private static final String TAG = "Mms/image"; 48 private static final boolean DEBUG = false; 49 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 50 51 private static final int THUMBNAIL_BOUNDS_LIMIT = 480; 52 53 private int mWidth; 54 private int mHeight; 55 private SoftReference<Bitmap> mBitmapCache = new SoftReference<Bitmap>(null); 56 57 public ImageModel(Context context, Uri uri, RegionModel region) 58 throws MmsException { 59 super(context, SmilHelper.ELEMENT_TAG_IMAGE, uri, region); 60 initModelFromUri(uri); 61 checkContentRestriction(); 62 } 63 64 public ImageModel(Context context, String contentType, String src, 65 Uri uri, RegionModel region) throws DrmException, MmsException { 66 super(context, SmilHelper.ELEMENT_TAG_IMAGE, 67 contentType, src, uri, region); 68 decodeImageBounds(); 69 } 70 71 public ImageModel(Context context, String contentType, String src, 72 DrmWrapper wrapper, RegionModel regionModel) throws IOException { 73 super(context, SmilHelper.ELEMENT_TAG_IMAGE, contentType, src, 74 wrapper, regionModel); 75 } 76 77 private void initModelFromUri(Uri uri) throws MmsException { 78 UriImage uriImage = new UriImage(mContext, uri); 79 80 mContentType = uriImage.getContentType(); 81 if (TextUtils.isEmpty(mContentType)) { 82 throw new MmsException("Type of media is unknown."); 83 } 84 mSrc = uriImage.getSrc(); 85 mWidth = uriImage.getWidth(); 86 mHeight = uriImage.getHeight(); 87 88 if (LOCAL_LOGV) { 89 Log.v(TAG, "New ImageModel created:" 90 + " mSrc=" + mSrc 91 + " mContentType=" + mContentType 92 + " mUri=" + uri); 93 } 94 } 95 96 private void decodeImageBounds() throws DrmException { 97 UriImage uriImage = new UriImage(mContext, getUriWithDrmCheck()); 98 mWidth = uriImage.getWidth(); 99 mHeight = uriImage.getHeight(); 100 101 if (LOCAL_LOGV) { 102 Log.v(TAG, "Image bounds: " + mWidth + "x" + mHeight); 103 } 104 } 105 106 // EventListener Interface 107 public void handleEvent(Event evt) { 108 if (evt.getType().equals(SmilMediaElementImpl.SMIL_MEDIA_START_EVENT)) { 109 mVisible = true; 110 } else if (mFill != ElementTime.FILL_FREEZE) { 111 mVisible = false; 112 } 113 114 notifyModelChanged(false); 115 } 116 117 public int getWidth() { 118 return mWidth; 119 } 120 121 public int getHeight() { 122 return mHeight; 123 } 124 125 protected void checkContentRestriction() throws ContentRestrictionException { 126 ContentRestriction cr = ContentRestrictionFactory.getContentRestriction(); 127 cr.checkImageContentType(mContentType); 128 cr.checkResolution(mWidth, mHeight); 129 } 130 131 public Bitmap getBitmap() { 132 Bitmap bm = mBitmapCache.get(); 133 if (bm == null) { 134 bm = createThumbnailBitmap(THUMBNAIL_BOUNDS_LIMIT, getUri()); 135 mBitmapCache = new SoftReference<Bitmap>(bm); 136 } 137 return bm; 138 } 139 140 public Bitmap getBitmapWithDrmCheck() throws DrmException { 141 Bitmap bm = mBitmapCache.get(); 142 if (bm == null) { 143 bm = createThumbnailBitmap(THUMBNAIL_BOUNDS_LIMIT, getUriWithDrmCheck()); 144 mBitmapCache = new SoftReference<Bitmap>(bm); 145 } 146 return bm; 147 } 148 149 private Bitmap createThumbnailBitmap(int thumbnailBoundsLimit, Uri uri) { 150 int outWidth = mWidth; 151 int outHeight = mHeight; 152 153 int s = 1; 154 while ((outWidth / s > thumbnailBoundsLimit) 155 || (outHeight / s > thumbnailBoundsLimit)) { 156 s *= 2; 157 } 158 if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 159 Log.v(TAG, "createThumbnailBitmap: scale=" + s + ", w=" + outWidth / s 160 + ", h=" + outHeight / s); 161 } 162 BitmapFactory.Options options = new BitmapFactory.Options(); 163 options.inSampleSize = s; 164 165 InputStream input = null; 166 try { 167 input = mContext.getContentResolver().openInputStream(uri); 168 return BitmapFactory.decodeStream(input, null, options); 169 } catch (FileNotFoundException e) { 170 Log.e(TAG, e.getMessage(), e); 171 return null; 172 } catch (OutOfMemoryError ex) { 173 MessageUtils.writeHprofDataToFile(); 174 throw ex; 175 } finally { 176 if (input != null) { 177 try { 178 input.close(); 179 } catch (IOException e) { 180 Log.e(TAG, e.getMessage(), e); 181 } 182 } 183 } 184 } 185 186} 187