172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.ui; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.io.ByteArrayOutputStream; 2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport org.w3c.dom.NamedNodeMap; 23d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport org.w3c.dom.Node; 24d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport org.w3c.dom.NodeList; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.Event; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventListener; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.smil.SMILDocument; 29d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport org.w3c.dom.smil.SMILElement; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.PixelFormat; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Bundle; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.KeyEvent; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.MotionEvent; 40d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport android.view.View; 41d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Taoimport android.view.View.OnClickListener; 42d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.view.Window; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.MediaController; 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.MediaController.MediaPlayerControl; 45828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predonimport android.widget.SeekBar; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 48d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.AttrImpl; 49d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.SmilDocumentImpl; 50d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.SmilPlayer; 51d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.parser.SmilXmlSerializer; 52d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.LayoutModel; 53d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.RegionModel; 54d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SlideshowModel; 55d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SmilHelper; 56d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException; 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Plays the given slideshow in full-screen mode with a common controller. 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SlideshowActivity extends Activity implements EventListener { 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "SlideshowActivity"; 6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean DEBUG = false; 64150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato private static final boolean LOCAL_LOGV = false; 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private MediaController mMediaController; 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private SmilPlayer mSmilPlayer; 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Handler mHandler; 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private SMILDocument mSmilDoc; 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 73d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private SlideView mSlideView; 74257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor private int mSlideCount; 75d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 76d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao /** 77d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao * @return whether the Smil has MMS conformance layout. 78d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao * Refer to MMS Conformance Document OMA-MMS-CONF-v1_2-20050301-A 79d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao */ 80d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao private static final boolean isMMSConformance(SMILDocument smilDoc) { 81d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao SMILElement head = smilDoc.getHead(); 82d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (head == null) { 83d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // No 'head' element 84d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 85d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 86d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao NodeList children = head.getChildNodes(); 87d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (children == null || children.getLength() != 1) { 88d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The 'head' element should have only one child. 89d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 90d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 91d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao Node layout = children.item(0); 92d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (layout == null || !"layout".equals(layout.getNodeName())) { 93d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The child is not layout element 94d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 95d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 96d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao NodeList layoutChildren = layout.getChildNodes(); 97d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (layoutChildren == null) { 98d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The 'layout' element has no child. 99d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 100d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 101d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int num = layoutChildren.getLength(); 102d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (num <= 0) { 103d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The 'layout' element has no child. 104d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 105d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 106d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (int i = 0; i < num; i++) { 107d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao Node layoutChild = layoutChildren.item(i); 108d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (layoutChild == null) { 109d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The 'layout' child is null. 110d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 111d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 112d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao String name = layoutChild.getNodeName(); 113d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if ("root-layout".equals(name)) { 114d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao continue; 115d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else if ("region".equals(name)) { 116d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao NamedNodeMap map = layoutChild.getAttributes(); 117d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao for (int j = 0; j < map.getLength(); j++) { 118d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao Node node = map.item(j); 119d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (node == null) { 120d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 121d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 122d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao String attrName = node.getNodeName(); 123d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The attr should be one of left, top, height, width, fit and id 124d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if ("left".equals(attrName) || "top".equals(attrName) || 125d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao "height".equals(attrName) || "width".equals(attrName) || 126d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao "fit".equals(attrName)) { 127d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao continue; 128d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else if ("id".equals(attrName)) { 129d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao String value; 130d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (node instanceof AttrImpl) { 131d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao value = ((AttrImpl)node).getValue(); 132d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 133d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 134d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 135d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if ("Text".equals(value) || "Image".equals(value)) { 136d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao continue; 137d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 138d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The id attr is not 'Text' or 'Image' 139d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 140d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 141d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 142d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 143d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 144d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 145d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } else { 146d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao // The 'layout' element has the child other than 'root-layout' or 'region' 147d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return false; 148d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 149d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 150d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao return true; 151d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 152d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao 15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreate(Bundle icicle) { 15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onCreate(icicle); 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mHandler = new Handler(); 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Play slide-show in full-screen mode. 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project requestWindowFeature(Window.FEATURE_NO_TITLE); 16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project getWindow().setFormat(PixelFormat.TRANSLUCENT); 16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project setContentView(R.layout.slideshow); 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = getIntent(); 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri msg = intent.getData(); 16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final SlideshowModel model; 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project model = SlideshowModel.createFromMessageUri(this, msg); 169257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor mSlideCount = model.size(); 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (MmsException e) { 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Cannot present the slide show.", e); 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project finish(); 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 176d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mSlideView = (SlideView) findViewById(R.id.slide_view); 177d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao PresenterFactory.getPresenter("SlideshowPresenter", this, mSlideView, model); 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mHandler.post(new Runnable() { 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private boolean isRotating() { 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mSmilPlayer.isPausedState() 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project || mSmilPlayer.isPlayingState() 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project || mSmilPlayer.isPlayedState(); 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer = SmilPlayer.getPlayer(); 188257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor if (mSlideCount > 1) { 189257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor // Only show the slideshow controller if we have more than a single slide. 190257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor // Otherwise, when we play a sound on a single slide, it appears like 191257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor // the slide controller should control the sound (seeking, ff'ing, etc). 192257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor initMediaController(); 193257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor mSlideView.setMediaController(mMediaController); 194257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor } 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Use SmilHelper.getDocument() to ensure rebuilding the 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // entire SMIL document. 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilDoc = SmilHelper.getDocument(model); 198d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (isMMSConformance(mSmilDoc)) { 199d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int imageLeft = 0; 200d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int imageTop = 0; 201d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int textLeft = 0; 202d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao int textTop = 0; 203d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao LayoutModel layout = model.getLayout(); 204d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (layout != null) { 205d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao RegionModel imageRegion = layout.getImageRegion(); 206d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (imageRegion != null) { 207d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao imageLeft = imageRegion.getLeft(); 208d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao imageTop = imageRegion.getTop(); 209d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 210d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao RegionModel textRegion = layout.getTextRegion(); 211d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao if (textRegion != null) { 212d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao textLeft = textRegion.getLeft(); 213d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao textTop = textRegion.getTop(); 214d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 215d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 216d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mSlideView.enableMMSConformanceMode(textLeft, textTop, imageLeft, imageTop); 217d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao } 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (DEBUG) { 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ByteArrayOutputStream ostream = new ByteArrayOutputStream(); 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmilXmlSerializer.serialize(mSmilDoc, ostream); 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, ostream.toString()); 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Add event listener. 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ((EventTarget) mSmilDoc).addEventListener( 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT, 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SlideshowActivity.this, false); 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer.init(mSmilDoc); 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isRotating()) { 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer.reload(); 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer.play(); 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 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 private void initMediaController() { 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaController = new MediaController(SlideshowActivity.this, false); 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaController.setMediaPlayer(new SmilPlayerController(mSmilPlayer)); 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaController.setAnchorView(findViewById(R.id.slide_view)); 245d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao mMediaController.setPrevNextListeners( 246d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao new OnClickListener() { 247b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev public void onClick(View v) { 248b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev mSmilPlayer.next(); 249b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev } 250d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao }, 251d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao new OnClickListener() { 252b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev public void onClick(View v) { 253b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev mSmilPlayer.prev(); 254b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev } 255d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao }); 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((mSmilPlayer != null) && (mMediaController != null)) { 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaController.show(); 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onPause() { 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onPause(); 26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mSmilDoc != null) { 27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ((EventTarget) mSmilDoc).removeEventListener( 27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT, this, false); 272a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor } 273a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor if (mSmilPlayer != null) { 274a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor mSmilPlayer.pause(); 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onStop() { 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onStop(); 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((null != mSmilPlayer)) { 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isFinishing()) { 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer.stop(); 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSmilPlayer.stopWhenReload(); 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 287ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor if (mMediaController != null) { 288612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor // Must set the seek bar change listener null, otherwise if we rotate it 289612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor // while tapping progress bar continuously, window will leak. 290612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor View seekBar = mMediaController 291828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon .findViewById(com.android.internal.R.id.mediacontroller_progress); 292612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor if (seekBar instanceof SeekBar) { 293612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor ((SeekBar)seekBar).setOnSeekBarChangeListener(null); 294612ec565b9b76446bd3af6c074f7180d97fa9d7cTom Taylor } 295ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor // Must do this so we don't leak a window. 296ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor mMediaController.hide(); 297ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor } 29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 302828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon protected void onDestroy() { 303828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon if (mSlideView != null) { 304828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon mSlideView.setMediaController(null); 305828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon } 306828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon super.onDestroy(); 307828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon } 308828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon 309828f0d230982a0bddb4ad1e67150ccac08c1bb58Frederic Predon @Override 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (keyCode) { 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_VOLUME_DOWN: 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_VOLUME_UP: 31460cbbe405bffddf13ed723b6d2181d7b93e71fe1Jeff Brown case KeyEvent.KEYCODE_VOLUME_MUTE: 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 320bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B case KeyEvent.KEYCODE_BACK: 321bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B case KeyEvent.KEYCODE_MENU: 322bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B if ((mSmilPlayer != null) && 323bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B (mSmilPlayer.isPausedState() 324bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B || mSmilPlayer.isPlayingState() 325bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B || mSmilPlayer.isPlayedState())) { 326bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B mSmilPlayer.stop(); 327bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B } 328bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B break; 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((mSmilPlayer != null) && (mMediaController != null)) { 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMediaController.show(); 33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return super.onKeyDown(keyCode, event); 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private class SmilPlayerController implements MediaPlayerControl { 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final SmilPlayer mPlayer; 339626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev /** 340626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * We need to cache the playback state because when the MediaController issues a play or 341626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * pause command, it expects subsequent calls to {@link #isPlaying()} to return the right 342626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * value immediately. However, the SmilPlayer executes play and pause asynchronously, so 343626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * {@link #isPlaying()} will return the wrong value for some time. That's why we keep our 344626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * own version of the state of whether the player is playing. 345626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * 346626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev * Initialized to true because we always programatically start the SmilPlayer upon creation 347626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev */ 348626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev private boolean mCachedIsPlaying = true; 34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public SmilPlayerController(SmilPlayer player) { 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mPlayer = player; 35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int getBufferPercentage() { 35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // We don't need to buffer data, always return 100%. 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return 100; 35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int getCurrentPosition() { 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mPlayer.getCurrentPosition(); 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public int getDuration() { 36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mPlayer.getDuration(); 36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean isPlaying() { 368626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev return mCachedIsPlaying; 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void pause() { 372626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev mPlayer.pause(); 373626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev mCachedIsPlaying = false; 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void seekTo(int pos) { 37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Don't need to support. 37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void start() { 381626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev mPlayer.start(); 382626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev mCachedIsPlaying = true; 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 384020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen 385020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen public boolean canPause() { 386020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen return true; 387020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen } 388020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen 389020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen public boolean canSeekBackward() { 390020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen return true; 391020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen } 392020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen 393020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen public boolean canSeekForward() { 394020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen return true; 395020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen } 3963c2ce64729072ac1ce0fe77757a1971209b01fddMarco Nelissen 3973c2ce64729072ac1ce0fe77757a1971209b01fddMarco Nelissen @Override 3983c2ce64729072ac1ce0fe77757a1971209b01fddMarco Nelissen public int getAudioSessionId() { 3993c2ce64729072ac1ce0fe77757a1971209b01fddMarco Nelissen return 0; 4003c2ce64729072ac1ce0fe77757a1971209b01fddMarco Nelissen } 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleEvent(Event evt) { 40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final Event event = evt; 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mHandler.post(new Runnable() { 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String type = event.getType(); 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if(type.equals(SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT)) { 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project finish(); 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }); 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 415