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
21d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.io.ByteArrayOutputStream;
22469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylorimport java.io.FileNotFoundException;
23d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.io.IOException;
24469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylorimport java.io.InputStream;
25d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.ArrayList;
26d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Collection;
27469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylorimport java.util.HashMap;
28d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Iterator;
29d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.List;
30d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.ListIterator;
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.NodeList;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILDocument;
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILElement;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILLayoutElement;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILMediaElement;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILParElement;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRegionElement;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRootLayoutElement;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylorimport android.content.ContentResolver;
4310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylorimport android.content.ContentUris;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ContentRestrictionException;
50d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.ExceedMessageSizeException;
51d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.LogTag;
52d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.MmsConfig;
53d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.parser.SmilXmlSerializer;
54d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.layout.LayoutManager;
55d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.ContentType;
56d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException;
57d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.GenericPdu;
58d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.MultimediaMessagePdu;
59d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduBody;
60d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduHeaders;
61d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduPart;
62d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduPersister;
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SlideshowModel extends Model
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        implements List<SlideModel>, IModelChangedObserver {
669242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = "Mms/slideshow";
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final LayoutModel mLayout;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ArrayList<SlideModel> mSlides;
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SMILDocument mDocumentCache;
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody mPduBodyCache;
72adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    private int mCurrentMessageSize;    // This is the current message size, not including
73adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor                                        // attachments that can be resized (such as photos)
74adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    private int mTotalMessageSize;      // This is the computed total message size
7510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    private Context mContext;
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    // amount of space to leave in a slideshow for text and overhead.
7810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public static final int SLIDESHOW_SLOP = 1024;
7910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
8010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    private SlideshowModel(Context context) {
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = new LayoutModel();
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = new ArrayList<SlideModel>();
8310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        mContext = context;
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SlideshowModel (
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            LayoutModel layouts, ArrayList<SlideModel> slides,
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILDocument documentCache, PduBody pbCache,
8910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            Context context) {
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = layouts;
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = slides;
9210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        mContext = context;
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mDocumentCache = documentCache;
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mPduBodyCache = pbCache;
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(slide.getSlideSize());
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setParent(this);
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createNew(Context context) {
10310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        return new SlideshowModel(context);
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromMessageUri(
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Uri uri) throws MmsException {
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return createFromPduBody(context, getPduBody(context, uri));
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromPduBody(Context context, PduBody pb) throws MmsException {
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILDocument document = SmilHelper.getDocument(pb);
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create root-layout model.
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILLayoutElement sle = document.getLayout();
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILRootLayoutElement srle = sle.getRootLayout();
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int w = srle.getWidth();
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int h = srle.getHeight();
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((w == 0) || (h == 0)) {
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            w = LayoutManager.getInstance().getLayoutParameters().getWidth();
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            h = LayoutManager.getInstance().getLayoutParameters().getHeight();
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setWidth(w);
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setHeight(h);
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        RegionModel rootLayout = new RegionModel(
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                null, 0, 0, w, h);
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create region models.
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList nlRegions = sle.getRegions();
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int regionsNum = nlRegions.getLength();
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < regionsNum; i++) {
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILRegionElement sre = (SMILRegionElement) nlRegions.item(i);
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            RegionModel r = new RegionModel(sre.getId(), sre.getFit(),
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getLeft(), sre.getTop(), sre.getWidth(), sre.getHeight(),
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getBackgroundColor());
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            regions.add(r);
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        LayoutModel layouts = new LayoutModel(rootLayout, regions);
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create slide models.
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILElement docBody = document.getBody();
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList slideNodes = docBody.getChildNodes();
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int slidesNum = slideNodes.getLength();
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<SlideModel> slides = new ArrayList<SlideModel>(slidesNum);
147adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        int totalMessageSize = 0;
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < slidesNum; i++) {
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // FIXME: This is NOT compatible with the SMILDocument which is
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // generated by some other mobile phones.
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILParElement par = (SMILParElement) slideNodes.item(i);
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Create media models for each slide.
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            NodeList mediaNodes = par.getChildNodes();
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int mediaNum = mediaNodes.getLength();
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum);
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (int j = 0; j < mediaNum; j++) {
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                SMILMediaElement sme = (SMILMediaElement) mediaNodes.item(j);
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MediaModel media = MediaModelFactory.getMediaModel(
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            context, sme, layouts, pb);
1649aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1659aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    /*
1669aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    * This is for slide duration value set.
1679aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    * If mms server does not support slide duration.
1689aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    */
1699aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    if (!MmsConfig.getSlideDurationEnabled()) {
1709aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        int mediadur = media.getDuration();
1719aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        float dur = par.getDur();
1729aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        if (dur == 0) {
1739aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            mediadur = MmsConfig.getMinimumSlideElementDuration() * 1000;
1749aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            media.setDuration(mediadur);
1759aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        }
1769aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1779aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        if ((int)mediadur / 1000 != dur) {
1789aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            String tag = sme.getTagName();
1799aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin
1809aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            if (ContentType.isVideoType(media.mContentType)
1819aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || tag.equals(SmilHelper.ELEMENT_TAG_VIDEO)
1829aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || ContentType.isAudioType(media.mContentType)
1839aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                              || tag.equals(SmilHelper.ELEMENT_TAG_AUDIO)) {
1849aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                /*
1859aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * add 1 sec to release and close audio/video
1869aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * for guaranteeing the audio/video playing.
1879aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * because the mmsc does not support the slide duration.
1889aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                */
1899aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                par.setDur((float)mediadur / 1000 + 1);
1909aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            } else {
1919aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                /*
1929aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * If a slide has an image and an audio/video element
1939aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * and the audio/video element has longer duration than the image,
1949aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * The Image disappear before the slide play done. so have to match
1959aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                * an image duration to the slide duration.
1969aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                */
1979aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                if ((int)mediadur / 1000 < dur) {
1989aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    media.setDuration((int)dur * 1000);
1999aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                } else {
2009aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    if ((int)dur != 0) {
2019aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                        media.setDuration((int)dur * 1000);
2029aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    } else {
2039aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                        par.setDur((float)mediadur / 1000);
2049aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                    }
2059aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                                }
2069aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                            }
2079aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                        }
2089aed641d68fafdec88f83d9c4f949ca9ab6fdb0eSoojung Shin                    }
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmilHelper.addMediaElementEventListeners(
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            (EventTarget) sme, media);
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mediaSet.add(media);
212adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor                    totalMessageSize += media.getMediaSize();
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IllegalArgumentException e) {
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = new SlideModel((int) (par.getDur() * 1000), mediaSet);
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setFill(par.getFill());
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SmilHelper.addParElementEventListeners((EventTarget) par, slide);
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slides.add(slide);
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context);
227adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        slideshow.mTotalMessageSize = totalMessageSize;
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slideshow.registerModelChangedObserver(slideshow);
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slideshow;
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public PduBody toPduBody() {
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mPduBodyCache == null) {
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = makePduBody(mDocumentCache);
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mPduBodyCache;
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
23910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody makePduBody(SMILDocument document) {
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduBody pb = new PduBody();
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean hasForwardLock = false;
24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = new PduPart();
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (media.isText()) {
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    TextModel text = (TextModel) media;
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Don't create empty text part.
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (TextUtils.isEmpty(text.getText())) {
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        continue;
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Set Charset if it's a text media.
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setCharset(text.getCharset());
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Type.
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentType(media.getContentType().getBytes());
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String src = media.getSrc();
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String location;
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                boolean startWithContentId = src.startsWith("cid:");
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src.substring("cid:".length());
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src;
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Location.
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentLocation(location.getBytes());
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Id.
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    //Keep the original Content-Id.
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(location.getBytes());
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                else {
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int index = location.lastIndexOf(".");
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String contentId = (index == -1) ? location
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            : location.substring(0, index);
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(contentId.getBytes());
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2850ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor                if (media.isText()) {
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setData(((TextModel) media).getText().getBytes());
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (media.isImage() || media.isVideo() || media.isAudio()) {
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setDataUri(media.getUri());
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "Unsupport media: " + media);
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                pb.addPart(part);
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create and insert SMIL part(as the first part) into the PduBody.
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ByteArrayOutputStream out = new ByteArrayOutputStream();
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SmilXmlSerializer.serialize(document, out);
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPart smilPart = new PduPart();
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentId("smil".getBytes());
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentLocation("smil.xml".getBytes());
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentType(ContentType.APP_SMIL.getBytes());
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setData(out.toByteArray());
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        pb.addPart(0, smilPart);
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return pb;
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
310469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor    public HashMap<Uri, InputStream> openPartFiles(ContentResolver cr) {
311469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor        HashMap<Uri, InputStream> openedFiles = null;     // Don't create unless we have to
312469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor
313469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor        for (SlideModel slide : mSlides) {
314469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor            for (MediaModel media : slide) {
315469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                if (media.isText()) {
316469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                    continue;
317469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                }
318469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                Uri uri = media.getUri();
319469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                InputStream is;
320469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                try {
321469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                    is = cr.openInputStream(uri);
322469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                    if (is != null) {
323469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                        if (openedFiles == null) {
324469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                            openedFiles = new HashMap<Uri, InputStream>();
325469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                        }
326469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                        openedFiles.put(uri, is);
327469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                    }
328469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                } catch (FileNotFoundException e) {
329469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                    Log.e(TAG, "openPartFiles couldn't open: " + uri, e);
330469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor                }
331469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor            }
332469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor        }
333469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor        return openedFiles;
334469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor    }
335469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor
3360ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor    public PduBody makeCopy() {
3370ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor        return makePduBody(SmilHelper.getDocument(this));
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SMILDocument toSmilDocument() {
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mDocumentCache == null) {
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mDocumentCache;
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static PduBody getPduBody(Context context, Uri msg) throws MmsException {
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPersister p = PduPersister.getPduPersister(context);
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        GenericPdu pdu = p.load(msg);
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgType = pdu.getMessageType();
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)) {
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return ((MultimediaMessagePdu) pdu).getBody();
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new MmsException();
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void setCurrentMessageSize(int size) {
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mCurrentMessageSize = size;
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
364adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // getCurrentMessageSize returns the size of the message, not including resizable attachments
365adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // such as photos. mCurrentMessageSize is used when adding/deleting/replacing non-resizable
366adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // attachments (movies, sounds, etc) in order to compute how much size is left in the message.
367adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // The difference between mCurrentMessageSize and the maxSize allowed for a message is then
368adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // divided up between the remaining resizable attachments. While this function is public,
369adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // it is only used internally between various MMS classes. If the UI wants to know the
370adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // size of a MMS message, it should call getTotalMessageSize() instead.
37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int getCurrentMessageSize() {
37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mCurrentMessageSize;
37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
375adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // getTotalMessageSize returns the total size of the message, including resizable attachments
376adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // such as photos. This function is intended to be used by the UI for displaying the size of the
377adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    // MMS message.
378adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    public int getTotalMessageSize() {
379adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor        return mTotalMessageSize;
380adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor    }
381adb8015394c49958fb6374f030aa9ddafb271a4fTom Taylor
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void increaseMessageSize(int increaseSize) {
38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (increaseSize > 0) {
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize += increaseSize;
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void decreaseMessageSize(int decreaseSize) {
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (decreaseSize > 0) {
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize -= decreaseSize;
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public LayoutModel getLayout() {
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mLayout;
39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Implement List<E> interface.
40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean add(SlideModel object) {
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int increaseSize = object.getSlideSize();
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        checkMessageSize(increaseSize);
40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.add(object)) {
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(Collection<? extends SlideModel> collection) {
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void clear() {
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mSlides.size() > 0) {
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (SlideModel slide : mSlides) {
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                slide.unregisterModelChangedObserver(this);
42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (IModelChangedObserver observer : mModelChangedObservers) {
42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    slide.unregisterModelChangedObserver(observer);
42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize = 0;
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.clear();
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean contains(Object object) {
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.contains(object);
43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean containsAll(Collection<?> collection) {
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.containsAll(collection);
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isEmpty() {
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.isEmpty();
44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Iterator<SlideModel> iterator() {
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.iterator();
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean remove(Object object) {
45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.remove(object)) {
45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = (SlideModel) object;
45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            decreaseMessageSize(slide.getSlideSize());
45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean removeAll(Collection<?> collection) {
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean retainAll(Collection<?> collection) {
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int size() {
47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.size();
47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Object[] toArray() {
47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray();
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public <T> T[] toArray(T[] array) {
47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray(array);
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void add(int location, SlideModel object) {
48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int increaseSize = object.getSlideSize();
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            checkMessageSize(increaseSize);
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.add(location, object);
48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(int location,
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Collection<? extends SlideModel> collection) {
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel get(int location) {
503f9e3786006b0a0e8ce264f91670bba1527e04b0aTom Taylor        return (location >= 0 && location < mSlides.size()) ? mSlides.get(location) : null;
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int indexOf(Object object) {
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.indexOf(object);
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int lastIndexOf(Object object) {
51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.lastIndexOf(object);
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator() {
51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator();
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator(int location) {
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator(location);
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel remove(int location) {
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.remove(location);
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            decreaseMessageSize(slide.getSlideSize());
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel set(int location, SlideModel object) {
53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.get(location);
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null != object) {
53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int removeSize = 0;
53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int addSize = object.getSlideSize();
53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null != slide) {
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                removeSize = slide.getSlideSize();
53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (addSize > removeSize) {
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                checkMessageSize(addSize - removeSize);
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                increaseMessageSize(addSize - removeSize);
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                decreaseMessageSize(removeSize - addSize);
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slide =  mSlides.set(location, object);
54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        notifyModelChanged(true);
56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public List<SlideModel> subList(int start, int end) {
56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.subList(start, end);
56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void registerModelChangedObserverInDescendants(
57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.registerModelChangedObserver(observer);
57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.registerModelChangedObserver(observer);
57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterModelChangedObserverInDescendants(
58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterModelChangedObserver(observer);
58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterModelChangedObserver(observer);
58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterAllModelChangedObserversInDescendants() {
59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterAllModelChangedObservers();
59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
59572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
59672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onModelChanged(Model model, boolean dataChanged) {
59872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (dataChanged) {
59972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = null;
60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = null;
60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void sync(PduBody pb) {
60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
60672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = pb.getPartByContentLocation(media.getSrc());
60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (part != null) {
60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    media.setUri(part.getDataUri());
61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void checkMessageSize(int increaseSize) throws ContentRestrictionException {
61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
61710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        cr.checkMessageSize(mCurrentMessageSize, increaseSize, mContext.getContentResolver());
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
61910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Determines whether this is a "simple" slideshow.
62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Criteria:
62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one slide
62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one multimedia attachment, but no audio
62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - It can optionally have a caption
62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    */
62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isSimple() {
62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // There must be one (and only one) slide.
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (size() != 1)
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
63110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = get(0);
63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // The slide must have either an image or video, but not both.
63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!(slide.hasImage() ^ slide.hasVideo()))
63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
63610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
63772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // No audio allowed.
63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasAudio())
63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
64010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
64310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
6445d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    /**
6455d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * Make sure the text in slide 0 is no longer holding onto a reference to the text
6465d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * in the message text box.
64710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     */
6485d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    public void prepareForSend() {
6495d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        if (size() == 1) {
6505d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            TextModel text = get(0).getText();
6515d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            if (text != null) {
6525d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project                text.cloneText();
6535d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            }
6545d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        }
6555d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    }
65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
65710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    /**
65810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * Resize all the resizeable media objects to fit in the remaining size of the slideshow.
65910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * This should be called off of the UI thread.
66010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     *
66110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     * @throws MmsException, ExceedMessageSizeException
66210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor     */
66310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public void finalResize(Uri messageUri) throws MmsException, ExceedMessageSizeException {
66410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
66510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        // Figure out if we have any media items that need to be resized and total up the
66610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        // sizes of the items that can't be resized.
66710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        int resizableCnt = 0;
66810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        int fixedSizeTotal = 0;
66910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        for (SlideModel slide : mSlides) {
67010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (MediaModel media : slide) {
67110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                if (media.getMediaResizable()) {
67210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    ++resizableCnt;
67310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                } else {
67410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    fixedSizeTotal += media.getMediaSize();
67510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
67610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
67710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        }
6781db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
6791db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor            Log.v(TAG, "finalResize: original message size: " + getCurrentMessageSize() +
6801db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor                    " getMaxMessageSize: " + MmsConfig.getMaxMessageSize() +
6811db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor                    " fixedSizeTotal: " + fixedSizeTotal);
6821db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor        }
68310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        if (resizableCnt > 0) {
68410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int remainingSize = MmsConfig.getMaxMessageSize() - fixedSizeTotal - SLIDESHOW_SLOP;
68510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            if (remainingSize <= 0) {
68610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                throw new ExceedMessageSizeException("No room for pictures");
68710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
68810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            long messageId = ContentUris.parseId(messageUri);
68910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int bytesPerMediaItem = remainingSize / resizableCnt;
69010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // Resize the resizable media items to fit within their byte limit.
69110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (SlideModel slide : mSlides) {
69210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                for (MediaModel media : slide) {
69310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    if (media.getMediaResizable()) {
69410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                        media.resizeMedia(bytesPerMediaItem, messageId);
69510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    }
69610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
69710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
69810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // One last time through to calc the real message size.
69910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            int totalSize = 0;
70010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            for (SlideModel slide : mSlides) {
70110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                for (MediaModel media : slide) {
70210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                    totalSize += media.getMediaSize();
70310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                }
70410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
7051db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
7061db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor                Log.v(TAG, "finalResize: new message size: " + totalSize);
7071db5a0d573c462a5be6f8da636b4a7db18a7bf08Tom Taylor            }
70810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
70910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            if (totalSize > MmsConfig.getMaxMessageSize()) {
71010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                throw new ExceedMessageSizeException("After compressing pictures, message too big");
71110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
71210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            setCurrentMessageSize(totalSize);
71310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
71410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            onModelChanged(this, true);     // clear the cached pdu body
71510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            PduBody pb = toPduBody();
71610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // This will write out all the new parts to:
71710eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            //      /data/data/com.android.providers.telephony/app_parts
71810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            // and at the same time delete the old parts.
719469db72fcf219fd4c60bc9b01c728bdc3e866d40Tom Taylor            PduPersister.getPduPersister(mContext).updateParts(messageUri, pb, null);
72010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        }
72110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    }
72210eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
724