FileDocCategorySizeDatePackage
SmilHelper.javaAPI DocAndroid 1.5 API16853Wed May 06 22:42:46 BST 2009com.android.mms.model

SmilHelper

public class SmilHelper extends Object

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final boolean
LOCAL_LOGV
public static final String
ELEMENT_TAG_TEXT
public static final String
ELEMENT_TAG_IMAGE
public static final String
ELEMENT_TAG_AUDIO
public static final String
ELEMENT_TAG_VIDEO
public static final String
ELEMENT_TAG_REF
Constructors Summary
private SmilHelper()


      
        // Never instantiate this class.
    
Methods Summary
static voidaddMediaElementEventListeners(org.w3c.dom.events.EventTarget target, MediaModel media)

        // To play the media with SmilPlayer, we should add them
        // as EventListener into an EventTarget.
        target.addEventListener(SMIL_MEDIA_START_EVENT, media, false);
        target.addEventListener(SMIL_MEDIA_END_EVENT, media, false);
        target.addEventListener(SMIL_MEDIA_PAUSE_EVENT, media, false);
        target.addEventListener(SMIL_MEDIA_SEEK_EVENT, media, false);
    
public static org.w3c.dom.smil.SMILParElementaddPar(org.w3c.dom.smil.SMILDocument document)

        SMILParElement par = (SMILParElement) document.createElement("par");
        // Set duration to eight seconds by default.
        par.setDur(8.0f);
        document.getBody().appendChild(par);
        return par;
    
static voidaddParElementEventListeners(org.w3c.dom.events.EventTarget target, SlideModel slide)

        // To play the slide with SmilPlayer, we should add it
        // as EventListener into an EventTarget.
        target.addEventListener(SMIL_SLIDE_START_EVENT, slide, false);
        target.addEventListener(SMIL_SLIDE_END_EVENT, slide, false);
    
public static org.w3c.dom.smil.SMILMediaElementcreateMediaElement(java.lang.String tag, org.w3c.dom.smil.SMILDocument document, java.lang.String src)

        SMILMediaElement mediaElement =
                (SMILMediaElement) document.createElement(tag);
        mediaElement.setSrc(src);
        return mediaElement;
    
