172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-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.dom.smil; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.ArrayList; 21d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Collections; 22d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.Comparator; 23d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.HashSet; 24d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chen 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.NodeList; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.DocumentEvent; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.Event; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.ElementParallelTimeContainer; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.ElementSequentialTimeContainer; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.ElementTime; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.Time; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.TimeList; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The SmilPlayer is responsible for playing, stopping, pausing and resuming a SMIL tree. 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>It creates a whole timeline before playing.</li> 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>The player runs in a different thread which intends not to block the main thread.</li> 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SmilPlayer implements Runnable { 439242286c35743422051d439d7460cd0a1426899cWei Huang private static final String TAG = "Mms/smil"; 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean DEBUG = false; 45150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato private static final boolean LOCAL_LOGV = false; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TIMESLICE = 200; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev private static enum SmilPlayerState { 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project INITIALIZED, 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PLAYING, 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PLAYED, 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PAUSED, 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project STOPPED, 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static enum SmilPlayerAction { 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NO_ACTIVE_ACTION, 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RELOAD, 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project STOP, 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PAUSE, 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project START, 62d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao NEXT, 63d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao PREV 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String MEDIA_TIME_UPDATED_EVENT = "mediaTimeUpdated"; 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final Comparator<TimelineEntry> sTimelineEntryComparator = 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new Comparator<TimelineEntry>() { 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int compare(TimelineEntry o1, TimelineEntry o2) { 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Double.compare(o1.getOffsetTime(), o2.getOffsetTime()); 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static SmilPlayer sPlayer; 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private long mCurrentTime; 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int mCurrentElement; 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int mCurrentSlide; 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ArrayList<TimelineEntry> mAllEntries; 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ElementTime mRoot; 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Thread mPlayerThread; 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private SmilPlayerState mState = SmilPlayerState.INITIALIZED; 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private SmilPlayerAction mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ArrayList<ElementTime> mActiveElements; 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Event mMediaTimeUpdatedEvent; 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static ArrayList<TimelineEntry> getParTimeline( 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementParallelTimeContainer par, double offset, double maxOffset) { 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>(); 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set my begin at first 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList myBeginList = par.getBegin(); 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Begin list only contain 1 begin time which has been resolved. 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getBegin() 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time begin = myBeginList.item(0); 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double beginOffset = begin.getResolvedOffset() + offset; 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (beginOffset > maxOffset) { 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This element can't be started. 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return timeline; 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry myBegin = new TimelineEntry(beginOffset, par, TimelineEntry.ACTION_BEGIN); 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(myBegin); 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList myEndList = par.getEnd(); 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * End list only contain 1 end time which has been resolved. 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @see com.android.mms.dom.smil.ElementParallelTimeContainerImpl#getEnd() 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time end = myEndList.item(0); 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double endOffset = end.getResolvedOffset() + offset; 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (endOffset > maxOffset) { 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endOffset = maxOffset; 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry myEnd = new TimelineEntry(endOffset, par, TimelineEntry.ACTION_END); 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project maxOffset = endOffset; 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NodeList children = par.getTimeChildren(); 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < children.getLength(); ++i) { 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime child = (ElementTime) children.item(i); 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset); 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.addAll(childTimeline); 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Collections.sort(timeline, sTimelineEntryComparator); 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Add end-event to timeline for all active children 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NodeList activeChildrenAtEnd = par.getActiveChildrenAt( 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (float) (endOffset - offset) * 1000); 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) { 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(new TimelineEntry(endOffset, 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (ElementTime) activeChildrenAtEnd.item(i), 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry.ACTION_END)); 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set my end at last 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(myEnd); 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return timeline; 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static ArrayList<TimelineEntry> getSeqTimeline( 14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementSequentialTimeContainer seq, double offset, double maxOffset) { 14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>(); 14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double orgOffset = offset; 14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set my begin at first 15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList myBeginList = seq.getBegin(); 15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Begin list only contain 1 begin time which has been resolved. 15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getBegin() 15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time begin = myBeginList.item(0); 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double beginOffset = begin.getResolvedOffset() + offset; 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (beginOffset > maxOffset) { 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This element can't be started. 16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return timeline; 16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry myBegin = new TimelineEntry(beginOffset, seq, TimelineEntry.ACTION_BEGIN); 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(myBegin); 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList myEndList = seq.getEnd(); 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * End list only contain 1 end time which has been resolved. 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @see com.android.mms.dom.smil.ElementSequentialTimeContainerImpl#getEnd() 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time end = myEndList.item(0); 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double endOffset = end.getResolvedOffset() + offset; 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (endOffset > maxOffset) { 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endOffset = maxOffset; 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry myEnd = new TimelineEntry(endOffset, seq, TimelineEntry.ACTION_END); 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project maxOffset = endOffset; 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Get children's timelines 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NodeList children = seq.getTimeChildren(); 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < children.getLength(); ++i) { 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime child = (ElementTime) children.item(i); 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ArrayList<TimelineEntry> childTimeline = getTimeline(child, offset, maxOffset); 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.addAll(childTimeline); 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Since the child timeline has been sorted, the offset of the last one is the biggest. 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project offset = childTimeline.get(childTimeline.size() - 1).getOffsetTime(); 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Add end-event to timeline for all active children 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NodeList activeChildrenAtEnd = seq.getActiveChildrenAt( 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (float) (endOffset - orgOffset)); 19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < activeChildrenAtEnd.getLength(); ++i) { 19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(new TimelineEntry(endOffset, 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project (ElementTime) activeChildrenAtEnd.item(i), 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry.ACTION_END)); 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set my end at last 20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(myEnd); 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return timeline; 20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static ArrayList<TimelineEntry> getTimeline(ElementTime element, 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double offset, double maxOffset) { 20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (element instanceof ElementParallelTimeContainer) { 20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return getParTimeline((ElementParallelTimeContainer) element, offset, maxOffset); 20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (element instanceof ElementSequentialTimeContainer) { 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return getSeqTimeline((ElementSequentialTimeContainer) element, offset, maxOffset); 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Not ElementTimeContainer here 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ArrayList<TimelineEntry> timeline = new ArrayList<TimelineEntry>(); 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList beginList = element.getBegin(); 21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < beginList.getLength(); ++i) { 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time begin = beginList.item(i); 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (begin.getResolved()) { 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double beginOffset = begin.getResolvedOffset() + offset; 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (beginOffset <= maxOffset) { 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = new TimelineEntry(beginOffset, 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element, TimelineEntry.ACTION_BEGIN); 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(entry); 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimeList endList = element.getEnd(); 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < endList.getLength(); ++i) { 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Time end = endList.item(i); 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (end.getResolved()) { 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double endOffset = end.getResolvedOffset() + offset; 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (endOffset <= maxOffset) { 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = new TimelineEntry(endOffset, 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element, TimelineEntry.ACTION_END); 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project timeline.add(entry); 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Collections.sort(timeline, sTimelineEntryComparator); 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return timeline; 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private SmilPlayer() { 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Private constructor 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static SmilPlayer getPlayer() { 25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (sPlayer == null) { 25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sPlayer = new SmilPlayer(); 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return sPlayer; 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized boolean isPlayingState() { 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mState == SmilPlayerState.PLAYING; 26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized boolean isPlayedState() { 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mState == SmilPlayerState.PLAYED; 26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized boolean isPausedState() { 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mState == SmilPlayerState.PAUSED; 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized boolean isStoppedState() { 27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mState == SmilPlayerState.STOPPED; 27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized boolean isPauseAction() { 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mAction == SmilPlayerAction.PAUSE; 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized boolean isStartAction() { 27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mAction == SmilPlayerAction.START; 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized boolean isStopAction() { 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mAction == SmilPlayerAction.STOP; 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized boolean isReloadAction() { 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mAction == SmilPlayerAction.RELOAD; 28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 290d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private synchronized boolean isNextAction() { 291d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return mAction == SmilPlayerAction.NEXT; 292d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 293d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 294d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private synchronized boolean isPrevAction() { 295d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return mAction == SmilPlayerAction.PREV; 296d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 297d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void init(ElementTime root) { 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mRoot = root; 30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAllEntries = getTimeline(mRoot, 0, Long.MAX_VALUE); 30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaTimeUpdatedEvent = ((DocumentEvent) mRoot).createEvent("Event"); 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaTimeUpdatedEvent.initEvent(MEDIA_TIME_UPDATED_EVENT, false, false); 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mActiveElements = new ArrayList<ElementTime>(); 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void play() { 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!isPlayingState()) { 30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentTime = 0; 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentElement = 0; 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentSlide = 0; 311ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev mPlayerThread = new Thread(this, "SmilPlayer thread"); 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mState = SmilPlayerState.PLAYING; 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mPlayerThread.start(); 31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Error State: Playback is playing!"); 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void pause() { 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPlayingState()) { 32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.PAUSE; 32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notifyAll(); 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Error State: Playback is not playing!"); 32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void start() { 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPausedState()) { 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project resumeActiveElements(); 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.START; 33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notifyAll(); 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (isPlayedState()) { 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project play(); 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Error State: Playback can not be started!"); 33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void stop() { 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPlayingState() || isPausedState()) { 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.STOP; 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notifyAll(); 34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (isPlayedState()) { 34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionStop(); 34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void stopWhenReload() { 35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endActiveElements(); 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized void reload() { 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPlayingState() || isPausedState()) { 35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.RELOAD; 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project notifyAll(); 35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (isPlayedState()) { 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionReload(); 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 362d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao public synchronized void next() { 363d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isPlayingState() || isPausedState()) { 364d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.NEXT; 365d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao notifyAll(); 366d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 367d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 368d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 369d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao public synchronized void prev() { 370d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isPlayingState() || isPausedState()) { 371d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.PREV; 372d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao notifyAll(); 373d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 374d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 375d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized boolean isBeginOfSlide(TimelineEntry entry) { 37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return (TimelineEntry.ACTION_BEGIN == entry.getAction()) 37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project && (entry.getElement() instanceof SmilParElementImpl); 37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void reloadActiveSlide() { 38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mActiveElements.clear(); 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project beginSmilDocument(); 38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = mCurrentSlide; i < mCurrentElement; i++) { 38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = mAllEntries.get(i); 38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionEntry(entry); 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project seekActiveMedia(); 39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void beginSmilDocument() { 39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = mAllEntries.get(0); 39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionEntry(entry); 39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized double getOffsetTime(ElementTime element) { 39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = mCurrentSlide; i < mCurrentElement; i++) { 39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = mAllEntries.get(i); 40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (element.equals(entry.getElement())) { 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return entry.getOffsetTime() * 1000; // in ms 40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return -1; 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void seekActiveMedia() { 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = mActiveElements.size() - 1; i >= 0; i--) { 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime element = mActiveElements.get(i); 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (element instanceof SmilParElementImpl) { 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project double offset = getOffsetTime(element); 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((offset >= 0) && (offset <= mCurrentTime)) { 41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[SEEK] " + " at " + mCurrentTime 41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " " + element); 41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element.seekElement( (float) (mCurrentTime - offset) ); 42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void waitForEntry(long interval) 42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throws InterruptedException { 42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Waiting for " + interval + "ms."); 42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long overhead = 0; 43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project while (interval > 0) { 43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long startAt = System.currentTimeMillis(); 43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long sleep = Math.min(interval, TIMESLICE); 43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (overhead < sleep) { 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project wait(sleep - overhead); 43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentTime += sleep; 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sleep = 0; 44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentTime += overhead; 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 443d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isStopAction() || isReloadAction() || isPauseAction() || isNextAction() || 444d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao isPrevAction()) { 44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ((EventTarget) mRoot).dispatchEvent(mMediaTimeUpdatedEvent); 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project interval -= TIMESLICE; 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project overhead = System.currentTimeMillis() - startAt - sleep; 45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized int getDuration() { 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((mAllEntries != null) && !mAllEntries.isEmpty()) { 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return (int) mAllEntries.get(mAllEntries.size() - 1).mOffsetTime * 1000; 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 0; 46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public synchronized int getCurrentPosition() { 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return (int) mCurrentTime; 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void endActiveElements() { 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = mActiveElements.size() - 1; i >= 0; i--) { 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime element = mActiveElements.get(i); 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[STOP] " + " at " + mCurrentTime 47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " " + element); 47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element.endElement(); 47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void pauseActiveElements() { 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = mActiveElements.size() - 1; i >= 0; i--) { 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime element = mActiveElements.get(i); 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[PAUSE] " + " at " + mCurrentTime 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " " + element); 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element.pauseElement(); 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void resumeActiveElements() { 48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int size = mActiveElements.size(); 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (int i = 0; i < size; i++) { 49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ElementTime element = mActiveElements.get(i); 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[RESUME] " + " at " + mCurrentTime 49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + " " + element); 49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project element.resumeElement(); 49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void waitForWakeUp() { 50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 502d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao while ( !(isStartAction() || isStopAction() || isReloadAction() || 503d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao isNextAction() || isPrevAction()) ) { 50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project wait(TIMESLICE); 50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isStartAction()) { 50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mState = SmilPlayerState.PLAYING; 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (InterruptedException e) { 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Unexpected InterruptedException.", e); 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void actionEntry(TimelineEntry entry) { 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (entry.getAction()) { 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TimelineEntry.ACTION_BEGIN: 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[START] " + " at " + mCurrentTime + " " 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + entry.getElement()); 52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project entry.getElement().beginElement(); 52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mActiveElements.add(entry.getElement()); 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TimelineEntry.ACTION_END: 52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "[STOP] " + " at " + mCurrentTime + " " 52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + entry.getElement()); 52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project entry.getElement().endElement(); 53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mActiveElements.remove(entry.getElement()); 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized TimelineEntry reloadCurrentEntry() { 5396a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla // Check if the position is less than size of all entries 5406a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (mCurrentElement < mAllEntries.size()) { 5416a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla return mAllEntries.get(mCurrentElement); 5426a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } else { 5436a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla return null; 5446a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla } 54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 547d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private void stopCurrentSlide() { 548d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao HashSet<TimelineEntry> skippedEntries = new HashSet<TimelineEntry>(); 549d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int totalEntries = mAllEntries.size(); 550d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (int i = mCurrentElement; i < totalEntries; i++) { 551d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // Stop any started entries, and skip the not started entries until 552d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // meeting the end of slide 553d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao TimelineEntry entry = mAllEntries.get(i); 554d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int action = entry.getAction(); 555d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (entry.getElement() instanceof SmilParElementImpl && 556d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao action == TimelineEntry.ACTION_END) { 557d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao actionEntry(entry); 558d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentElement = i; 559d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao break; 560d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else if (action == TimelineEntry.ACTION_END && !skippedEntries.contains(entry)) { 561d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao actionEntry(entry); 562d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else if (action == TimelineEntry.ACTION_BEGIN) { 563d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao skippedEntries.add(entry); 564d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 565d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 566d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 567d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 568d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private TimelineEntry loadNextSlide() { 569d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao TimelineEntry entry; 570d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int totalEntries = mAllEntries.size(); 571d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (int i = mCurrentElement; i < totalEntries; i++) { 572d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao entry = mAllEntries.get(i); 573d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isBeginOfSlide(entry)) { 574d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentElement = i; 575d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentSlide = i; 576d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentTime = (long)(entry.getOffsetTime() * 1000); 577d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return entry; 578d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 579d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 580d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // No slide, finish play back 581d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentElement++; 582d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao entry = null; 583d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (mCurrentElement < totalEntries) { 584d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao entry = mAllEntries.get(mCurrentElement); 585d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentTime = (long)(entry.getOffsetTime() * 1000); 586d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 587d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return entry; 588d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 589d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 590d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private TimelineEntry loadPrevSlide() { 591d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int skippedSlides = 1; 592d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int latestBeginEntryIndex = -1; 593d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (int i = mCurrentSlide; i >= 0; i--) { 594d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao TimelineEntry entry = mAllEntries.get(i); 595d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isBeginOfSlide(entry)) { 596d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao latestBeginEntryIndex = i; 597d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (0 == skippedSlides-- ) { 598d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentElement = i; 599d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentSlide = i; 600d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentTime = (long)(entry.getOffsetTime() * 1000); 601d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return entry; 602d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 603d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 604d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 605d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (latestBeginEntryIndex != -1) { 606d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentElement = latestBeginEntryIndex; 607d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mCurrentSlide = latestBeginEntryIndex; 608d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return mAllEntries.get(mCurrentElement); 609d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 610d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return null; 611d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 612d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 613d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private synchronized TimelineEntry actionNext() { 614d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao stopCurrentSlide(); 615d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return loadNextSlide(); 616d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 617d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 618d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private synchronized TimelineEntry actionPrev() { 619d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao stopCurrentSlide(); 620d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return loadPrevSlide(); 621d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 622d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void actionPause() { 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project pauseActiveElements(); 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mState = SmilPlayerState.PAUSED; 62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void actionStop() { 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endActiveElements(); 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentTime = 0; 63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentElement = 0; 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentSlide = 0; 63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mState = SmilPlayerState.STOPPED; 63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 63672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void actionReload() { 63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project reloadActiveSlide(); 64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isStoppedState()) { 64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 647d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (LOCAL_LOGV) { 648d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao dumpAllEntries(); 649d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Play the Element by following the timeline 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int size = mAllEntries.size(); 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (mCurrentElement = 0; mCurrentElement < size; mCurrentElement++) { 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TimelineEntry entry = mAllEntries.get(mCurrentElement); 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isBeginOfSlide(entry)) { 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentSlide = mCurrentElement; 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long offset = (long) (entry.getOffsetTime() * 1000); // in ms. 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project while (offset > mCurrentTime) { 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project waitForEntry(offset - mCurrentTime); 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (InterruptedException e) { 66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Unexpected InterruptedException.", e); 66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 665d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao while (isPauseAction() || isStopAction() || isReloadAction() || isNextAction() || 666d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao isPrevAction()) { 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPauseAction()) { 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionPause(); 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project waitForWakeUp(); 67072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isStopAction()) { 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionStop(); 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isReloadAction()) { 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionReload(); 67972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project entry = reloadCurrentEntry(); 6806a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla if (entry == null) 6816a7ba7cf4d775dbb29f3cafbee67d823149da5f1Naveen Kalla return; 68272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isPausedState()) { 68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = SmilPlayerAction.PAUSE; 68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 686d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 687d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isNextAction()) { 688d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao TimelineEntry nextEntry = actionNext(); 689d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (nextEntry != null) { 690d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao entry = nextEntry; 691d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 692d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (mState == SmilPlayerState.PAUSED) { 693d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.PAUSE; 694d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao actionEntry(entry); 695d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 696d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 697d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 698d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao offset = mCurrentTime; 699d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 700d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 701d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isPrevAction()) { 702d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao TimelineEntry prevEntry = actionPrev(); 703d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (prevEntry != null) { 704d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao entry = prevEntry; 705d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 706d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (mState == SmilPlayerState.PAUSED) { 707d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.PAUSE; 708d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao actionEntry(entry); 709d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 710d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mAction = SmilPlayerAction.NO_ACTIVE_ACTION; 711d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 712d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao offset = mCurrentTime; 713d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mCurrentTime = offset; 71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project actionEntry(entry); 71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mState = SmilPlayerState.PLAYED; 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final class TimelineEntry { 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final static int ACTION_BEGIN = 0; 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final static int ACTION_END = 1; 72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final double mOffsetTime; 72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final ElementTime mElement; 72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final int mAction; 73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public TimelineEntry(double offsetTime, ElementTime element, int action) { 73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mOffsetTime = offsetTime; 73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mElement = element; 73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mAction = action; 73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public double getOffsetTime() { 73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mOffsetTime; 73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ElementTime getElement() { 74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mElement; 74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int getAction() { 74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mAction; 74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 748d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 749d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao public String toString() { 750d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return "Type = " + mElement + " offset = " + getOffsetTime() + " action = " + getAction(); 751d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 752d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 753d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 754d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private void dumpAllEntries() { 755d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (LOCAL_LOGV) { 756d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (TimelineEntry entry : mAllEntries) { 757d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao Log.v(TAG, "[Entry] "+ entry); 758d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 759d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 762