SlideshowModel.java revision adb8015394c49958fb6374f030aa9ddafb271a4f
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 Project
2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.ContentRestrictionException;
2210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylorimport com.android.mms.ExceedMessageSizeException;
2310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylorimport com.android.mms.MmsConfig;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.dom.smil.parser.SmilXmlSerializer;
266be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylorimport android.drm.mobile1.DrmException;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.drm.DrmWrapper;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.layout.LayoutManager;
29f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType;
30f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.GenericPdu;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.MultimediaMessagePdu;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduBody;
34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders;
35f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPart;
36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.NodeList;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILDocument;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILElement;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILLayoutElement;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILMediaElement;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILParElement;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRegionElement;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRootLayoutElement;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylorimport android.content.ContentUris;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast;
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.ByteArrayOutputStream;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException;
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Collection;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Iterator;
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.List;
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ListIterator;
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SlideshowModel extends Model
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        implements List<SlideModel>, IModelChangedObserver {
659242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = "Mms/slideshow";
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final LayoutModel mLayout;
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ArrayList<SlideModel> mSlides;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SMILDocument mDocumentCache;
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody mPduBodyCache;
71adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    private int mCurrentMessageSize;    // This is the current message size, not including
72adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor                                        // attachments that can be resized (such as photos)
73adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    private int mTotalMessageSize;      // This is the computed total message size
7410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    private Context mContext;
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    // amount of space to leave in a slideshow for text and overhead.
7710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public static final int SLIDESHOW_SLOP = 1024;
7810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
7910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    private SlideshowModel(Context context) {
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = new LayoutModel();
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = new ArrayList<SlideModel>();
8210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        mContext = context;
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SlideshowModel (
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            LayoutModel layouts, ArrayList<SlideModel> slides,
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILDocument documentCache, PduBody pbCache,
8810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            Context context) {
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = layouts;
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = slides;
9110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        mContext = context;
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mDocumentCache = documentCache;
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mPduBodyCache = pbCache;
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(slide.getSlideSize());
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setParent(this);
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createNew(Context context) {
10210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        return new SlideshowModel(context);
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromMessageUri(
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Uri uri) throws MmsException {
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return createFromPduBody(context, getPduBody(context, uri));
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromPduBody(Context context, PduBody pb) throws MmsException {
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILDocument document = SmilHelper.getDocument(pb);
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create root-layout model.
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILLayoutElement sle = document.getLayout();
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILRootLayoutElement srle = sle.getRootLayout();
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int w = srle.getWidth();
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int h = srle.getHeight();
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((w == 0) || (h == 0)) {
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            w = LayoutManager.getInstance().getLayoutParameters().getWidth();
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            h = LayoutManager.getInstance().getLayoutParameters().getHeight();
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setWidth(w);
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setHeight(h);
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        RegionModel rootLayout = new RegionModel(
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                null, 0, 0, w, h);
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create region models.
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList nlRegions = sle.getRegions();
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int regionsNum = nlRegions.getLength();
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < regionsNum; i++) {
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILRegionElement sre = (SMILRegionElement) nlRegions.item(i);
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            RegionModel r = new RegionModel(sre.getId(), sre.getFit(),
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getLeft(), sre.getTop(), sre.getWidth(), sre.getHeight(),
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getBackgroundColor());
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            regions.add(r);
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        LayoutModel layouts = new LayoutModel(rootLayout, regions);
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create slide models.
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILElement docBody = document.getBody();
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList slideNodes = docBody.getChildNodes();
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int slidesNum = slideNodes.getLength();
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<SlideModel> slides = new ArrayList<SlideModel>(slidesNum);
146adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        int totalMessageSize = 0;
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < slidesNum; i++) {
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // FIXME: This is NOT compatible with the SMILDocument which is
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // generated by some other mobile phones.
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILParElement par = (SMILParElement) slideNodes.item(i);
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Create media models for each slide.
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            NodeList mediaNodes = par.getChildNodes();
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int mediaNum = mediaNodes.getLength();
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum);
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (int j = 0; j < mediaNum; j++) {
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                SMILMediaElement sme = (SMILMediaElement) mediaNodes.item(j);
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MediaModel media = MediaModelFactory.getMediaModel(
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            context, sme, layouts, pb);
1639aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1649aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    /*
1659aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    * This is for slide duration value set.
1669aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    * If mms server does not support slide duration.
1679aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    */
1689aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    if (!MmsConfig.getSlideDurationEnabled()) {
1699aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        int mediadur = media.getDuration();
1709aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        float dur = par.getDur();
1719aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        if (dur == 0) {
1729aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            mediadur = MmsConfig.getMinimumSlideElementDuration() * 1000;
1739aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            media.setDuration(mediadur);
1749aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        }
1759aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1769aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        if ((int)mediadur / 1000 != dur) {
1779aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            String tag = sme.getTagName();
1789aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1799aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            if (ContentType.isVideoType(media.mContentType)
1809aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || tag.equals(SmilHelper.ELEMENT_TAG_VIDEO)
1819aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || ContentType.isAudioType(media.mContentType)
1829aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || tag.equals(SmilHelper.ELEMENT_TAG_AUDIO)) {
1839aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                /*
1849aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * add 1 sec to release and close audio/video
1859aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * for guaranteeing the audio/video playing.
1869aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * because the mmsc does not support the slide duration.
1879aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                */
1889aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                par.setDur((float)mediadur / 1000 + 1);
1899aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            } else {
1909aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                /*
1919aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * If a slide has an image and an audio/video element
1929aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * and the audio/video element has longer duration than the image,
1939aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * The Image disappear before the slide play done. so have to match
1949aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * an image duration to the slide duration.
1959aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                */
1969aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                if ((int)mediadur / 1000 < dur) {
1979aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    media.setDuration((int)dur * 1000);
1989aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                } else {
1999aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    if ((int)dur != 0) {
2009aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                        media.setDuration((int)dur * 1000);
2019aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    } else {
2029aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                        par.setDur((float)mediadur / 1000);
2039aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    }
2049aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                }
2059aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            }
2069aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        }
2079aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    }
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmilHelper.addMediaElementEventListeners(
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            (EventTarget) sme, media);
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mediaSet.add(media);
211adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor                    totalMessageSize += media.getMediaSize();
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (DrmException e) {
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IllegalArgumentException e) {
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = new SlideModel((int) (par.getDur() * 1000), mediaSet);
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setFill(par.getFill());
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SmilHelper.addParElementEventListeners((EventTarget) par, slide);
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slides.add(slide);
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context);
228adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        slideshow.mTotalMessageSize = totalMessageSize;
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slideshow.registerModelChangedObserver(slideshow);
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slideshow;
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public PduBody toPduBody() {
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mPduBodyCache == null) {
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = makePduBody(mDocumentCache);
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mPduBodyCache;
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
24010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody makePduBody(SMILDocument document) {
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return makePduBody(null, document, false);
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody makePduBody(Context context, SMILDocument document, boolean isMakingCopy) {
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduBody pb = new PduBody();
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean hasForwardLock = false;
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isMakingCopy) {
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (media.isDrmProtected() && !media.isAllowedToForward()) {
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        hasForwardLock = true;
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        continue;
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = new PduPart();
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (media.isText()) {
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    TextModel text = (TextModel) media;
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Don't create empty text part.
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (TextUtils.isEmpty(text.getText())) {
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        continue;
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Set Charset if it's a text media.
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setCharset(text.getCharset());
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Type.
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentType(media.getContentType().getBytes());
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String src = media.getSrc();
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String location;
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                boolean startWithContentId = src.startsWith("cid:");
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src.substring("cid:".length());
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src;
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Location.
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentLocation(location.getBytes());
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Id.
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    //Keep the original Content-Id.
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(location.getBytes());
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                else {
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int index = location.lastIndexOf(".");
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String contentId = (index == -1) ? location
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            : location.substring(0, index);
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(contentId.getBytes());
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (media.isDrmProtected()) {
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    DrmWrapper wrapper = media.getDrmObject();
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setDataUri(wrapper.getOriginalUri());
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setData(wrapper.getOriginalData());
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (media.isText()) {
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setData(((TextModel) media).getText().getBytes());
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (media.isImage() || media.isVideo() || media.isAudio()) {
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setDataUri(media.getUri());
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "Unsupport media: " + media);
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                pb.addPart(part);
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (hasForwardLock && isMakingCopy && context != null) {
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Toast.makeText(context,
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context.getString(R.string.cannot_forward_drm_obj),
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Toast.LENGTH_LONG).show();
31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            document = SmilHelper.getDocument(pb);
31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create and insert SMIL part(as the first part) into the PduBody.
32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ByteArrayOutputStream out = new ByteArrayOutputStream();
32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SmilXmlSerializer.serialize(document, out);
32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPart smilPart = new PduPart();
32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentId("smil".getBytes());
32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentLocation("smil.xml".getBytes());
32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentType(ContentType.APP_SMIL.getBytes());
32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setData(out.toByteArray());
32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        pb.addPart(0, smilPart);
32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return pb;
33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public PduBody makeCopy(Context context) {
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return makePduBody(context, SmilHelper.getDocument(this), true);
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SMILDocument toSmilDocument() {
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mDocumentCache == null) {
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mDocumentCache;
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static PduBody getPduBody(Context context, Uri msg) throws MmsException {
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPersister p = PduPersister.getPduPersister(context);
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        GenericPdu pdu = p.load(msg);
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgType = pdu.getMessageType();
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)) {
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return ((MultimediaMessagePdu) pdu).getBody();
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new MmsException();
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void setCurrentMessageSize(int size) {
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mCurrentMessageSize = size;
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
361adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // getCurrentMessageSize returns the size of the message, not including resizable attachments
362adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // such as photos. mCurrentMessageSize is used when adding/deleting/replacing non-resizable
363adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // attachments (movies, sounds, etc) in order to compute how much size is left in the message.
364adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // The difference between mCurrentMessageSize and the maxSize allowed for a message is then
365adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // divided up between the remaining resizable attachments. While this function is public,
366adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // it is only used internally between various MMS classes. If the UI wants to know the
367adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // size of a MMS message, it should call getTotalMessageSize() instead.
36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int getCurrentMessageSize() {
36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mCurrentMessageSize;
37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
372adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // getTotalMessageSize returns the total size of the message, including resizable attachments
373adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // such as photos. This function is intended to be used by the UI for displaying the size of the
374adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // MMS message.
375adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    public int getTotalMessageSize() {
376adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        return mTotalMessageSize;
377adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    }
378adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor
37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void increaseMessageSize(int increaseSize) {
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (increaseSize > 0) {
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize += increaseSize;
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void decreaseMessageSize(int decreaseSize) {
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (decreaseSize > 0) {
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize -= decreaseSize;
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public LayoutModel getLayout() {
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mLayout;
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Implement List<E> interface.
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean add(SlideModel object) {
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int increaseSize = object.getSlideSize();
40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        checkMessageSize(increaseSize);
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.add(object)) {
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(Collection<? extends SlideModel> collection) {
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void clear() {
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mSlides.size() > 0) {
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (SlideModel slide : mSlides) {
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                slide.unregisterModelChangedObserver(this);
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (IModelChangedObserver observer : mModelChangedObservers) {
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    slide.unregisterModelChangedObserver(observer);
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize = 0;
42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.clear();
42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean contains(Object object) {
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.contains(object);
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean containsAll(Collection<?> collection) {
43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.containsAll(collection);
43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isEmpty() {
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.isEmpty();
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Iterator<SlideModel> iterator() {
44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.iterator();
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean remove(Object object) {
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.remove(object)) {
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = (SlideModel) object;
45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            decreaseMessageSize(slide.getSlideSize());
45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean removeAll(Collection<?> collection) {
46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean retainAll(Collection<?> collection) {
46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int size() {
46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.size();
46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Object[] toArray() {
47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray();
47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public <T> T[] toArray(T[] array) {
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray(array);
47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void add(int location, SlideModel object) {
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int increaseSize = object.getSlideSize();
48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            checkMessageSize(increaseSize);
48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.add(location, object);
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(int location,
49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Collection<? extends SlideModel> collection) {
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel get(int location) {
500f9e3786006b0a0e8ce264f91670bba1527e04b0aTom Taylor        return (location >= 0 && location < mSlides.size()) ? mSlides.get(location) : null;
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int indexOf(Object object) {
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.indexOf(object);
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int lastIndexOf(Object object) {
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.lastIndexOf(object);
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator() {
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator();
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator(int location) {
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator(location);
51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel remove(int location) {
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.remove(location);
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            decreaseMessageSize(slide.getSlideSize());
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel set(int location, SlideModel object) {
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.get(location);
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null != object) {
53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int removeSize = 0;
53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int addSize = object.getSlideSize();
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null != slide) {
53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                removeSize = slide.getSlideSize();
53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (addSize > removeSize) {
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                checkMessageSize(addSize - removeSize);
53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                increaseMessageSize(addSize - removeSize);
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                decreaseMessageSize(removeSize - addSize);
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slide =  mSlides.set(location, object);
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        notifyModelChanged(true);
55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public List<SlideModel> subList(int start, int end) {
56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.subList(start, end);
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void registerModelChangedObserverInDescendants(
56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.registerModelChangedObserver(observer);
56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.registerModelChangedObserver(observer);
57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterModelChangedObserverInDescendants(
57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterModelChangedObserver(observer);
57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterModelChangedObserver(observer);
58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterAllModelChangedObserversInDescendants() {
58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterAllModelChangedObservers();
58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onModelChanged(Model model, boolean dataChanged) {
59572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (dataChanged) {
59672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = null;
59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = null;
59872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
59972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void sync(PduBody pb) {
60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = pb.getPartByContentLocation(media.getSrc());
60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (part != null) {
60672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    media.setUri(part.getDataUri());
60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void checkMessageSize(int increaseSize) throws ContentRestrictionException {
61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
61410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        cr.checkMessageSize(mCurrentMessageSize, increaseSize, mContext.getContentResolver());
61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
61610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Determines whether this is a "simple" slideshow.
61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Criteria:
62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one slide
62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one multimedia attachment, but no audio
62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - It can optionally have a caption
62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    */
62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isSimple() {
62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // There must be one (and only one) slide.
62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (size() != 1)
62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
62810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = get(0);
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // The slide must have either an image or video, but not both.
63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!(slide.hasImage() ^ slide.hasVideo()))
63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
63310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // No audio allowed.
63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasAudio())
63672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
63710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
64010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
6415d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    /**
6425d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * Make sure the text in slide 0 is no longer holding onto a reference to the text
6435d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * in the message text box.
64410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     */
6455d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    public void prepareForSend() {
6465d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        if (size() == 1) {
6475d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            TextModel text = get(0).getText();
6485d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            if (text != null) {
6495d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project                text.cloneText();
6505d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            }
6515d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        }
6525d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    }
65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
65410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    /**
65510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * Resize all the resizeable media objects to fit in the remaining size of the slideshow.
65610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * This should be called off of the UI thread.
65710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     *
65810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * @throws MmsException, ExceedMessageSizeException
65910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     */
66010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public void finalResize(Uri messageUri) throws MmsException, ExceedMessageSizeException {
66110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor//        Log.v(TAG, "Original message size: " + getCurrentMessageSize() + " getMaxMessageSize: "
66210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor//                + MmsConfig.getMaxMessageSize());
66310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
66410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        // Figure out if we have any media items that need to be resized and total up the
66510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        // sizes of the items that can't be resized.
66610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        int resizableCnt = 0;
66710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        int fixedSizeTotal = 0;
66810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        for (SlideModel slide : mSlides) {
66910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (MediaModel media : slide) {
67010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                if (media.getMediaResizable()) {
67110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    ++resizableCnt;
67210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                } else {
67310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    fixedSizeTotal += media.getMediaSize();
67410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
67510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
67610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        }
67710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        if (resizableCnt > 0) {
67810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int remainingSize = MmsConfig.getMaxMessageSize() - fixedSizeTotal - SLIDESHOW_SLOP;
67910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            if (remainingSize <= 0) {
68010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                throw new ExceedMessageSizeException("No room for pictures");
68110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
68210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            long messageId = ContentUris.parseId(messageUri);
68310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int bytesPerMediaItem = remainingSize / resizableCnt;
68410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // Resize the resizable media items to fit within their byte limit.
68510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (SlideModel slide : mSlides) {
68610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                for (MediaModel media : slide) {
68710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    if (media.getMediaResizable()) {
68810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                        media.resizeMedia(bytesPerMediaItem, messageId);
68910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    }
69010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
69110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
69210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // One last time through to calc the real message size.
69310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int totalSize = 0;
69410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (SlideModel slide : mSlides) {
69510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                for (MediaModel media : slide) {
69610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    totalSize += media.getMediaSize();
69710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
69810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
69910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor//            Log.v(TAG, "New message size: " + totalSize + " getMaxMessageSize: "
70010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor//                    + MmsConfig.getMaxMessageSize());
70110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
70210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            if (totalSize > MmsConfig.getMaxMessageSize()) {
70310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                throw new ExceedMessageSizeException("After compressing pictures, message too big");
70410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
70510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            setCurrentMessageSize(totalSize);
70610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
70710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            onModelChanged(this, true);     // clear the cached pdu body
70810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            PduBody pb = toPduBody();
70910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // This will write out all the new parts to:
71010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            //      /data/data/com.android.providers.telephony/app_parts
71110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // and at the same time delete the old parts.
71210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            PduPersister.getPduPersister(mContext).updateParts(messageUri, pb);
71310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        }
71410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    }
71510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
717