private static org.w3c.dom.smil.SMILDocumentcreateSmilDocument(SlideshowModel slideshow)

        if (Config.LOGV) {
            Log.v(TAG, "Creating SMIL document from SlideshowModel.");
        }

        SMILDocument document = new SmilDocumentImpl();

        // Create SMIL and append it to document
        SMILElement smilElement = (SMILElement) document.createElement("smil");
        document.appendChild(smilElement);

        // Create HEAD and append it to SMIL
        SMILElement headElement = (SMILElement) document.createElement("head");
        smilElement.appendChild(headElement);

        // Create LAYOUT and append it to HEAD
        SMILLayoutElement layoutElement = (SMILLayoutElement)
                document.createElement("layout");
        headElement.appendChild(layoutElement);

        // Create ROOT-LAYOUT and append it to LAYOUT
        SMILRootLayoutElement rootLayoutElement =
                (SMILRootLayoutElement) document.createElement("root-layout");
        LayoutModel layouts = slideshow.getLayout();
        rootLayoutElement.setWidth(layouts.getLayoutWidth());
        rootLayoutElement.setHeight(layouts.getLayoutHeight());
        String bgColor = layouts.getBackgroundColor();
        if (!TextUtils.isEmpty(bgColor)) {
            rootLayoutElement.setBackgroundColor(bgColor);
        }
        layoutElement.appendChild(rootLayoutElement);

        // Create REGIONs and append them to LAYOUT
        ArrayList<RegionModel> regions = layouts.getRegions();
        ArrayList<SMILRegionElement> smilRegions = new ArrayList<SMILRegionElement>();
        for (RegionModel r : regions) {
            SMILRegionElement smilRegion = (SMILRegionElement) document.createElement("region");
            smilRegion.setId(r.getRegionId());
            smilRegion.setLeft(r.getLeft());
            smilRegion.setTop(r.getTop());
            smilRegion.setWidth(r.getWidth());
            smilRegion.setHeight(r.getHeight());
            smilRegion.setFit(r.getFit());
            smilRegions.add(smilRegion);
        }

        // Create BODY and append it to the document.
        SMILElement bodyElement = (SMILElement) document.createElement("body");
        smilElement.appendChild(bodyElement);

        boolean txtRegionPresentInLayout = false;
        boolean imgRegionPresentInLayout = false;
        for (SlideModel slide : slideshow) {
            // Create PAR element.
            SMILParElement par = addPar(document);
            par.setDur(slide.getDuration() / 1000f);

            addParElementEventListeners((EventTarget) par, slide);

            // Add all media elements.
            for (MediaModel media : slide) {
                SMILMediaElement sme = null;
                String src = media.getSrc();
                if (media instanceof TextModel) {
                    TextModel text = (TextModel) media;
                    if (TextUtils.isEmpty(text.getText())) {
                        if (LOCAL_LOGV) {
                            Log.v(TAG, "Empty text part ignored: " + text.getSrc());
                        }
                        continue;
                    }
                    sme = SmilHelper.createMediaElement(SmilHelper.ELEMENT_TAG_TEXT, document, src);
                    txtRegionPresentInLayout = setRegion((SMILRegionMediaElement) sme,
                                                         smilRegions,
                                                         layoutElement,
                                                         LayoutModel.TEXT_REGION_ID,
                                                         txtRegionPresentInLayout);
                } else if (media instanceof ImageModel) {
                    sme = SmilHelper.createMediaElement(SmilHelper.ELEMENT_TAG_IMAGE, document, src);
                    imgRegionPresentInLayout = setRegion((SMILRegionMediaElement) sme,
                                                         smilRegions,
                                                         layoutElement,
                                                         LayoutModel.IMAGE_REGION_ID,
                                                         imgRegionPresentInLayout);
                } else if (media instanceof VideoModel) {
                    sme = SmilHelper.createMediaElement(SmilHelper.ELEMENT_TAG_VIDEO, document, src);
                    imgRegionPresentInLayout = setRegion((SMILRegionMediaElement) sme,
                                                         smilRegions,
                                                         layoutElement,
                                                         LayoutModel.IMAGE_REGION_ID,
                                                         imgRegionPresentInLayout);
                } else if (media instanceof AudioModel) {
                    sme = SmilHelper.createMediaElement(SmilHelper.ELEMENT_TAG_AUDIO, document, src);
                } else {
                    Log.w(TAG, "Unsupport media: " + media);
                    continue;
                }

                // Set timing information.
                int begin = media.getBegin();
                if (begin != 0) {
                    sme.setAttribute("begin", String.valueOf(begin / 1000));
                }
                int duration = media.getDuration();
                if (duration != 0) {
                    sme.setDur((float) duration / 1000);
                }
                par.appendChild(sme);

                addMediaElementEventListeners((EventTarget) sme, media);
            }
        }

        if (LOCAL_LOGV) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            SmilXmlSerializer.serialize(document, out);
            Log.v(TAG, out.toString());
        }

        return document;
    
private static org.w3c.dom.smil.SMILDocumentcreateSmilDocument(com.google.android.mms.pdu.PduBody pb)

        if (Config.LOGV) {
            Log.v(TAG, "Creating default SMIL document.");
        }

        SMILDocument document = new SmilDocumentImpl();

        // Create root element.
        // FIXME: Should we create root element in the constructor of document?
        SMILElement smil = (SMILElement) document.createElement("smil");
        smil.setAttribute("xmlns", "http://www.w3.org/2001/SMIL20/Language");
        document.appendChild(smil);

        // Create <head> and <layout> element.
        SMILElement head = (SMILElement) document.createElement("head");
        smil.appendChild(head);

        SMILLayoutElement layout = (SMILLayoutElement) document.createElement("layout");
        head.appendChild(layout);

        // Create <body> element and add a empty <par>.
        SMILElement body = (SMILElement) document.createElement("body");
        smil.appendChild(body);
        SMILParElement par = addPar(document);

        // Create media objects for the parts in PDU.
        int partsNum = pb.getPartsNum();
        if (partsNum == 0) {
            return document;
        }

        boolean hasText = false;
        boolean hasMedia = false;
        for (int i = 0; i < partsNum; i++) {
            // Create new <par> element.
            if ((par == null) || (hasMedia && hasText)) {
                par = addPar(document);
                hasText = false;
                hasMedia = false;
            }

            PduPart part = pb.getPart(i);
            String contentType = new String(part.getContentType());
            if (ContentType.isDrmType(contentType)) {
                DrmWrapper dw;
                try {
                    dw = new DrmWrapper(contentType, part.getDataUri(),
                                        part.getData());
                    contentType = dw.getContentType();
                } catch (DrmException e) {
                    Log.e(TAG, e.getMessage(), e);
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage(), e);
                }
            }

            if (contentType.equals(ContentType.TEXT_PLAIN)
                    || contentType.equalsIgnoreCase(ContentType.APP_WAP_XHTML)) {
                SMILMediaElement textElement = createMediaElement(
                        ELEMENT_TAG_TEXT, document, part.generateLocation());
                par.appendChild(textElement);
                hasText = true;
            } else if (ContentType.isImageType(contentType)) {
                SMILMediaElement imageElement = createMediaElement(
                        ELEMENT_TAG_IMAGE, document, part.generateLocation());
                par.appendChild(imageElement);
                hasMedia = true;
            } else if (ContentType.isVideoType(contentType)) {
                SMILMediaElement videoElement = createMediaElement(
                        ELEMENT_TAG_VIDEO, document, part.generateLocation());
                par.appendChild(videoElement);
                hasMedia = true;
            } else if (ContentType.isAudioType(contentType)) {
                SMILMediaElement audioElement = createMediaElement(
                        ELEMENT_TAG_AUDIO, document, part.generateLocation());
                par.appendChild(audioElement);
                hasMedia = true;
            } else {
                // TODO: handle other media types.
                Log.w(TAG, "unsupport media type");
            }
        }

        return document;
    
