Home | History | Annotate | Download | only in smil
      1 /*
      2  * Copyright (C) 2007-2008 Esmertec AG.
      3  * Copyright (C) 2007-2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.dom.smil;
     19 
     20 import java.util.ArrayList;
     21 
     22 import org.w3c.dom.DOMException;
     23 import org.w3c.dom.Node;
     24 import org.w3c.dom.NodeList;
     25 import org.w3c.dom.smil.ElementParallelTimeContainer;
     26 import org.w3c.dom.smil.ElementTime;
     27 import org.w3c.dom.smil.SMILElement;
     28 import org.w3c.dom.smil.Time;
     29 import org.w3c.dom.smil.TimeList;
     30 
     31 import com.android.mms.dom.NodeListImpl;
     32 
     33 public abstract class ElementParallelTimeContainerImpl extends ElementTimeContainerImpl
     34         implements ElementParallelTimeContainer {
     35     private final static String ENDSYNC_ATTRIBUTE_NAME = "endsync";
     36     private final static String ENDSYNC_FIRST = "first";
     37     private final static String ENDSYNC_LAST  = "last";
     38     private final static String ENDSYNC_ALL   = "all";
     39     private final static String ENDSYNC_MEDIA = "media";
     40 
     41     /*
     42      * Internal Interface
     43      */
     44 
     45     ElementParallelTimeContainerImpl(SMILElement element) {
     46         super(element);
     47     }
     48 
     49     public String getEndSync() {
     50         String endsync = mSmilElement.getAttribute(ENDSYNC_ATTRIBUTE_NAME);
     51         if ((endsync == null) || (endsync.length() == 0)) {
     52             setEndSync(ENDSYNC_LAST);
     53             return ENDSYNC_LAST;
     54         }
     55         if (ENDSYNC_FIRST.equals(endsync) || ENDSYNC_LAST.equals(endsync) ||
     56                 ENDSYNC_ALL.equals(endsync) || ENDSYNC_MEDIA.equals(endsync)) {
     57             return endsync;
     58         }
     59 
     60         // FIXME add the checking for ID-Value and smil1.0-Id-value.
     61 
     62         setEndSync(ENDSYNC_LAST);
     63         return ENDSYNC_LAST;
     64     }
     65 
     66     public void setEndSync(String endSync) throws DOMException {
     67         if (ENDSYNC_FIRST.equals(endSync) || ENDSYNC_LAST.equals(endSync) ||
     68                 ENDSYNC_ALL.equals(endSync) || ENDSYNC_MEDIA.equals(endSync)) {
     69             mSmilElement.setAttribute(ENDSYNC_ATTRIBUTE_NAME, endSync);
     70         } else { // FIXME add the support for ID-Value and smil1.0-Id-value.
     71             throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
     72                     "Unsupported endsync value" + endSync);
     73         }
     74     }
     75 
     76     @Override
     77     public float getDur() {
     78         float dur = super.getDur();
     79         if (dur == 0) {
     80             dur = getImplicitDuration();
     81         }
     82         return dur;
     83     }
     84 
     85     public float getImplicitDuration() {
     86         float dur = -1.0F;
     87         if (ENDSYNC_LAST.equals(getEndSync())) {
     88             NodeList children = getTimeChildren();
     89             for (int i = 0; i < children.getLength(); ++i) {
     90                 ElementTime child = (ElementTime) children.item(i);
     91                 TimeList endTimeList = child.getEnd();
     92                 for (int j = 0; j < endTimeList.getLength(); ++j) {
     93                     Time endTime = endTimeList.item(j);
     94                     if (endTime.getTimeType() == Time.SMIL_TIME_INDEFINITE) {
     95                         // Return "indefinite" here.
     96                         return -1.0F;
     97                     }
     98                     if (endTime.getResolved()) {
     99                         float end = (float)endTime.getResolvedOffset();
    100                         dur = (end > dur) ? end : dur;
    101                     }
    102                 }
    103             }
    104         } // Other endsync types are not supported now.
    105 
    106         return dur;
    107     }
    108 
    109     public NodeList getActiveChildrenAt(float instant) {
    110         /*
    111          * Find the closest Time of ElementTime before instant.
    112          * Add ElementTime to list of active elements if the Time belongs to the begin-list,
    113          * do not add it otherwise.
    114          */
    115         ArrayList<Node> activeChildren = new ArrayList<Node>();
    116         NodeList children = getTimeChildren();
    117         int childrenLen = children.getLength();
    118         for (int i = 0; i < childrenLen; ++i) {
    119             double maxOffset = 0.0;
    120             boolean active = false;
    121             ElementTime child = (ElementTime) children.item(i);
    122 
    123             TimeList beginList = child.getBegin();
    124             int len = beginList.getLength();
    125             for (int j = 0; j < len; ++j) {
    126                 Time begin = beginList.item(j);
    127                 if (begin.getResolved()) {
    128                     double resolvedOffset = begin.getResolvedOffset() * 1000.0;
    129                     if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
    130                         maxOffset = resolvedOffset;
    131                         active = true;
    132                     }
    133                 }
    134             }
    135 
    136             TimeList endList = child.getEnd();
    137             len = endList.getLength();
    138             for (int j = 0; j < len; ++j) {
    139                 Time end = endList.item(j);
    140                 if (end.getResolved()) {
    141                     double resolvedOffset = end.getResolvedOffset() * 1000.0;
    142                     if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
    143                         maxOffset = resolvedOffset;
    144                         active = false;
    145                     }
    146                 }
    147             }
    148 
    149             if (active) {
    150                 activeChildren.add((Node) child);
    151             }
    152         }
    153         return new NodeListImpl(activeChildren);
    154     }
    155 }
    156