SlideshowModel.java revision 9242286c35743422051d439d7460cd0a1426899c
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;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R;
2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.dom.smil.parser.SmilXmlSerializer;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.drm.DrmWrapper;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.layout.LayoutManager;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.ContentType;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.MmsException;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.GenericPdu;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.MultimediaMessagePdu;
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduBody;
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduHeaders;
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPart;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPersister;
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.NodeList;
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILDocument;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILElement;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILLayoutElement;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILMediaElement;
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILParElement;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRegionElement;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILRootLayoutElement;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.drm.mobile1.DrmException;
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.ByteArrayOutputStream;
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Collection;
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Iterator;
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.List;
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ListIterator;
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SlideshowModel extends Model
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        implements List<SlideModel>, IModelChangedObserver {
639242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = "Mms/slideshow";
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final LayoutModel mLayout;
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ArrayList<SlideModel> mSlides;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SMILDocument mDocumentCache;
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody mPduBodyCache;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private int mCurrentMessageSize;
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private ContentResolver mContentResolver;
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SlideshowModel(ContentResolver contentResolver) {
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = new LayoutModel();
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = new ArrayList<SlideModel>();
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentResolver = contentResolver;
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SlideshowModel (
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            LayoutModel layouts, ArrayList<SlideModel> slides,
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILDocument documentCache, PduBody pbCache,
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ContentResolver contentResolver) {
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout = layouts;
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSlides = slides;
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentResolver = contentResolver;
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mDocumentCache = documentCache;
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mPduBodyCache = pbCache;
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(slide.getSlideSize());
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setParent(this);
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createNew(Context context) {
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return new SlideshowModel(context.getContentResolver());
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromMessageUri(
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Context context, Uri uri) throws MmsException {
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return createFromPduBody(context, getPduBody(context, uri));
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static SlideshowModel createFromPduBody(Context context, PduBody pb) throws MmsException {
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILDocument document = SmilHelper.getDocument(pb);
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create root-layout model.
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILLayoutElement sle = document.getLayout();
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILRootLayoutElement srle = sle.getRootLayout();
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int w = srle.getWidth();
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int h = srle.getHeight();
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((w == 0) || (h == 0)) {
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            w = LayoutManager.getInstance().getLayoutParameters().getWidth();
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            h = LayoutManager.getInstance().getLayoutParameters().getHeight();
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setWidth(w);
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            srle.setHeight(h);
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        RegionModel rootLayout = new RegionModel(
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                null, 0, 0, w, h);
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create region models.
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList nlRegions = sle.getRegions();
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int regionsNum = nlRegions.getLength();
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < regionsNum; i++) {
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILRegionElement sre = (SMILRegionElement) nlRegions.item(i);
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            RegionModel r = new RegionModel(sre.getId(), sre.getFit(),
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getLeft(), sre.getTop(), sre.getWidth(), sre.getHeight(),
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    sre.getBackgroundColor());
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            regions.add(r);
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        LayoutModel layouts = new LayoutModel(rootLayout, regions);
13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create slide models.
13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SMILElement docBody = document.getBody();
13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        NodeList slideNodes = docBody.getChildNodes();
13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int slidesNum = slideNodes.getLength();
13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<SlideModel> slides = new ArrayList<SlideModel>(slidesNum);
13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < slidesNum; i++) {
14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // FIXME: This is NOT compatible with the SMILDocument which is
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // generated by some other mobile phones.
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SMILParElement par = (SMILParElement) slideNodes.item(i);
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Create media models for each slide.
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            NodeList mediaNodes = par.getChildNodes();
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int mediaNum = mediaNodes.getLength();
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum);
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (int j = 0; j < mediaNum; j++) {
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                SMILMediaElement sme = (SMILMediaElement) mediaNodes.item(j);
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MediaModel media = MediaModelFactory.getMediaModel(
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            context, sme, layouts, pb);
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmilHelper.addMediaElementEventListeners(
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            (EventTarget) sme, media);
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mediaSet.add(media);
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (DrmException e) {
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IllegalArgumentException e) {
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, e.getMessage(), e);
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = new SlideModel((int) (par.getDur() * 1000), mediaSet);
16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.setFill(par.getFill());
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SmilHelper.addParElementEventListeners((EventTarget) par, slide);
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slides.add(slide);
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb,
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                context.getContentResolver());
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slideshow.registerModelChangedObserver(slideshow);
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slideshow;
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public PduBody toPduBody() {
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mPduBodyCache == null) {
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = makePduBody(mDocumentCache);
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mPduBodyCache;
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody makePduBody(SMILDocument document) {
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return makePduBody(null, document, false);
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private PduBody makePduBody(Context context, SMILDocument document, boolean isMakingCopy) {
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduBody pb = new PduBody();
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean hasForwardLock = false;
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isMakingCopy) {
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (media.isDrmProtected() && !media.isAllowedToForward()) {
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        hasForwardLock = true;
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        continue;
20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = new PduPart();
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (media.isText()) {
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    TextModel text = (TextModel) media;
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Don't create empty text part.
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (TextUtils.isEmpty(text.getText())) {
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        continue;
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Set Charset if it's a text media.
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setCharset(text.getCharset());
21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Type.
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentType(media.getContentType().getBytes());
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String src = media.getSrc();
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String location;
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                boolean startWithContentId = src.startsWith("cid:");
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src.substring("cid:".length());
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = src;
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Location.
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                part.setContentLocation(location.getBytes());
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Set Content-Id.
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (startWithContentId) {
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    //Keep the original Content-Id.
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(location.getBytes());
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                else {
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int index = location.lastIndexOf(".");
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String contentId = (index == -1) ? location
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            : location.substring(0, index);
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setContentId(contentId.getBytes());
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (media.isDrmProtected()) {
24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    DrmWrapper wrapper = media.getDrmObject();
24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setDataUri(wrapper.getOriginalUri());
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setData(wrapper.getOriginalData());
24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (media.isText()) {
24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setData(((TextModel) media).getText().getBytes());
24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else if (media.isImage() || media.isVideo() || media.isAudio()) {
25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    part.setDataUri(media.getUri());
25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "Unsupport media: " + media);
25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                pb.addPart(part);
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (hasForwardLock && isMakingCopy && context != null) {
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Toast.makeText(context,
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    context.getString(R.string.cannot_forward_drm_obj),
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Toast.LENGTH_LONG).show();
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            document = SmilHelper.getDocument(pb);
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Create and insert SMIL part(as the first part) into the PduBody.
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ByteArrayOutputStream out = new ByteArrayOutputStream();
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SmilXmlSerializer.serialize(document, out);
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPart smilPart = new PduPart();
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentId("smil".getBytes());
27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentLocation("smil.xml".getBytes());
27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setContentType(ContentType.APP_SMIL.getBytes());
27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        smilPart.setData(out.toByteArray());
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        pb.addPart(0, smilPart);
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return pb;
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public PduBody makeCopy(Context context) {
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return makePduBody(context, SmilHelper.getDocument(this), true);
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SMILDocument toSmilDocument() {
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mDocumentCache == null) {
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = SmilHelper.getDocument(this);
28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mDocumentCache;
28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static PduBody getPduBody(Context context, Uri msg) throws MmsException {
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        PduPersister p = PduPersister.getPduPersister(context);
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        GenericPdu pdu = p.load(msg);
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgType = pdu.getMessageType();
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)) {
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return ((MultimediaMessagePdu) pdu).getBody();
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new MmsException();
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void setCurrentMessageSize(int size) {
30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mCurrentMessageSize = size;
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int getCurrentMessageSize() {
30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mCurrentMessageSize;
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void increaseMessageSize(int increaseSize) {
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (increaseSize > 0) {
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize += increaseSize;
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void decreaseMessageSize(int decreaseSize) {
31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (decreaseSize > 0) {
31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize -= decreaseSize;
32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public LayoutModel getLayout() {
32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mLayout;
32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Implement List<E> interface.
32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //
33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean add(SlideModel object) {
33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int increaseSize = object.getSlideSize();
33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        checkMessageSize(increaseSize);
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.add(object)) {
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(Collection<? extends SlideModel> collection) {
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void clear() {
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mSlides.size() > 0) {
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (SlideModel slide : mSlides) {
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                slide.unregisterModelChangedObserver(this);
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (IModelChangedObserver observer : mModelChangedObservers) {
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    slide.unregisterModelChangedObserver(observer);
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mCurrentMessageSize = 0;
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.clear();
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean contains(Object object) {
36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.contains(object);
36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean containsAll(Collection<?> collection) {
36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.containsAll(collection);
37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isEmpty() {
37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.isEmpty();
37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Iterator<SlideModel> iterator() {
37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.iterator();
37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean remove(Object object) {
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((object != null) && mSlides.remove(object)) {
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SlideModel slide = (SlideModel) object;
38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            decreaseMessageSize(slide.getSlideSize());
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean removeAll(Collection<?> collection) {
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean retainAll(Collection<?> collection) {
39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int size() {
40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.size();
40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public Object[] toArray() {
40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray();
40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public <T> T[] toArray(T[] array) {
40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.toArray(array);
40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void add(int location, SlideModel object) {
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int increaseSize = object.getSlideSize();
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            checkMessageSize(increaseSize);
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSlides.add(location, object);
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            increaseMessageSize(increaseSize);
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            notifyModelChanged(true);
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean addAll(int location,
42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Collection<? extends SlideModel> collection) {
42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        throw new UnsupportedOperationException("Operation not supported.");
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel get(int location) {
43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.get(location);
43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int indexOf(Object object) {
43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.indexOf(object);
43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public int lastIndexOf(Object object) {
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.lastIndexOf(object);
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator() {
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator();
44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public ListIterator<SlideModel> listIterator(int location) {
44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.listIterator(location);
44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel remove(int location) {
45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.remove(location);
45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
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        }
45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public SlideModel set(int location, SlideModel object) {
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = mSlides.get(location);
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null != object) {
46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int removeSize = 0;
46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int addSize = object.getSlideSize();
46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null != slide) {
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                removeSize = slide.getSlideSize();
46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (addSize > removeSize) {
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                checkMessageSize(addSize - removeSize);
47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                increaseMessageSize(addSize - removeSize);
47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                decreaseMessageSize(removeSize - addSize);
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        slide =  mSlides.set(location, object);
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide != null) {
47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (object != null) {
48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            object.registerModelChangedObserver(this);
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (IModelChangedObserver observer : mModelChangedObservers) {
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                object.registerModelChangedObserver(observer);
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        notifyModelChanged(true);
49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return slide;
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public List<SlideModel> subList(int start, int end) {
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return mSlides.subList(start, end);
49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void registerModelChangedObserverInDescendants(
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.registerModelChangedObserver(observer);
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.registerModelChangedObserver(observer);
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterModelChangedObserverInDescendants(
50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            IModelChangedObserver observer) {
51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterModelChangedObserver(observer);
51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterModelChangedObserver(observer);
51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void unregisterAllModelChangedObserversInDescendants() {
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mLayout.unregisterAllModelChangedObservers();
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            slide.unregisterAllModelChangedObservers();
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onModelChanged(Model model, boolean dataChanged) {
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (dataChanged) {
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDocumentCache = null;
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPduBodyCache = null;
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void sync(PduBody pb) {
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (SlideModel slide : mSlides) {
53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (MediaModel media : slide) {
53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PduPart part = pb.getPartByContentLocation(media.getSrc());
53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (part != null) {
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    media.setUri(part.getDataUri());
53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void checkMessageSize(int increaseSize) throws ContentRestrictionException {
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        cr.checkMessageSize(mCurrentMessageSize, increaseSize, mContentResolver);
54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Determines whether this is a "simple" slideshow.
55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Criteria:
55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one slide
55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - Exactly one multimedia attachment, but no audio
55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * - It can optionally have a caption
55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    */
55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean isSimple() {
55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // There must be one (and only one) slide.
55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (size() != 1)
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SlideModel slide = get(0);
56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // The slide must have either an image or video, but not both.
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!(slide.hasImage() ^ slide.hasVideo()))
56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // No audio allowed.
56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (slide.hasAudio())
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5725d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project
5735d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    /**
5745d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * Make sure the text in slide 0 is no longer holding onto a reference to the text
5755d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project     * in the message text box.
5765d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    */
5775d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    public void prepareForSend() {
5785d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        if (size() == 1) {
5795d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            TextModel text = get(0).getText();
5805d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            if (text != null) {
5815d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project                text.cloneText();
5825d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project            }
5835d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        }
5845d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    }
58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
587