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;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
46d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R;
47d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.AttrImpl;
48d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.SmilDocumentImpl;
49d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.SmilPlayer;
50d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.dom.smil.parser.SmilXmlSerializer;
51d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.LayoutModel;
52d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.RegionModel;
53d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SlideshowModel;
54d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.model.SmilHelper;
55d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.MmsException;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Plays the given slideshow in full-screen mode with a common controller.
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SlideshowActivity extends Activity implements EventListener {
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final String TAG = "SlideshowActivity";
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean DEBUG = false;
63150c4179995cc0a75f934ef194372f9295957ca2Joe Onorato    private static final boolean LOCAL_LOGV = false;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private MediaController mMediaController;
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SmilPlayer mSmilPlayer;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private Handler mHandler;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private SMILDocument mSmilDoc;
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao    private SlideView mSlideView;
73257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor    private int mSlideCount;
74d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao
75d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao    /**
76d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao     * @return whether the Smil has MMS conformance layout.
77d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao     * Refer to MMS Conformance Document OMA-MMS-CONF-v1_2-20050301-A
78d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao     */
79d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao    private static final boolean isMMSConformance(SMILDocument smilDoc) {
80d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        SMILElement head = smilDoc.getHead();
81d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        if (head == null) {
82d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            // No 'head' element
83d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            return false;
84d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
85d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        NodeList children = head.getChildNodes();
86d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        if (children == null || children.getLength() != 1) {
87d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            // The 'head' element should have only one child.
88d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            return false;
89d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
90d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        Node layout = children.item(0);
91d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        if (layout == null || !"layout".equals(layout.getNodeName())) {
92d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            // The child is not layout element
93d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            return false;
94d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
95d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        NodeList layoutChildren = layout.getChildNodes();
96d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        if (layoutChildren == null) {
97d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            // The 'layout' element has no child.
98d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            return false;
99d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
100d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        int num = layoutChildren.getLength();
101d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        if (num <= 0) {
102d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            // The 'layout' element has no child.
103d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            return false;
104d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
105d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        for (int i = 0; i < num; i++) {
106d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            Node layoutChild = layoutChildren.item(i);
107d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            if (layoutChild == null) {
108d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                // The 'layout' child is null.
109d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                return false;
110d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            }
111d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            String name = layoutChild.getNodeName();
112d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            if ("root-layout".equals(name)) {
113d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                continue;
114d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            } else if ("region".equals(name)) {
115d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                NamedNodeMap map = layoutChild.getAttributes();
116d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                for (int j = 0; j < map.getLength(); j++) {
117d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    Node node = map.item(j);
118d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    if (node == null) {
119d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        return false;
120d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    }
121d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    String attrName = node.getNodeName();
122d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    // The attr should be one of left, top, height, width, fit and id
123d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    if ("left".equals(attrName) || "top".equals(attrName) ||
124d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            "height".equals(attrName) || "width".equals(attrName) ||
125d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            "fit".equals(attrName)) {
126d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        continue;
127d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    } else if ("id".equals(attrName)) {
128d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        String value;
129d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        if (node instanceof AttrImpl) {
130d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            value = ((AttrImpl)node).getValue();
131d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        } else {
132d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            return false;
133d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        }
134d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        if ("Text".equals(value) || "Image".equals(value)) {
135d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            continue;
136d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        } else {
137d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            // The id attr is not 'Text' or 'Image'
138d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            return false;
139d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        }
140d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    } else {
141d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        return false;
142d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    }
143d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                }
144d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            } else {
145d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                // The 'layout' element has the child other than 'root-layout' or 'region'
146d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                return false;
147d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            }
148d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        }
149d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        return true;
150d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao    }
151d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onCreate(Bundle icicle) {
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onCreate(icicle);
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mHandler = new Handler();
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Play slide-show in full-screen mode.
15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        requestWindowFeature(Window.FEATURE_NO_TITLE);
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        getWindow().setFormat(PixelFormat.TRANSLUCENT);
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        setContentView(R.layout.slideshow);
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Intent intent = getIntent();
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri msg = intent.getData();
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final SlideshowModel model;
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            model = SlideshowModel.createFromMessageUri(this, msg);
168257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor            mSlideCount = model.size();
16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (MmsException e) {
17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Cannot present the slide show.", e);
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            finish();
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
175d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        mSlideView = (SlideView) findViewById(R.id.slide_view);
176d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        PresenterFactory.getPresenter("SlideshowPresenter", this, mSlideView, model);
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mHandler.post(new Runnable() {
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            private boolean isRotating() {
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return mSmilPlayer.isPausedState()
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        || mSmilPlayer.isPlayingState()
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        || mSmilPlayer.isPlayedState();
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSmilPlayer = SmilPlayer.getPlayer();
187257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                if (mSlideCount > 1) {
188257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                    // Only show the slideshow controller if we have more than a single slide.
189257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                    // Otherwise, when we play a sound on a single slide, it appears like
190257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                    // the slide controller should control the sound (seeking, ff'ing, etc).
191257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                    initMediaController();
192257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                    mSlideView.setMediaController(mMediaController);
193257690a737bec08d4dc445c92075e0ff84a66bc7Tom Taylor                }
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Use SmilHelper.getDocument() to ensure rebuilding the
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // entire SMIL document.
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSmilDoc = SmilHelper.getDocument(model);
197d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                if (isMMSConformance(mSmilDoc)) {
198d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    int imageLeft = 0;
199d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    int imageTop = 0;
200d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    int textLeft = 0;
201d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    int textTop = 0;
202d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    LayoutModel layout = model.getLayout();
203d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    if (layout != null) {
204d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        RegionModel imageRegion = layout.getImageRegion();
205d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        if (imageRegion != null) {
206d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            imageLeft = imageRegion.getLeft();
207d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            imageTop = imageRegion.getTop();
208d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        }
209d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        RegionModel textRegion = layout.getTextRegion();
210d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        if (textRegion != null) {
211d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            textLeft = textRegion.getLeft();
212d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                            textTop = textRegion.getTop();
213d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                        }
214d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    }
215d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                    mSlideView.enableMMSConformanceMode(textLeft, textTop, imageLeft, imageTop);
216d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao                }
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (DEBUG) {
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    ByteArrayOutputStream ostream = new ByteArrayOutputStream();
21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmilXmlSerializer.serialize(mSmilDoc, ostream);
22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (LOCAL_LOGV) {
22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Log.v(TAG, ostream.toString());
22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Add event listener.
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                ((EventTarget) mSmilDoc).addEventListener(
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT,
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        SlideshowActivity.this, false);
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSmilPlayer.init(mSmilDoc);
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isRotating()) {
23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mSmilPlayer.reload();
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mSmilPlayer.play();
23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
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    private void initMediaController() {
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMediaController = new MediaController(SlideshowActivity.this, false);
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMediaController.setMediaPlayer(new SmilPlayerController(mSmilPlayer));
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMediaController.setAnchorView(findViewById(R.id.slide_view));
244d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao        mMediaController.setPrevNextListeners(
245d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            new OnClickListener() {
246b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev              public void onClick(View v) {
247b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev                  mSmilPlayer.next();
248b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev              }
249d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            },
250d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            new OnClickListener() {
251b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev              public void onClick(View v) {
252b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev                  mSmilPlayer.prev();
253b764ab1119f862e033d8b616d9f87ce9a87a87e5Todor Kalaydjiev              }
254d7a1ec4c8a007f707cc3115ed6e558f839f875eaBai Tao            });
25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onTouchEvent(MotionEvent ev) {
25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((mSmilPlayer != null) && (mMediaController != null)) {
26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mMediaController.show();
26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onPause() {
26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onPause();
26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mSmilDoc != null) {
26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ((EventTarget) mSmilDoc).removeEventListener(
27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT, this, false);
271a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor        }
272a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor        if (mSmilPlayer != null) {
273a713f75b8d9f7158d7d89e5f7f7f024db3a0ab13Tom Taylor            mSmilPlayer.pause();
27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onStop() {
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onStop();
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((null != mSmilPlayer)) {
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (isFinishing()) {
28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSmilPlayer.stop();
28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSmilPlayer.stopWhenReload();
28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
286ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor            if (mMediaController != null) {
287ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor                // Must do this so we don't leak a window.
288ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor                mMediaController.hide();
289ff408aa9dd640912cf94ae37739d76722b1d2806Tom Taylor            }
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch (keyCode) {
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_VOLUME_DOWN:
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_VOLUME_UP:
29860cbbe405bffddf13ed723b6d2181d7b93e71fe1Jeff Brown            case KeyEvent.KEYCODE_VOLUME_MUTE:
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DPAD_UP:
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DPAD_DOWN:
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DPAD_LEFT:
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DPAD_RIGHT:
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
304bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B            case KeyEvent.KEYCODE_BACK:
305bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B            case KeyEvent.KEYCODE_MENU:
306bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                if ((mSmilPlayer != null) &&
307bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                        (mSmilPlayer.isPausedState()
308bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                        || mSmilPlayer.isPlayingState()
309bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                        || mSmilPlayer.isPlayedState())) {
310bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                    mSmilPlayer.stop();
311bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                }
312bdf926782d291baf6f6b96dd71ad883deb77582fMadhav B                break;
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if ((mSmilPlayer != null) && (mMediaController != null)) {
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mMediaController.show();
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return super.onKeyDown(keyCode, event);
31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private class SmilPlayerController implements MediaPlayerControl {
32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        private final SmilPlayer mPlayer;
323626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev        /**
324626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * We need to cache the playback state because when the MediaController issues a play or
325626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * pause command, it expects subsequent calls to {@link #isPlaying()} to return the right
326626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * value immediately. However, the SmilPlayer executes play and pause asynchronously, so
327626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * {@link #isPlaying()} will return the wrong value for some time. That's why we keep our
328626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * own version of the state of whether the player is playing.
329626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         *
330626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         * Initialized to true because we always programatically start the SmilPlayer upon creation
331626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev         */
332626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev        private boolean mCachedIsPlaying = true;
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public SmilPlayerController(SmilPlayer player) {
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPlayer = player;
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public int getBufferPercentage() {
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // We don't need to buffer data, always return 100%.
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return 100;
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public int getCurrentPosition() {
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return mPlayer.getCurrentPosition();
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public int getDuration() {
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return mPlayer.getDuration();
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public boolean isPlaying() {
352626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev            return mCachedIsPlaying;
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void pause() {
356626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev            mPlayer.pause();
357626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev            mCachedIsPlaying = false;
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void seekTo(int pos) {
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Don't need to support.
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void start() {
365626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev            mPlayer.start();
366626772e1cf5dc119e127b6519c8143b6691aab4eTodor Kalaydjiev            mCachedIsPlaying = true;
36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
368020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen
369020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        public boolean canPause() {
370020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen            return true;
371020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        }
372020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen
373020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        public boolean canSeekBackward() {
374020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen            return true;
375020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        }
376020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen
377020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        public boolean canSeekForward() {
378020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen            return true;
379020411c42adb2b7968872d43f5594535aa3acaf4Marco Nelissen        }
38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void handleEvent(Event evt) {
38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final Event event = evt;
38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mHandler.post(new Runnable() {
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void run() {
38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String type = event.getType();
38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if(type.equals(SmilDocumentImpl.SMIL_DOCUMENT_END_EVENT)) {
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    finish();
38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        });
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
394