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