172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.model;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ContentRestrictionException;
210d4645de339b4681d18198ba7451e7b8807116f9Tom Taylorimport com.android.mms.ExceedMessageSizeException;
229242286c35743422051d439d7460cd0a1426899cWei Huangimport com.android.mms.LogTag;
2310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylorimport com.android.mms.MmsConfig;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.dom.smil.SmilMediaElementImpl;
256be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylorimport android.drm.mobile1.DrmException;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.drm.DrmWrapper;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ui.UriImage;
289242286c35743422051d439d7460cd0a1426899cWei Huangimport com.android.mms.ui.MessageUtils;
29bbc5b8d0076b0cdae851bfec636a854ef77bd6ceTodor Kalaydjiev
30bbc5b8d0076b0cdae851bfec636a854ef77bd6ceTodor Kalaydjievimport com.google.android.mms.ContentType;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPart;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.Event;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.ElementTime;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Bitmap;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.BitmapFactory;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.FileNotFoundException;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.InputStream;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.lang.ref.SoftReference;
491009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjievimport java.util.Arrays;
501009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjievimport java.util.HashSet;
511009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjievimport java.util.Set;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class ImageModel extends RegionMediaModel {
551009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev    @SuppressWarnings("hiding")
569242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = "Mms/image";
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean DEBUG = false;
58150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato    private static final boolean LOCAL_LOGV = false;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int THUMBNAIL_BOUNDS_LIMIT = 480;
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
621009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev    /**
631009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev     * These are the image content types that MMS supports. Anything else needs to be transcoded
641009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev     * into one of these content types before being sent over MMS.
651009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev     */
661009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev    private static final Set<String> SUPPORTED_MMS_IMAGE_CONTENT_TYPES =
671009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        new HashSet<String>(Arrays.asList(new String[] {
681009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                "image/jpeg",
691009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            }));
701009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private int mWidth;
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private int mHeight;
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SoftReference<Bitmap> mBitmapCache = new SoftReference<Bitmap>(null);
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ImageModel(Context context, Uri uri, RegionModel region)
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throws MmsException {
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super(context, SmilHelper.ELEMENT_TAG_IMAGE, uri, region);
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        initModelFromUri(uri);
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        checkContentRestriction();
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ImageModel(Context context, String contentType, String src,
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Uri uri, RegionModel region) throws DrmException, MmsException {
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super(context, SmilHelper.ELEMENT_TAG_IMAGE,
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                contentType, src, uri, region);
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        decodeImageBounds();
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ImageModel(Context context, String contentType, String src,
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            DrmWrapper wrapper, RegionModel regionModel) throws IOException {
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super(context, SmilHelper.ELEMENT_TAG_IMAGE, contentType, src,
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                wrapper, regionModel);
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void initModelFromUri(Uri uri) throws MmsException {
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        UriImage uriImage = new UriImage(mContext, uri);
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentType = uriImage.getContentType();
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (TextUtils.isEmpty(mContentType)) {
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new MmsException("Type of media is unknown.");
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSrc = uriImage.getSrc();
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mWidth = uriImage.getWidth();
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mHeight = uriImage.getHeight();
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (LOCAL_LOGV) {
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.v(TAG, "New ImageModel created:"
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    + " mSrc=" + mSrc
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    + " mContentType=" + mContentType
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    + " mUri=" + uri);
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void decodeImageBounds() throws DrmException {
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        UriImage uriImage = new UriImage(mContext, getUriWithDrmCheck());
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mWidth = uriImage.getWidth();
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mHeight = uriImage.getHeight();
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (LOCAL_LOGV) {
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.v(TAG, "Image bounds: " + mWidth + "x" + mHeight);
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // EventListener Interface
1251009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev    @Override
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void handleEvent(Event evt) {
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (evt.getType().equals(SmilMediaElementImpl.SMIL_MEDIA_START_EVENT)) {
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mVisible = true;
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (mFill != ElementTime.FILL_FREEZE) {
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mVisible = false;
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        notifyModelChanged(false);
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int getWidth() {
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mWidth;
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int getHeight() {
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mHeight;
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void checkContentRestriction() throws ContentRestrictionException {
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        cr.checkImageContentType(mContentType);
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Bitmap getBitmap() {
150bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor        return internalGetBitmap(getUri());
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Bitmap getBitmapWithDrmCheck() throws DrmException {
154bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor        return internalGetBitmap(getUriWithDrmCheck());
155bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor    }
156bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor
157bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor    private Bitmap internalGetBitmap(Uri uri) {
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Bitmap bm = mBitmapCache.get();
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (bm == null) {
160bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor            try {
161bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                bm = createThumbnailBitmap(THUMBNAIL_BOUNDS_LIMIT, uri);
162bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                if (bm != null) {
163bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                    mBitmapCache = new SoftReference<Bitmap>(bm);
164bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                }
165bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor            } catch (OutOfMemoryError ex) {
166bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                // fall through and return a null bitmap. The callers can handle a null
167bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor                // result and show R.drawable.ic_missing_thumbnail_picture
168bb689a98bd5dcc5e4b3f0d7e102decff346dc631Tom Taylor            }
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return bm;
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private Bitmap createThumbnailBitmap(int thumbnailBoundsLimit, Uri uri) {
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int outWidth = mWidth;
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int outHeight = mHeight;
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int s = 1;
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        while ((outWidth / s > thumbnailBoundsLimit)
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                || (outHeight / s > thumbnailBoundsLimit)) {
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            s *= 2;
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
1829242286c35743422051d439d7460cd0a1426899cWei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1839242286c35743422051d439d7460cd0a1426899cWei Huang            Log.v(TAG, "createThumbnailBitmap: scale=" + s + ", w=" + outWidth / s
1849242286c35743422051d439d7460cd0a1426899cWei Huang                    + ", h=" + outHeight / s);
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        BitmapFactory.Options options = new BitmapFactory.Options();
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        options.inSampleSize = s;
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        InputStream input = null;
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            input = mContext.getContentResolver().openInputStream(uri);
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return BitmapFactory.decodeStream(input, null, options);
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (FileNotFoundException e) {
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, e.getMessage(), e);
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
1969242286c35743422051d439d7460cd0a1426899cWei Huang        } catch (OutOfMemoryError ex) {
197574c33bcccbb888d8126d444da330dc57ea7fc2bTom Taylor            if (DEBUG) {
198574c33bcccbb888d8126d444da330dc57ea7fc2bTom Taylor                MessageUtils.writeHprofDataToFile();
199574c33bcccbb888d8126d444da330dc57ea7fc2bTom Taylor            }
2009242286c35743422051d439d7460cd0a1426899cWei Huang            throw ex;
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (input != null) {
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    input.close();
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
2119242286c35743422051d439d7460cd0a1426899cWei Huang
21210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    @Override
21310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public boolean getMediaResizable() {
21410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        return true;
21510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    }
21610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
21710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    @Override
21810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    protected void resizeMedia(int byteLimit, long messageId) throws MmsException {
21910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        UriImage image = new UriImage(mContext, getUri());
2201009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
2211009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        int widthLimit = MmsConfig.getMaxImageWidth();
2221009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        int heightLimit = MmsConfig.getMaxImageHeight();
22337260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        int size = getMediaSize();
2241009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        // In mms_config.xml, the max width has always been declared larger than the max height.
2251009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        // Swap the width and height limits if necessary so we scale the picture as little as
2261009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        // possible.
2271009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        if (image.getHeight() > image.getWidth()) {
2281009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            int temp = widthLimit;
2291009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            widthLimit = heightLimit;
2301009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            heightLimit = temp;
2310d4645de339b4681d18198ba7451e7b8807116f9Tom Taylor        }
2321009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
23337260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
23437260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor            Log.v(TAG, "resizeMedia size: " + size + " image.getWidth(): "
23537260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor                    + image.getWidth() + " widthLimit: " + widthLimit
23637260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor                    + " image.getHeight(): " + image.getHeight()
23737260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor                    + " heightLimit: " + heightLimit
23837260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor                    + " image.getContentType(): " + image.getContentType());
23937260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        }
24037260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor
24137260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        // Check if we're already within the limits - in which case we don't need to resize.
24237260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        // The size can be zero here, even when the media has content. See the comment in
24337260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        // MediaModel.initMediaSize. Sometimes it'll compute zero and it's costly to read the
24437260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        // whole stream to compute the size. When we call getResizedImageAsPart(), we'll correctly
24537260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        // set the size.
24637260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        if (size != 0 && size <= byteLimit &&
2471009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                image.getWidth() <= widthLimit &&
2481009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                image.getHeight() <= heightLimit &&
2491009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                SUPPORTED_MMS_IMAGE_CONTENT_TYPES.contains(image.getContentType())) {
25037260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
25137260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor                Log.v(TAG, "resizeMedia - already sized");
25237260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor            }
2531009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev            return;
2541009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev        }
2551009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev
25610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        PduPart part = image.getResizedImageAsPart(
2571009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                widthLimit,
2581009d4bf5ee9fd1f2523e530828de5babb78eb19Todor Kalaydjiev                heightLimit,
25910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                byteLimit);
26010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
2613b13ad40393f44e16bc65c8df5abc76f1c6fc754Tom Taylor        if (part == null) {
2623b13ad40393f44e16bc65c8df5abc76f1c6fc754Tom Taylor            throw new ExceedMessageSizeException("Not enough memory to turn image into part: " +
2633b13ad40393f44e16bc65c8df5abc76f1c6fc754Tom Taylor                    getUri());
2643b13ad40393f44e16bc65c8df5abc76f1c6fc754Tom Taylor        }
265b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park
266bbc5b8d0076b0cdae851bfec636a854ef77bd6ceTodor Kalaydjiev        // Update the content type because it may have changed due to resizing/recompressing
267bbc5b8d0076b0cdae851bfec636a854ef77bd6ceTodor Kalaydjiev        mContentType = new String(part.getContentType());
268bbc5b8d0076b0cdae851bfec636a854ef77bd6ceTodor Kalaydjiev
269b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        String src = getSrc();
270b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        byte[] srcBytes = src.getBytes();
271b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        part.setContentLocation(srcBytes);
272b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        int period = src.lastIndexOf(".");
273b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        byte[] contentId = period != -1 ? src.substring(0, period).getBytes() : srcBytes;
274b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park        part.setContentId(contentId);
275b02d890bd31dbf4c91390652a35282babec3b889Sang-Jun Park
27610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        PduPersister persister = PduPersister.getPduPersister(mContext);
27710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        this.mSize = part.getData().length;
27837260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor
27937260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
28037260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor            Log.v(TAG, "resizeMedia mSize: " + mSize);
28137260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor        }
28237260f1a28619edf1bde204eb1bc46e9e4a5b282Tom Taylor
28310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        Uri newUri = persister.persistPart(part, messageId);
28410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        setUri(newUri);
28510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    }
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
287