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