• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.LogTag;
22 import com.android.mms.dom.smil.SmilMediaElementImpl;
23 import com.android.mms.drm.DrmWrapper;
24 import com.android.mms.ui.UriImage;
25 import com.android.mms.ui.MessageUtils;
26 import com.google.android.mms.MmsException;
27 
28 import org.w3c.dom.events.Event;
29 import org.w3c.dom.smil.ElementTime;
30 
31 import android.content.Context;
32 import android.drm.mobile1.DrmException;
33 import android.graphics.Bitmap;
34 import android.graphics.BitmapFactory;
35 import android.net.Uri;
36 import android.text.TextUtils;
37 import android.util.Config;
38 import android.util.Log;
39 
40 import java.io.FileNotFoundException;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.lang.ref.SoftReference;
44 
45 
46 public 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 
ImageModel(Context context, Uri uri, RegionModel region)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 
ImageModel(Context context, String contentType, String src, Uri uri, RegionModel region)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 
ImageModel(Context context, String contentType, String src, DrmWrapper wrapper, RegionModel regionModel)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 
initModelFromUri(Uri uri)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 
decodeImageBounds()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
handleEvent(Event evt)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 
getWidth()117     public int getWidth() {
118         return mWidth;
119     }
120 
getHeight()121     public int getHeight() {
122         return mHeight;
123     }
124 
checkContentRestriction()125     protected void checkContentRestriction() throws ContentRestrictionException {
126         ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
127         cr.checkImageContentType(mContentType);
128         cr.checkResolution(mWidth, mHeight);
129     }
130 
getBitmap()131     public Bitmap getBitmap() {
132         return internalGetBitmap(getUri());
133     }
134 
getBitmapWithDrmCheck()135     public Bitmap getBitmapWithDrmCheck() throws DrmException {
136         return internalGetBitmap(getUriWithDrmCheck());
137     }
138 
internalGetBitmap(Uri uri)139     private Bitmap internalGetBitmap(Uri uri) {
140         Bitmap bm = mBitmapCache.get();
141         if (bm == null) {
142             try {
143                 bm = createThumbnailBitmap(THUMBNAIL_BOUNDS_LIMIT, uri);
144                 if (bm != null) {
145                     mBitmapCache = new SoftReference<Bitmap>(bm);
146                 }
147             } catch (OutOfMemoryError ex) {
148                 // fall through and return a null bitmap. The callers can handle a null
149                 // result and show R.drawable.ic_missing_thumbnail_picture
150             }
151         }
152         return bm;
153     }
154 
createThumbnailBitmap(int thumbnailBoundsLimit, Uri uri)155     private Bitmap createThumbnailBitmap(int thumbnailBoundsLimit, Uri uri) {
156         int outWidth = mWidth;
157         int outHeight = mHeight;
158 
159         int s = 1;
160         while ((outWidth / s > thumbnailBoundsLimit)
161                 || (outHeight / s > thumbnailBoundsLimit)) {
162             s *= 2;
163         }
164         if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
165             Log.v(TAG, "createThumbnailBitmap: scale=" + s + ", w=" + outWidth / s
166                     + ", h=" + outHeight / s);
167         }
168         BitmapFactory.Options options = new BitmapFactory.Options();
169         options.inSampleSize = s;
170 
171         InputStream input = null;
172         try {
173             input = mContext.getContentResolver().openInputStream(uri);
174             return BitmapFactory.decodeStream(input, null, options);
175         } catch (FileNotFoundException e) {
176             Log.e(TAG, e.getMessage(), e);
177             return null;
178         } catch (OutOfMemoryError ex) {
179             MessageUtils.writeHprofDataToFile();
180             throw ex;
181         } finally {
182             if (input != null) {
183                 try {
184                     input.close();
185                 } catch (IOException e) {
186                     Log.e(TAG, e.getMessage(), e);
187                 }
188             }
189         }
190     }
191 
192 }
193