private static org.w3c.dom.smil.SMILRegionElementfindRegionElementById(java.util.ArrayList smilRegions, java.lang.String rId)

        for (SMILRegionElement smilRegion : smilRegions) {
            if (smilRegion.getId().equals(rId)) {
                return smilRegion;
            }
        }
        return null;
    
private static com.google.android.mms.pdu.PduPartfindSmilPart(com.google.android.mms.pdu.PduBody body)
Find a SMIL part in the MM.

return
The existing SMIL part or null if no SMIL part was found.

        int partNum = body.getPartsNum();
        for(int i = 0; i < partNum; i++) {
            PduPart part = body.getPart(i);
            if (Arrays.equals(part.getContentType(),
                            ContentType.APP_SMIL.getBytes())) {
                // Sure only one SMIL part.
                return part;
            }
        }
        return null;
    
public static org.w3c.dom.smil.SMILDocumentgetDocument(com.google.android.mms.pdu.PduBody pb)

        // Find SMIL part in the message.
        PduPart smilPart = findSmilPart(pb);
        SMILDocument document = null;

        // Try to load SMIL document from existing part.
        if (smilPart != null) {
            document = getSmilDocument(smilPart);
        }

        if (document == null) {
            // Create a new SMIL document.
            document = createSmilDocument(pb);
        }

        return document;
    
public static org.w3c.dom.smil.SMILDocumentgetDocument(SlideshowModel model)

        return createSmilDocument(model);
    
private static org.w3c.dom.smil.SMILDocumentgetSmilDocument(com.google.android.mms.pdu.PduPart smilPart)
Parse SMIL message and retrieve SMILDocument.

return
A SMILDocument or null if parsing failed.

        try {
            byte[] data = smilPart.getData();
            if (data != null) {
                if (LOCAL_LOGV) {
                    Log.v(TAG, "Parsing SMIL document.");
                    Log.v(TAG, new String(data));
                }

                ByteArrayInputStream bais = new ByteArrayInputStream(data);
                SMILDocument document = new SmilXmlParser().parse(bais);
                return validate(document);
            }
        } catch (IOException e) {
            Log.e(TAG, "Failed to parse SMIL document.", e);
        } catch (SAXException e) {
            Log.e(TAG, "Failed to parse SMIL document.", e);
        } catch (MmsException e) {
            Log.e(TAG, "Failed to parse SMIL document.", e);
        }
        return null;
    
private static booleansetRegion(org.w3c.dom.smil.SMILRegionMediaElement srme, java.util.ArrayList smilRegions, org.w3c.dom.smil.SMILLayoutElement smilLayout, java.lang.String regionId, boolean regionPresentInLayout)

        SMILRegionElement smilRegion = findRegionElementById(smilRegions, regionId);
        if (!regionPresentInLayout && smilRegion != null) {
            srme.setRegion(smilRegion);
            smilLayout.appendChild(smilRegion);
            return true;
        }
        return false;
    
private static org.w3c.dom.smil.SMILDocumentvalidate(org.w3c.dom.smil.SMILDocument in)

        // TODO: add more validating facilities.
        return in;