mirror of
https://github.com/oxen-io/session-android.git
synced 2023-12-14 02:53:01 +01:00
parent
b355991b0b
commit
7441c191a7
32 changed files with 3878 additions and 41 deletions
|
@ -19,6 +19,9 @@ repositories {
|
|||
maven {
|
||||
url "https://raw.github.com/whispersystems/maven/master/gson/releases/"
|
||||
}
|
||||
maven {
|
||||
url "https://raw.github.com/whispersystems/maven/master/smil/releases/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -27,6 +30,7 @@ dependencies {
|
|||
compile 'se.emilsjolander:stickylistheaders:2.2.0'
|
||||
compile 'com.google.android.gms:play-services:5.0.89'
|
||||
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
|
||||
compile 'org.w3c:smil:1.0.0'
|
||||
|
||||
androidTestCompile 'com.squareup:fest-android:1.0.8'
|
||||
|
||||
|
@ -40,6 +44,7 @@ dependencyVerification {
|
|||
'se.emilsjolander:stickylistheaders:89146b46c96fea0e40200474a2625cda10fe94891e4128f53cdb42375091b9b6',
|
||||
'com.google.android.gms:play-services:38f326e525830f1d70f60f594ceafcbdf5b312287ddbecd338fd1ed7958a4b1e',
|
||||
'com.astuetz:pagerslidingtabstrip:f1641396732c7132a7abb837e482e5ee2b0ebb8d10813fc52bbaec2c15c184c2',
|
||||
'org.w3c:smil:085dc40f2bb249651578bfa07499fd08b16ad0886dbe2c4078586a408da62f9b',
|
||||
'com.google.protobuf:protobuf-java:ad9769a22989e688a46af4d3accc348cc501ced22118033230542bc916e33f0b',
|
||||
'com.madgag:sc-light-jdk15on:931f39d351429fb96c2f749e7ecb1a256a8ebbf5edca7995c9cc085b94d1841d',
|
||||
'com.googlecode.libphonenumber:libphonenumber:eba17eae81dd622ea89a00a3a8c025b2f25d342e0d9644c5b62e16f15687c3ab',
|
||||
|
|
108
src/org/thoughtcrime/securesms/dom/AttrImpl.java
Normal file
108
src/org/thoughtcrime/securesms/dom/AttrImpl.java
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.TypeInfo;
|
||||
|
||||
public class AttrImpl extends NodeImpl implements Attr {
|
||||
private String mName;
|
||||
private String mValue;
|
||||
|
||||
/*
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
protected AttrImpl(DocumentImpl owner, String name) {
|
||||
super(owner);
|
||||
mName = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attr Interface Methods
|
||||
*/
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public Element getOwnerElement() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getSpecified() {
|
||||
return mValue != null;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
// Instead of setting a <code>Text></code> with the content of the
|
||||
// String value as defined in the specs, we directly set here the
|
||||
// internal mValue member.
|
||||
public void setValue(String value) throws DOMException {
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Interface Methods
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getNodeType() {
|
||||
return Node.ATTRIBUTE_NODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getParentNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getPreviousSibling() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getNextSibling() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNodeValue(String nodeValue) throws DOMException {
|
||||
setValue(nodeValue);
|
||||
}
|
||||
|
||||
public TypeInfo getSchemaTypeInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return false;
|
||||
}
|
||||
}
|
194
src/org/thoughtcrime/securesms/dom/DocumentImpl.java
Normal file
194
src/org/thoughtcrime/securesms/dom/DocumentImpl.java
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.CDATASection;
|
||||
import org.w3c.dom.Comment;
|
||||
import org.w3c.dom.DOMConfiguration;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.DOMImplementation;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.DocumentFragment;
|
||||
import org.w3c.dom.DocumentType;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.EntityReference;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.ProcessingInstruction;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
public abstract class DocumentImpl extends NodeImpl implements Document {
|
||||
|
||||
/*
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
public DocumentImpl() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Document Interface Methods
|
||||
*/
|
||||
|
||||
public Attr createAttribute(String name) throws DOMException {
|
||||
return new AttrImpl(this, name);
|
||||
}
|
||||
|
||||
public Attr createAttributeNS(String namespaceURI, String qualifiedName)
|
||||
throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public CDATASection createCDATASection(String data) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Comment createComment(String data) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public DocumentFragment createDocumentFragment() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract Element createElement(String tagName) throws DOMException;
|
||||
|
||||
public Element createElementNS(String namespaceURI, String qualifiedName)
|
||||
throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public EntityReference createEntityReference(String name) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProcessingInstruction createProcessingInstruction(String target, String data)
|
||||
throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Text createTextNode(String data) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public DocumentType getDoctype() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract Element getDocumentElement();
|
||||
|
||||
public Element getElementById(String elementId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public NodeList getElementsByTagName(String tagname) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public DOMImplementation getImplementation() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node importNode(Node importedNode, boolean deep) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Interface methods
|
||||
*/
|
||||
|
||||
@Override
|
||||
public short getNodeType() {
|
||||
return Node.DOCUMENT_NODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
// The value of nodeName is "#document" when Node is a Document
|
||||
return "#document";
|
||||
}
|
||||
|
||||
public String getInputEncoding() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getXmlEncoding() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getXmlStandalone() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setXmlStandalone(boolean xmlStandalone) throws DOMException {}
|
||||
|
||||
public String getXmlVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setXmlVersion(String xmlVersion) throws DOMException {}
|
||||
|
||||
public boolean getStrictErrorChecking() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setStrictErrorChecking(boolean strictErrorChecking) {}
|
||||
|
||||
public String getDocumentURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDocumentURI(String documentURI) {}
|
||||
|
||||
public Node adoptNode(Node source) throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public DOMConfiguration getDomConfig() {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public void normalizeDocument() {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public Node renameNode(Node n, String namespaceURI, String qualifiedName)
|
||||
throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
}
|
172
src/org/thoughtcrime/securesms/dom/ElementImpl.java
Normal file
172
src/org/thoughtcrime/securesms/dom/ElementImpl.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.TypeInfo;
|
||||
|
||||
public class ElementImpl extends NodeImpl implements Element {
|
||||
private String mTagName;
|
||||
private NamedNodeMap mAttributes = new NamedNodeMapImpl();
|
||||
|
||||
/*
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
protected ElementImpl(DocumentImpl owner, String tagName) {
|
||||
super(owner);
|
||||
mTagName = tagName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Element Interface methods
|
||||
*/
|
||||
|
||||
public String getAttribute(String name) {
|
||||
Attr attrNode = getAttributeNode(name);
|
||||
String attrValue = "";
|
||||
if (attrNode != null) {
|
||||
attrValue = attrNode.getValue();
|
||||
}
|
||||
return attrValue;
|
||||
}
|
||||
|
||||
public String getAttributeNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Attr getAttributeNode(String name) {
|
||||
return (Attr)mAttributes.getNamedItem(name);
|
||||
}
|
||||
|
||||
public Attr getAttributeNodeNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public NodeList getElementsByTagName(String name) {
|
||||
return new NodeListImpl(this, name, true);
|
||||
}
|
||||
|
||||
public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return mTagName;
|
||||
}
|
||||
|
||||
public boolean hasAttribute(String name) {
|
||||
return (getAttributeNode(name) != null);
|
||||
}
|
||||
|
||||
public boolean hasAttributeNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAttribute(String name) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void removeAttributeNS(String namespaceURI, String localName)
|
||||
throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAttribute(String name, String value) throws DOMException {
|
||||
Attr attribute = getAttributeNode(name);
|
||||
if (attribute == null) {
|
||||
attribute = mOwnerDocument.createAttribute(name);
|
||||
}
|
||||
attribute.setNodeValue(value);
|
||||
mAttributes.setNamedItem(attribute);
|
||||
}
|
||||
|
||||
public void setAttributeNS(String namespaceURI, String qualifiedName,
|
||||
String value) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public Attr setAttributeNode(Attr newAttr) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Interface methods
|
||||
*/
|
||||
|
||||
@Override
|
||||
public short getNodeType() {
|
||||
return ELEMENT_NODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNodeName() {
|
||||
// The value of nodeName is tagName when Node is an Element
|
||||
return mTagName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedNodeMap getAttributes() {
|
||||
return mAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttributes() {
|
||||
return (mAttributes.getLength() > 0);
|
||||
}
|
||||
|
||||
public TypeInfo getSchemaTypeInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setIdAttribute(String name, boolean isId) throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public void setIdAttributeNS(String namespaceURI, String localName,
|
||||
boolean isId) throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public void setIdAttributeNode(Attr idAttr, boolean isId)
|
||||
throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
}
|
87
src/org/thoughtcrime/securesms/dom/NamedNodeMapImpl.java
Normal file
87
src/org/thoughtcrime/securesms/dom/NamedNodeMapImpl.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
public class NamedNodeMapImpl implements NamedNodeMap {
|
||||
|
||||
private Vector<Node> mNodes = new Vector<Node>();
|
||||
|
||||
public int getLength() {
|
||||
return mNodes.size();
|
||||
}
|
||||
|
||||
public Node getNamedItem(String name) {
|
||||
Node node = null;
|
||||
for (int i = 0; i < mNodes.size(); i++) {
|
||||
if (name.equals(mNodes.elementAt(i).getNodeName())) {
|
||||
node = mNodes.elementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public Node getNamedItemNS(String namespaceURI, String localName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node item(int index) {
|
||||
if (index < mNodes.size()) {
|
||||
return mNodes.elementAt(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node removeNamedItem(String name) throws DOMException {
|
||||
Node node = getNamedItem(name);
|
||||
if (node == null) {
|
||||
throw new DOMException(DOMException.NOT_FOUND_ERR, "Not found");
|
||||
} else {
|
||||
mNodes.remove(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public Node removeNamedItemNS(String namespaceURI, String localName)
|
||||
throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node setNamedItem(Node arg) throws DOMException {
|
||||
Node existing = getNamedItem(arg.getNodeName());
|
||||
if (existing != null) {
|
||||
mNodes.remove(existing);
|
||||
}
|
||||
mNodes.add(arg);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public Node setNamedItemNS(Node arg) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
273
src/org/thoughtcrime/securesms/dom/NodeImpl.java
Normal file
273
src/org/thoughtcrime/securesms/dom/NodeImpl.java
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.UserDataHandler;
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.events.EventException;
|
||||
import org.w3c.dom.events.EventListener;
|
||||
import org.w3c.dom.events.EventTarget;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.events.EventTargetImpl;
|
||||
|
||||
public abstract class NodeImpl implements Node, EventTarget {
|
||||
private Node mParentNode;
|
||||
private final Vector<Node> mChildNodes = new Vector<Node>();
|
||||
DocumentImpl mOwnerDocument;
|
||||
private final EventTarget mEventTarget = new EventTargetImpl(this);
|
||||
|
||||
/*
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
protected NodeImpl(DocumentImpl owner) {
|
||||
mOwnerDocument = owner;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Interface Methods
|
||||
*/
|
||||
|
||||
public Node appendChild(Node newChild) throws DOMException {
|
||||
((NodeImpl)newChild).setParentNode(this);
|
||||
mChildNodes.remove(newChild);
|
||||
mChildNodes.add(newChild);
|
||||
return newChild;
|
||||
}
|
||||
|
||||
public Node cloneNode(boolean deep) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public NamedNodeMap getAttributes() {
|
||||
// Default. Override in Element.
|
||||
return null;
|
||||
}
|
||||
|
||||
public NodeList getChildNodes() {
|
||||
return new NodeListImpl(this, null, false);
|
||||
}
|
||||
|
||||
public Node getFirstChild() {
|
||||
Node firstChild = null;
|
||||
try {
|
||||
firstChild = mChildNodes.firstElement();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// Ignore and return null
|
||||
}
|
||||
return firstChild;
|
||||
}
|
||||
|
||||
public Node getLastChild() {
|
||||
Node lastChild = null;
|
||||
try {
|
||||
lastChild = mChildNodes.lastElement();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// Ignore and return null
|
||||
}
|
||||
return lastChild;
|
||||
}
|
||||
|
||||
public String getLocalName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getNamespaceURI() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node getNextSibling() {
|
||||
if ((mParentNode != null) && (this != mParentNode.getLastChild())) {
|
||||
Vector<Node> siblings = ((NodeImpl)mParentNode).mChildNodes;
|
||||
int indexOfThis = siblings.indexOf(this);
|
||||
return siblings.elementAt(indexOfThis + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract String getNodeName();
|
||||
|
||||
public abstract short getNodeType();
|
||||
|
||||
public String getNodeValue() throws DOMException {
|
||||
// Default behaviour. Override if required.
|
||||
return null;
|
||||
}
|
||||
|
||||
public Document getOwnerDocument() {
|
||||
return mOwnerDocument;
|
||||
}
|
||||
|
||||
public Node getParentNode() {
|
||||
return mParentNode;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node getPreviousSibling() {
|
||||
if ((mParentNode != null) && (this != mParentNode.getFirstChild())) {
|
||||
Vector<Node> siblings = ((NodeImpl)mParentNode).mChildNodes;
|
||||
int indexOfThis = siblings.indexOf(this);
|
||||
return siblings.elementAt(indexOfThis - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasAttributes() {
|
||||
// Default. Override in Element.
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasChildNodes() {
|
||||
return !(mChildNodes.isEmpty());
|
||||
}
|
||||
|
||||
public Node insertBefore(Node newChild, Node refChild) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSupported(String feature, String version) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public void normalize() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public Node removeChild(Node oldChild) throws DOMException {
|
||||
if (mChildNodes.contains(oldChild)) {
|
||||
mChildNodes.remove(oldChild);
|
||||
((NodeImpl)oldChild).setParentNode(null);
|
||||
} else {
|
||||
throw new DOMException(DOMException.NOT_FOUND_ERR, "Child does not exist");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
|
||||
if (mChildNodes.contains(oldChild)) {
|
||||
// Try to remove the new child if available
|
||||
try {
|
||||
mChildNodes.remove(newChild);
|
||||
} catch (DOMException e) {
|
||||
// Ignore exception
|
||||
}
|
||||
mChildNodes.setElementAt(newChild, mChildNodes.indexOf(oldChild));
|
||||
((NodeImpl)newChild).setParentNode(this);
|
||||
((NodeImpl)oldChild).setParentNode(null);
|
||||
} else {
|
||||
throw new DOMException(DOMException.NOT_FOUND_ERR, "Old child does not exist");
|
||||
}
|
||||
return oldChild;
|
||||
}
|
||||
|
||||
public void setNodeValue(String nodeValue) throws DOMException {
|
||||
// Default behaviour. Override if required.
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
private void setParentNode(Node parentNode) {
|
||||
mParentNode = parentNode;
|
||||
}
|
||||
|
||||
/*
|
||||
* EventTarget Interface
|
||||
*/
|
||||
|
||||
public void addEventListener(String type, EventListener listener, boolean useCapture) {
|
||||
mEventTarget.addEventListener(type, listener, useCapture);
|
||||
}
|
||||
|
||||
public void removeEventListener(String type, EventListener listener, boolean useCapture) {
|
||||
mEventTarget.removeEventListener(type, listener, useCapture);
|
||||
}
|
||||
|
||||
public boolean dispatchEvent(Event evt) throws EventException {
|
||||
return mEventTarget.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
public String getBaseURI() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public short compareDocumentPosition(Node other) throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public String getTextContent() throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public void setTextContent(String textContent) throws DOMException {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public boolean isSameNode(Node other) {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public String lookupPrefix(String namespaceURI) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isDefaultNamespace(String namespaceURI) {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public String lookupNamespaceURI(String prefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isEqualNode(Node arg) {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public Object getFeature(String feature, String version) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object setUserData(String key, Object data,
|
||||
UserDataHandler handler) {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
|
||||
}
|
||||
|
||||
public Object getUserData(String key) {
|
||||
return null;
|
||||
}
|
||||
}
|
128
src/org/thoughtcrime/securesms/dom/NodeListImpl.java
Normal file
128
src/org/thoughtcrime/securesms/dom/NodeListImpl.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class NodeListImpl implements NodeList {
|
||||
private ArrayList<Node> mSearchNodes;
|
||||
private ArrayList<Node> mStaticNodes;
|
||||
private Node mRootNode;
|
||||
private String mTagName;
|
||||
private boolean mDeepSearch;
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a NodeList by searching for all descendants or the direct
|
||||
* children of a root node with a given tag name.
|
||||
* @param rootNode The root <code>Node</code> of the search.
|
||||
* @param tagName The tag name to be searched for. If null, all descendants
|
||||
* will be returned.
|
||||
* @param deep Limit the search to the direct children of rootNode if false,
|
||||
* to all descendants otherwise.
|
||||
*/
|
||||
public NodeListImpl(Node rootNode, String tagName, boolean deepSearch) {
|
||||
mRootNode = rootNode;
|
||||
mTagName = tagName;
|
||||
mDeepSearch = deepSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a NodeList for a given static node list.
|
||||
* @param nodes The static node list.
|
||||
*/
|
||||
public NodeListImpl(ArrayList<Node> nodes) {
|
||||
mStaticNodes = nodes;
|
||||
}
|
||||
|
||||
/*
|
||||
* NodeListImpl Interface
|
||||
*/
|
||||
|
||||
public int getLength() {
|
||||
if (mStaticNodes == null) {
|
||||
fillList(mRootNode);
|
||||
return mSearchNodes.size();
|
||||
} else {
|
||||
return mStaticNodes.size();
|
||||
}
|
||||
}
|
||||
|
||||
public Node item(int index) {
|
||||
Node node = null;
|
||||
if (mStaticNodes == null) {
|
||||
fillList(mRootNode);
|
||||
try {
|
||||
node = mSearchNodes.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Do nothing and return null
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
node = mStaticNodes.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Do nothing and return null
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* A preorder traversal is done in the following order:
|
||||
* <ul>
|
||||
* <li> Visit root.
|
||||
* <li> Traverse children from left to right in preorder.
|
||||
* </ul>
|
||||
* This method fills the live node list.
|
||||
* @param The root of preorder traversal
|
||||
* @return The next match
|
||||
*/
|
||||
private void fillList(Node node) {
|
||||
// (Re)-initialize the container if this is the start of the search.
|
||||
// Visit the root of this iteration otherwise.
|
||||
if (node == mRootNode) {
|
||||
mSearchNodes = new ArrayList<Node>();
|
||||
} else {
|
||||
if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
|
||||
mSearchNodes.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
// Descend one generation...
|
||||
node = node.getFirstChild();
|
||||
|
||||
// ...and visit in preorder the children if we are in deep search
|
||||
// or directly add the children to the list otherwise.
|
||||
while (node != null) {
|
||||
if (mDeepSearch) {
|
||||
fillList(node);
|
||||
} else {
|
||||
if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
|
||||
mSearchNodes.add(node);
|
||||
}
|
||||
}
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
}
|
127
src/org/thoughtcrime/securesms/dom/events/EventImpl.java
Normal file
127
src/org/thoughtcrime/securesms/dom/events/EventImpl.java
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.events;
|
||||
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.events.EventTarget;
|
||||
|
||||
public class EventImpl implements Event {
|
||||
|
||||
// Event type informations
|
||||
private String mEventType;
|
||||
private boolean mCanBubble;
|
||||
private boolean mCancelable;
|
||||
|
||||
// Flags whether the event type information was set
|
||||
// FIXME: Can we use mEventType for this purpose?
|
||||
private boolean mInitialized;
|
||||
|
||||
// Target of this event
|
||||
private EventTarget mTarget;
|
||||
|
||||
// Event status variables
|
||||
private short mEventPhase;
|
||||
private boolean mStopPropagation;
|
||||
private boolean mPreventDefault;
|
||||
private EventTarget mCurrentTarget;
|
||||
private int mSeekTo;
|
||||
|
||||
private final long mTimeStamp = System.currentTimeMillis();
|
||||
|
||||
public boolean getBubbles() {
|
||||
return mCanBubble;
|
||||
}
|
||||
|
||||
public boolean getCancelable() {
|
||||
return mCancelable;
|
||||
}
|
||||
|
||||
public EventTarget getCurrentTarget() {
|
||||
return mCurrentTarget;
|
||||
}
|
||||
|
||||
public short getEventPhase() {
|
||||
return mEventPhase;
|
||||
}
|
||||
|
||||
public EventTarget getTarget() {
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
public long getTimeStamp() {
|
||||
return mTimeStamp;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return mEventType;
|
||||
}
|
||||
|
||||
public void initEvent(String eventTypeArg, boolean canBubbleArg,
|
||||
boolean cancelableArg) {
|
||||
mEventType = eventTypeArg;
|
||||
mCanBubble = canBubbleArg;
|
||||
mCancelable = cancelableArg;
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
public void initEvent(String eventTypeArg, boolean canBubbleArg, boolean cancelableArg,
|
||||
int seekTo) {
|
||||
mSeekTo = seekTo;
|
||||
initEvent(eventTypeArg, canBubbleArg, cancelableArg);
|
||||
}
|
||||
|
||||
public void preventDefault() {
|
||||
mPreventDefault = true;
|
||||
}
|
||||
|
||||
public void stopPropagation() {
|
||||
mStopPropagation = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
boolean isInitialized() {
|
||||
return mInitialized;
|
||||
}
|
||||
|
||||
boolean isPreventDefault() {
|
||||
return mPreventDefault;
|
||||
}
|
||||
|
||||
boolean isPropogationStopped() {
|
||||
return mStopPropagation;
|
||||
}
|
||||
|
||||
void setTarget(EventTarget target) {
|
||||
mTarget = target;
|
||||
}
|
||||
|
||||
void setEventPhase(short eventPhase) {
|
||||
mEventPhase = eventPhase;
|
||||
}
|
||||
|
||||
void setCurrentTarget(EventTarget currentTarget) {
|
||||
mCurrentTarget = currentTarget;
|
||||
}
|
||||
|
||||
public int getSeekTo() {
|
||||
return mSeekTo;
|
||||
}
|
||||
}
|
131
src/org/thoughtcrime/securesms/dom/events/EventTargetImpl.java
Normal file
131
src/org/thoughtcrime/securesms/dom/events/EventTargetImpl.java
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.events.EventException;
|
||||
import org.w3c.dom.events.EventListener;
|
||||
import org.w3c.dom.events.EventTarget;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class EventTargetImpl implements EventTarget {
|
||||
private static final String TAG = "EventTargetImpl";
|
||||
private ArrayList<EventListenerEntry> mListenerEntries;
|
||||
private EventTarget mNodeTarget;
|
||||
|
||||
static class EventListenerEntry
|
||||
{
|
||||
final String mType;
|
||||
final EventListener mListener;
|
||||
final boolean mUseCapture;
|
||||
|
||||
EventListenerEntry(String type, EventListener listener, boolean useCapture)
|
||||
{
|
||||
mType = type;
|
||||
mListener = listener;
|
||||
mUseCapture = useCapture;
|
||||
}
|
||||
}
|
||||
|
||||
public EventTargetImpl(EventTarget target) {
|
||||
mNodeTarget = target;
|
||||
}
|
||||
|
||||
public void addEventListener(String type, EventListener listener, boolean useCapture) {
|
||||
if ((type == null) || type.equals("") || (listener == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have only one entry
|
||||
removeEventListener(type, listener, useCapture);
|
||||
|
||||
if (mListenerEntries == null) {
|
||||
mListenerEntries = new ArrayList<EventListenerEntry>();
|
||||
}
|
||||
mListenerEntries.add(new EventListenerEntry(type, listener, useCapture));
|
||||
}
|
||||
|
||||
public boolean dispatchEvent(Event evt) throws EventException {
|
||||
// We need to use the internal APIs to modify and access the event status
|
||||
EventImpl eventImpl = (EventImpl)evt;
|
||||
|
||||
if (!eventImpl.isInitialized()) {
|
||||
throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR,
|
||||
"Event not initialized");
|
||||
} else if ((eventImpl.getType() == null) || eventImpl.getType().equals("")) {
|
||||
throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR,
|
||||
"Unspecified even type");
|
||||
}
|
||||
|
||||
// Initialize event status
|
||||
eventImpl.setTarget(mNodeTarget);
|
||||
|
||||
// TODO: At this point, to support event capturing and bubbling, we should
|
||||
// establish the chain of EventTargets from the top of the tree to this
|
||||
// event's target.
|
||||
|
||||
// TODO: CAPTURING_PHASE skipped
|
||||
|
||||
// Handle AT_TARGET
|
||||
// Invoke handleEvent of non-capturing listeners on this EventTarget.
|
||||
eventImpl.setEventPhase(Event.AT_TARGET);
|
||||
eventImpl.setCurrentTarget(mNodeTarget);
|
||||
if (!eventImpl.isPropogationStopped() && (mListenerEntries != null)) {
|
||||
for (int i = 0; i < mListenerEntries.size(); i++) {
|
||||
EventListenerEntry listenerEntry = mListenerEntries.get(i);
|
||||
if (!listenerEntry.mUseCapture
|
||||
&& listenerEntry.mType.equals(eventImpl.getType())) {
|
||||
try {
|
||||
listenerEntry.mListener.handleEvent(eventImpl);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Any exceptions thrown inside an EventListener will
|
||||
// not stop propagation of the event
|
||||
Log.w(TAG, "Catched EventListener exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eventImpl.getBubbles()) {
|
||||
// TODO: BUBBLING_PHASE skipped
|
||||
}
|
||||
|
||||
return eventImpl.isPreventDefault();
|
||||
}
|
||||
|
||||
public void removeEventListener(String type, EventListener listener,
|
||||
boolean useCapture) {
|
||||
if (null == mListenerEntries) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mListenerEntries.size(); i ++) {
|
||||
EventListenerEntry listenerEntry = mListenerEntries.get(i);
|
||||
if ((listenerEntry.mUseCapture == useCapture)
|
||||
&& (listenerEntry.mListener == listener)
|
||||
&& listenerEntry.mType.equals(type)) {
|
||||
mListenerEntries.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.smil.ElementParallelTimeContainer;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
import org.w3c.dom.smil.Time;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.NodeListImpl;
|
||||
|
||||
public abstract class ElementParallelTimeContainerImpl extends ElementTimeContainerImpl
|
||||
implements ElementParallelTimeContainer {
|
||||
private final static String ENDSYNC_ATTRIBUTE_NAME = "endsync";
|
||||
private final static String ENDSYNC_FIRST = "first";
|
||||
private final static String ENDSYNC_LAST = "last";
|
||||
private final static String ENDSYNC_ALL = "all";
|
||||
private final static String ENDSYNC_MEDIA = "media";
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
ElementParallelTimeContainerImpl(SMILElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
public String getEndSync() {
|
||||
String endsync = mSmilElement.getAttribute(ENDSYNC_ATTRIBUTE_NAME);
|
||||
if ((endsync == null) || (endsync.length() == 0)) {
|
||||
setEndSync(ENDSYNC_LAST);
|
||||
return ENDSYNC_LAST;
|
||||
}
|
||||
if (ENDSYNC_FIRST.equals(endsync) || ENDSYNC_LAST.equals(endsync) ||
|
||||
ENDSYNC_ALL.equals(endsync) || ENDSYNC_MEDIA.equals(endsync)) {
|
||||
return endsync;
|
||||
}
|
||||
|
||||
// FIXME add the checking for ID-Value and smil1.0-Id-value.
|
||||
|
||||
setEndSync(ENDSYNC_LAST);
|
||||
return ENDSYNC_LAST;
|
||||
}
|
||||
|
||||
public void setEndSync(String endSync) throws DOMException {
|
||||
if (ENDSYNC_FIRST.equals(endSync) || ENDSYNC_LAST.equals(endSync) ||
|
||||
ENDSYNC_ALL.equals(endSync) || ENDSYNC_MEDIA.equals(endSync)) {
|
||||
mSmilElement.setAttribute(ENDSYNC_ATTRIBUTE_NAME, endSync);
|
||||
} else { // FIXME add the support for ID-Value and smil1.0-Id-value.
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
|
||||
"Unsupported endsync value" + endSync);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDur() {
|
||||
float dur = super.getDur();
|
||||
if (dur == 0) {
|
||||
dur = getImplicitDuration();
|
||||
}
|
||||
return dur;
|
||||
}
|
||||
|
||||
public float getImplicitDuration() {
|
||||
float dur = -1.0F;
|
||||
if (ENDSYNC_LAST.equals(getEndSync())) {
|
||||
NodeList children = getTimeChildren();
|
||||
for (int i = 0; i < children.getLength(); ++i) {
|
||||
ElementTime child = (ElementTime) children.item(i);
|
||||
TimeList endTimeList = child.getEnd();
|
||||
for (int j = 0; j < endTimeList.getLength(); ++j) {
|
||||
Time endTime = endTimeList.item(j);
|
||||
if (endTime.getTimeType() == Time.SMIL_TIME_INDEFINITE) {
|
||||
// Return "indefinite" here.
|
||||
return -1.0F;
|
||||
}
|
||||
if (endTime.getResolved()) {
|
||||
float end = (float)endTime.getResolvedOffset();
|
||||
dur = (end > dur) ? end : dur;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Other endsync types are not supported now.
|
||||
|
||||
return dur;
|
||||
}
|
||||
|
||||
public NodeList getActiveChildrenAt(float instant) {
|
||||
/*
|
||||
* Find the closest Time of ElementTime before instant.
|
||||
* Add ElementTime to list of active elements if the Time belongs to the begin-list,
|
||||
* do not add it otherwise.
|
||||
*/
|
||||
ArrayList<Node> activeChildren = new ArrayList<Node>();
|
||||
NodeList children = getTimeChildren();
|
||||
int childrenLen = children.getLength();
|
||||
for (int i = 0; i < childrenLen; ++i) {
|
||||
double maxOffset = 0.0;
|
||||
boolean active = false;
|
||||
ElementTime child = (ElementTime) children.item(i);
|
||||
|
||||
TimeList beginList = child.getBegin();
|
||||
int len = beginList.getLength();
|
||||
for (int j = 0; j < len; ++j) {
|
||||
Time begin = beginList.item(j);
|
||||
if (begin.getResolved()) {
|
||||
double resolvedOffset = begin.getResolvedOffset() * 1000.0;
|
||||
if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
|
||||
maxOffset = resolvedOffset;
|
||||
active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeList endList = child.getEnd();
|
||||
len = endList.getLength();
|
||||
for (int j = 0; j < len; ++j) {
|
||||
Time end = endList.item(j);
|
||||
if (end.getResolved()) {
|
||||
double resolvedOffset = end.getResolvedOffset() * 1000.0;
|
||||
if ((resolvedOffset <= instant) && (resolvedOffset >= maxOffset)) {
|
||||
maxOffset = resolvedOffset;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active) {
|
||||
activeChildren.add((Node) child);
|
||||
}
|
||||
}
|
||||
return new NodeListImpl(activeChildren);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.smil.ElementSequentialTimeContainer;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.NodeListImpl;
|
||||
|
||||
public abstract class ElementSequentialTimeContainerImpl extends
|
||||
ElementTimeContainerImpl implements ElementSequentialTimeContainer {
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
ElementSequentialTimeContainerImpl(SMILElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
/*
|
||||
* ElementSequentialTimeContainer Interface
|
||||
*/
|
||||
|
||||
public NodeList getActiveChildrenAt(float instant) {
|
||||
NodeList allChildren = this.getTimeChildren();
|
||||
ArrayList<Node> nodes = new ArrayList<Node>();
|
||||
for (int i = 0; i < allChildren.getLength(); i++) {
|
||||
instant -= ((ElementTime) allChildren.item(i)).getDur();
|
||||
if (instant < 0) {
|
||||
nodes.add(allChildren.item(i));
|
||||
return new NodeListImpl(nodes);
|
||||
}
|
||||
}
|
||||
return new NodeListImpl(nodes);
|
||||
}
|
||||
|
||||
public float getDur() {
|
||||
float dur = super.getDur();
|
||||
if (dur == 0) {
|
||||
NodeList children = getTimeChildren();
|
||||
for (int i = 0; i < children.getLength(); ++i) {
|
||||
ElementTime child = (ElementTime) children.item(i);
|
||||
if (child.getDur() < 0) {
|
||||
// Return "indefinite" since containing a child whose duration is indefinite.
|
||||
return -1.0F;
|
||||
}
|
||||
dur += child.getDur();
|
||||
}
|
||||
}
|
||||
return dur;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.smil.ElementTimeContainer;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
|
||||
public abstract class ElementTimeContainerImpl extends ElementTimeImpl implements
|
||||
ElementTimeContainer {
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
ElementTimeContainerImpl(SMILElement element) {
|
||||
super(element);
|
||||
}
|
||||
}
|
348
src/org/thoughtcrime/securesms/dom/smil/ElementTimeImpl.java
Normal file
348
src/org/thoughtcrime/securesms/dom/smil/ElementTimeImpl.java
Normal file
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
import org.w3c.dom.smil.Time;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public abstract class ElementTimeImpl implements ElementTime {
|
||||
private static final String TAG = "ElementTimeImpl";
|
||||
|
||||
private static final String FILL_REMOVE_ATTRIBUTE = "remove";
|
||||
private static final String FILL_FREEZE_ATTRIBUTE = "freeze";
|
||||
private static final String FILL_HOLD_ATTRIBUTE = "hold";
|
||||
private static final String FILL_TRANSITION_ATTRIBUTE = "transition";
|
||||
private static final String FILL_AUTO_ATTRIBUTE = "auto";
|
||||
private static final String FILL_ATTRIBUTE_NAME = "fill";
|
||||
private static final String FILLDEFAULT_ATTRIBUTE_NAME = "fillDefault";
|
||||
|
||||
final SMILElement mSmilElement;
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
ElementTimeImpl(SMILElement element) {
|
||||
mSmilElement = element;
|
||||
}
|
||||
|
||||
// Default implementation. Override if required.
|
||||
int getBeginConstraints() {
|
||||
return TimeImpl.ALLOW_ALL;
|
||||
}
|
||||
|
||||
// Default implementation. Override if required
|
||||
int getEndConstraints() {
|
||||
return TimeImpl.ALLOW_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the parent node on the ElementTime tree. It is in opposition to getTimeChildren.
|
||||
* @return the parent ElementTime. Returns <code>null</code> if there is no parent.
|
||||
*/
|
||||
abstract ElementTime getParentElementTime();
|
||||
|
||||
/*
|
||||
* ElementTime Interface
|
||||
*/
|
||||
|
||||
public TimeList getBegin() {
|
||||
String[] beginTimeStringList = mSmilElement.getAttribute("begin").split(";");
|
||||
|
||||
// TODO: Check other constraints on parsed values, e.g., "single, non-negative offset values
|
||||
ArrayList<Time> beginTimeList = new ArrayList<Time>();
|
||||
// Initialize Time instances and add them to Vector
|
||||
for (int i = 0; i < beginTimeStringList.length; i++) {
|
||||
try {
|
||||
beginTimeList.add(new TimeImpl(beginTimeStringList[i], getBeginConstraints()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Ignore badly formatted times
|
||||
}
|
||||
}
|
||||
if (beginTimeList.size() == 0) {
|
||||
/*
|
||||
* What is the right default value?
|
||||
*
|
||||
* In MMS SMIL, this method may be called either on an instance of:
|
||||
*
|
||||
* 1 - ElementSequentialTimeContainer (The SMILDocument)
|
||||
* 2 - ElementParallelTimeContainer (A Time-Child of the SMILDocument, which is a seq)
|
||||
* 3 - ElementTime (A SMILMediaElement).
|
||||
*
|
||||
* 1 - In the first case, the default start time is obviously 0.
|
||||
* 2 - In the second case, the specifications mentions that
|
||||
* "For children of a sequence, the only legal value for begin is
|
||||
* a (single) non-negative offset value. The default begin value is 0."
|
||||
* 3 - In the third case, the specification mentions that
|
||||
* "The default value of begin for children of a par is 0."
|
||||
*
|
||||
* In short, if no value is specified, the default is always 0.
|
||||
*/
|
||||
|
||||
beginTimeList.add(new TimeImpl("0", TimeImpl.ALLOW_ALL));
|
||||
}
|
||||
return new TimeListImpl(beginTimeList);
|
||||
}
|
||||
|
||||
public float getDur() {
|
||||
float dur = 0;
|
||||
try {
|
||||
String durString = mSmilElement.getAttribute("dur");
|
||||
if (durString != null) {
|
||||
dur = TimeImpl.parseClockValue(durString) / 1000f;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Do nothing and return the minimum value
|
||||
}
|
||||
|
||||
return dur;
|
||||
}
|
||||
|
||||
public TimeList getEnd() {
|
||||
ArrayList<Time> endTimeList = new ArrayList<Time>();
|
||||
|
||||
String[] endTimeStringList = mSmilElement.getAttribute("end").split(";");
|
||||
int len = endTimeStringList.length;
|
||||
if (!((len == 1) && (endTimeStringList[0].length() == 0))) { // Ensure the end field is set.
|
||||
// Initialize Time instances and add them to Vector
|
||||
for (int i = 0; i < len; i++) {
|
||||
try {
|
||||
endTimeList.add(new TimeImpl(endTimeStringList[i],
|
||||
getEndConstraints()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Ignore badly formatted times
|
||||
Log.e(TAG, "Malformed time value.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "end" time is not specified
|
||||
if (endTimeList.size() == 0) {
|
||||
// Get duration
|
||||
float duration = getDur();
|
||||
|
||||
if (duration < 0) {
|
||||
endTimeList.add(new TimeImpl("indefinite", getEndConstraints()));
|
||||
} else {
|
||||
// Get begin
|
||||
TimeList begin = getBegin();
|
||||
for (int i = 0; i < begin.getLength(); i++) {
|
||||
endTimeList.add(new TimeImpl(
|
||||
// end = begin + dur
|
||||
begin.item(i).getResolvedOffset() + duration + "s",
|
||||
getEndConstraints()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new TimeListImpl(endTimeList);
|
||||
}
|
||||
|
||||
private boolean beginAndEndAreZero() {
|
||||
TimeList begin = getBegin();
|
||||
TimeList end = getEnd();
|
||||
if (begin.getLength() == 1 && end.getLength() == 1) {
|
||||
Time beginTime = begin.item(0);
|
||||
Time endTime = end.item(0);
|
||||
return beginTime.getOffset() == 0. && endTime.getOffset() == 0.;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public short getFill() {
|
||||
String fill = mSmilElement.getAttribute(FILL_ATTRIBUTE_NAME);
|
||||
if (fill.equalsIgnoreCase(FILL_FREEZE_ATTRIBUTE)) {
|
||||
return FILL_FREEZE;
|
||||
} else if (fill.equalsIgnoreCase(FILL_REMOVE_ATTRIBUTE)) {
|
||||
return FILL_REMOVE;
|
||||
} else if (fill.equalsIgnoreCase(FILL_HOLD_ATTRIBUTE)) {
|
||||
// FIXME handle it as freeze for now
|
||||
return FILL_FREEZE;
|
||||
} else if (fill.equalsIgnoreCase(FILL_TRANSITION_ATTRIBUTE)) {
|
||||
// FIXME handle it as freeze for now
|
||||
return FILL_FREEZE;
|
||||
} else if (!fill.equalsIgnoreCase(FILL_AUTO_ATTRIBUTE)) {
|
||||
/*
|
||||
* fill = default
|
||||
* The fill behavior for the element is determined by the value of the fillDefault
|
||||
* attribute. This is the default value.
|
||||
*/
|
||||
short fillDefault = getFillDefault();
|
||||
if (fillDefault != FILL_AUTO) {
|
||||
return fillDefault;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fill = auto
|
||||
* The fill behavior for this element depends on whether the element specifies any of
|
||||
* the attributes that define the simple or active duration:
|
||||
* - If none of the attributes dur, end, repeatCount or repeatDur are specified on
|
||||
* the element, then the element will have a fill behavior identical to that if it were
|
||||
* specified as "freeze".
|
||||
* - Otherwise, the element will have a fill behavior identical to that if it were
|
||||
* specified as "remove".
|
||||
*/
|
||||
if (((mSmilElement.getAttribute("dur").length() == 0) &&
|
||||
(mSmilElement.getAttribute("end").length() == 0) &&
|
||||
(mSmilElement.getAttribute("repeatCount").length() == 0) &&
|
||||
(mSmilElement.getAttribute("repeatDur").length() == 0)) ||
|
||||
beginAndEndAreZero()) {
|
||||
return FILL_FREEZE;
|
||||
} else {
|
||||
return FILL_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
public short getFillDefault() {
|
||||
String fillDefault = mSmilElement.getAttribute(FILLDEFAULT_ATTRIBUTE_NAME);
|
||||
if (fillDefault.equalsIgnoreCase(FILL_REMOVE_ATTRIBUTE)) {
|
||||
return FILL_REMOVE;
|
||||
} else if (fillDefault.equalsIgnoreCase(FILL_FREEZE_ATTRIBUTE)) {
|
||||
return FILL_FREEZE;
|
||||
} else if (fillDefault.equalsIgnoreCase(FILL_AUTO_ATTRIBUTE)) {
|
||||
return FILL_AUTO;
|
||||
} else if (fillDefault.equalsIgnoreCase(FILL_HOLD_ATTRIBUTE)) {
|
||||
// FIXME handle it as freeze for now
|
||||
return FILL_FREEZE;
|
||||
} else if (fillDefault.equalsIgnoreCase(FILL_TRANSITION_ATTRIBUTE)) {
|
||||
// FIXME handle it as freeze for now
|
||||
return FILL_FREEZE;
|
||||
} else {
|
||||
/*
|
||||
* fillDefault = inherit
|
||||
* Specifies that the value of this attribute (and of the fill behavior) are
|
||||
* inherited from the fillDefault value of the parent element.
|
||||
* This is the default value.
|
||||
*/
|
||||
ElementTime parent = getParentElementTime();
|
||||
if (parent == null) {
|
||||
/*
|
||||
* fillDefault = auto
|
||||
* If there is no parent element, the value is "auto".
|
||||
*/
|
||||
return FILL_AUTO;
|
||||
} else {
|
||||
return ((ElementTimeImpl) parent).getFillDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getRepeatCount() {
|
||||
String repeatCount = mSmilElement.getAttribute("repeatCount");
|
||||
try {
|
||||
float value = Float.parseFloat(repeatCount);
|
||||
if (value > 0) {
|
||||
return value;
|
||||
} else {
|
||||
return 0; // default
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return 0; // default
|
||||
}
|
||||
}
|
||||
|
||||
public float getRepeatDur() {
|
||||
try {
|
||||
float repeatDur =
|
||||
TimeImpl.parseClockValue(mSmilElement.getAttribute("repeatDur"));
|
||||
if (repeatDur > 0) {
|
||||
return repeatDur;
|
||||
} else {
|
||||
return 0; // default
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
return 0; // default
|
||||
}
|
||||
}
|
||||
|
||||
public short getRestart() {
|
||||
String restart = mSmilElement.getAttribute("restart");
|
||||
if (restart.equalsIgnoreCase("never")) {
|
||||
return RESTART_NEVER;
|
||||
} else if (restart.equalsIgnoreCase("whenNotActive")) {
|
||||
return RESTART_WHEN_NOT_ACTIVE;
|
||||
} else {
|
||||
return RESTART_ALWAYS; // default
|
||||
}
|
||||
}
|
||||
|
||||
public void setBegin(TimeList begin) throws DOMException {
|
||||
// TODO Implement this
|
||||
mSmilElement.setAttribute("begin", "indefinite");
|
||||
}
|
||||
|
||||
public void setDur(float dur) throws DOMException {
|
||||
// In SMIL 3.0, the dur could be a timecount-value which may contain fractions.
|
||||
// However, in MMS 1.3, the dur SHALL be expressed in integer milliseconds.
|
||||
mSmilElement.setAttribute("dur", Integer.toString((int)(dur * 1000)) + "ms");
|
||||
}
|
||||
|
||||
public void setEnd(TimeList end) throws DOMException {
|
||||
// TODO Implement this
|
||||
mSmilElement.setAttribute("end", "indefinite");
|
||||
}
|
||||
|
||||
public void setFill(short fill) throws DOMException {
|
||||
if (fill == FILL_FREEZE) {
|
||||
mSmilElement.setAttribute(FILL_ATTRIBUTE_NAME, FILL_FREEZE_ATTRIBUTE);
|
||||
} else {
|
||||
mSmilElement.setAttribute(FILL_ATTRIBUTE_NAME, FILL_REMOVE_ATTRIBUTE); // default
|
||||
}
|
||||
}
|
||||
|
||||
public void setFillDefault(short fillDefault) throws DOMException {
|
||||
if (fillDefault == FILL_FREEZE) {
|
||||
mSmilElement.setAttribute(FILLDEFAULT_ATTRIBUTE_NAME, FILL_FREEZE_ATTRIBUTE);
|
||||
} else {
|
||||
mSmilElement.setAttribute(FILLDEFAULT_ATTRIBUTE_NAME, FILL_REMOVE_ATTRIBUTE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRepeatCount(float repeatCount) throws DOMException {
|
||||
String repeatCountString = "indefinite";
|
||||
if (repeatCount > 0) {
|
||||
repeatCountString = Float.toString(repeatCount);
|
||||
}
|
||||
mSmilElement.setAttribute("repeatCount", repeatCountString);
|
||||
}
|
||||
|
||||
public void setRepeatDur(float repeatDur) throws DOMException {
|
||||
String repeatDurString = "indefinite";
|
||||
if (repeatDur > 0) {
|
||||
repeatDurString = Float.toString(repeatDur) + "ms";
|
||||
}
|
||||
mSmilElement.setAttribute("repeatDur", repeatDurString);
|
||||
}
|
||||
|
||||
public void setRestart(short restart) throws DOMException {
|
||||
if (restart == RESTART_NEVER) {
|
||||
mSmilElement.setAttribute("restart", "never");
|
||||
} else if (restart == RESTART_WHEN_NOT_ACTIVE) {
|
||||
mSmilElement.setAttribute("restart", "whenNotActive");
|
||||
} else {
|
||||
mSmilElement.setAttribute("restart", "always");
|
||||
}
|
||||
}
|
||||
}
|
291
src/org/thoughtcrime/securesms/dom/smil/SmilDocumentImpl.java
Normal file
291
src/org/thoughtcrime/securesms/dom/smil/SmilDocumentImpl.java
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.events.DocumentEvent;
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.smil.ElementSequentialTimeContainer;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
import org.w3c.dom.smil.SMILLayoutElement;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.DocumentImpl;
|
||||
import org.thoughtcrime.securesms.dom.events.EventImpl;
|
||||
|
||||
public class SmilDocumentImpl extends DocumentImpl implements SMILDocument, DocumentEvent {
|
||||
/*
|
||||
* The sequential time container cannot be initialized here because the real container
|
||||
* is body, which hasn't been created yet. It will be initialized when the body has
|
||||
* already been created. Please see getBody().
|
||||
*/
|
||||
ElementSequentialTimeContainer mSeqTimeContainer;
|
||||
|
||||
public final static String SMIL_DOCUMENT_START_EVENT = "SmilDocumentStart";
|
||||
public final static String SMIL_DOCUMENT_END_EVENT = "SimlDocumentEnd";
|
||||
|
||||
/*
|
||||
* Internal methods
|
||||
*/
|
||||
public SmilDocumentImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* ElementSequentialTimeContainer stuff
|
||||
*/
|
||||
|
||||
public NodeList getActiveChildrenAt(float instant) {
|
||||
return mSeqTimeContainer.getActiveChildrenAt(instant);
|
||||
}
|
||||
|
||||
public NodeList getTimeChildren() {
|
||||
return mSeqTimeContainer.getTimeChildren();
|
||||
}
|
||||
|
||||
public boolean beginElement() {
|
||||
return mSeqTimeContainer.beginElement();
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
return mSeqTimeContainer.endElement();
|
||||
}
|
||||
|
||||
public TimeList getBegin() {
|
||||
return mSeqTimeContainer.getBegin();
|
||||
}
|
||||
|
||||
public float getDur() {
|
||||
return mSeqTimeContainer.getDur();
|
||||
}
|
||||
|
||||
public TimeList getEnd() {
|
||||
return mSeqTimeContainer.getEnd();
|
||||
}
|
||||
|
||||
public short getFill() {
|
||||
return mSeqTimeContainer.getFill();
|
||||
}
|
||||
|
||||
public short getFillDefault() {
|
||||
return mSeqTimeContainer.getFillDefault();
|
||||
}
|
||||
|
||||
public float getRepeatCount() {
|
||||
return mSeqTimeContainer.getRepeatCount();
|
||||
}
|
||||
|
||||
public float getRepeatDur() {
|
||||
return mSeqTimeContainer.getRepeatDur();
|
||||
}
|
||||
|
||||
public short getRestart() {
|
||||
return mSeqTimeContainer.getRestart();
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
mSeqTimeContainer.pauseElement();
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
mSeqTimeContainer.resumeElement();
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
mSeqTimeContainer.seekElement(seekTo);
|
||||
}
|
||||
|
||||
public void setBegin(TimeList begin) throws DOMException {
|
||||
mSeqTimeContainer.setBegin(begin);
|
||||
}
|
||||
|
||||
public void setDur(float dur) throws DOMException {
|
||||
mSeqTimeContainer.setDur(dur);
|
||||
}
|
||||
|
||||
public void setEnd(TimeList end) throws DOMException {
|
||||
mSeqTimeContainer.setEnd(end);
|
||||
}
|
||||
|
||||
public void setFill(short fill) throws DOMException {
|
||||
mSeqTimeContainer.setFill(fill);
|
||||
}
|
||||
|
||||
public void setFillDefault(short fillDefault) throws DOMException {
|
||||
mSeqTimeContainer.setFillDefault(fillDefault);
|
||||
}
|
||||
|
||||
public void setRepeatCount(float repeatCount) throws DOMException {
|
||||
mSeqTimeContainer.setRepeatCount(repeatCount);
|
||||
}
|
||||
|
||||
public void setRepeatDur(float repeatDur) throws DOMException {
|
||||
mSeqTimeContainer.setRepeatDur(repeatDur);
|
||||
}
|
||||
|
||||
public void setRestart(short restart) throws DOMException {
|
||||
mSeqTimeContainer.setRestart(restart);
|
||||
}
|
||||
|
||||
/*
|
||||
* Document Interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Element createElement(String tagName) throws DOMException {
|
||||
// Find the appropriate class for this element
|
||||
tagName = tagName.toLowerCase();
|
||||
if (tagName.equals("text") ||
|
||||
tagName.equals("img") ||
|
||||
tagName.equals("video")) {
|
||||
return new SmilRegionMediaElementImpl(this, tagName);
|
||||
} else if (tagName.equals("audio")) {
|
||||
return new SmilMediaElementImpl(this, tagName);
|
||||
} else if (tagName.equals("layout")) {
|
||||
return new SmilLayoutElementImpl(this, tagName);
|
||||
} else if (tagName.equals("root-layout")) {
|
||||
return new SmilRootLayoutElementImpl(this, tagName);
|
||||
} else if (tagName.equals("region")) {
|
||||
return new SmilRegionElementImpl(this, tagName);
|
||||
} else if (tagName.equals("ref")) {
|
||||
return new SmilRefElementImpl(this, tagName);
|
||||
} else if (tagName.equals("par")) {
|
||||
return new SmilParElementImpl(this, tagName);
|
||||
} else {
|
||||
// This includes also the structural nodes SMIL,
|
||||
// HEAD, BODY, for which no specific types are defined.
|
||||
return new SmilElementImpl(this, tagName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMILElement getDocumentElement() {
|
||||
Node rootElement = getFirstChild();
|
||||
if (rootElement == null || !(rootElement instanceof SMILElement)) {
|
||||
// The root doesn't exist. Create a new one.
|
||||
rootElement = createElement("smil");
|
||||
appendChild(rootElement);
|
||||
}
|
||||
|
||||
return (SMILElement) rootElement;
|
||||
}
|
||||
|
||||
/*
|
||||
* SMILElement Interface
|
||||
*/
|
||||
|
||||
public SMILElement getHead() {
|
||||
Node rootElement = getDocumentElement();
|
||||
Node headElement = rootElement.getFirstChild();
|
||||
if (headElement == null || !(headElement instanceof SMILElement)) {
|
||||
// The head doesn't exist. Create a new one.
|
||||
headElement = createElement("head");
|
||||
rootElement.appendChild(headElement);
|
||||
}
|
||||
|
||||
return (SMILElement) headElement;
|
||||
}
|
||||
|
||||
public SMILElement getBody() {
|
||||
Node rootElement = getDocumentElement();
|
||||
Node headElement = getHead();
|
||||
Node bodyElement = headElement.getNextSibling();
|
||||
if (bodyElement == null || !(bodyElement instanceof SMILElement)) {
|
||||
// The body doesn't exist. Create a new one.
|
||||
bodyElement = createElement("body");
|
||||
rootElement.appendChild(bodyElement);
|
||||
}
|
||||
|
||||
// Initialize the real sequential time container, which is body.
|
||||
mSeqTimeContainer = new ElementSequentialTimeContainerImpl((SMILElement) bodyElement) {
|
||||
public NodeList getTimeChildren() {
|
||||
return getBody().getElementsByTagName("par");
|
||||
}
|
||||
|
||||
public boolean beginElement() {
|
||||
Event startEvent = createEvent("Event");
|
||||
startEvent.initEvent(SMIL_DOCUMENT_START_EVENT, false, false);
|
||||
dispatchEvent(startEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
Event endEvent = createEvent("Event");
|
||||
endEvent.initEvent(SMIL_DOCUMENT_END_EVENT, false, false);
|
||||
dispatchEvent(endEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
ElementTime getParentElementTime() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (SMILElement) bodyElement;
|
||||
}
|
||||
|
||||
public SMILLayoutElement getLayout() {
|
||||
Node headElement = getHead();
|
||||
Node layoutElement = null;
|
||||
|
||||
// Find the layout element under <code>HEAD</code>
|
||||
layoutElement = headElement.getFirstChild();
|
||||
while ((layoutElement != null) && !(layoutElement instanceof SMILLayoutElement)) {
|
||||
layoutElement = layoutElement.getNextSibling();
|
||||
}
|
||||
|
||||
if (layoutElement == null) {
|
||||
// The layout doesn't exist. Create a default one.
|
||||
layoutElement = new SmilLayoutElementImpl(this, "layout");
|
||||
headElement.appendChild(layoutElement);
|
||||
}
|
||||
return (SMILLayoutElement) layoutElement;
|
||||
}
|
||||
|
||||
/*
|
||||
* DocumentEvent Interface
|
||||
*/
|
||||
public Event createEvent(String eventType) throws DOMException {
|
||||
if ("Event".equals(eventType)) {
|
||||
return new EventImpl();
|
||||
} else {
|
||||
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
|
||||
"Not supported interface");
|
||||
}
|
||||
}
|
||||
}
|
47
src/org/thoughtcrime/securesms/dom/smil/SmilElementImpl.java
Normal file
47
src/org/thoughtcrime/securesms/dom/smil/SmilElementImpl.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.ElementImpl;
|
||||
|
||||
public class SmilElementImpl extends ElementImpl implements SMILElement {
|
||||
/**
|
||||
* This constructor is used by the factory methods of the SmilDocument.
|
||||
*
|
||||
* @param owner The SMIL document to which this element belongs to
|
||||
* @param tagName The tag name of the element
|
||||
*/
|
||||
SmilElementImpl(SmilDocumentImpl owner, String tagName)
|
||||
{
|
||||
super(owner, tagName.toLowerCase());
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setId(String id) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.smil.SMILLayoutElement;
|
||||
import org.w3c.dom.smil.SMILRootLayoutElement;
|
||||
|
||||
public class SmilLayoutElementImpl extends SmilElementImpl implements
|
||||
SMILLayoutElement {
|
||||
SmilLayoutElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
public boolean getResolved() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.getAttribute("type");
|
||||
}
|
||||
|
||||
public NodeList getRegions() {
|
||||
return this.getElementsByTagName("region");
|
||||
}
|
||||
|
||||
public SMILRootLayoutElement getRootLayout() {
|
||||
NodeList childNodes = this.getChildNodes();
|
||||
SMILRootLayoutElement rootLayoutNode = null;
|
||||
int childrenCount = childNodes.getLength();
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
if (childNodes.item(i).getNodeName().equals("root-layout")) {
|
||||
rootLayoutNode = (SMILRootLayoutElement)childNodes.item(i);
|
||||
}
|
||||
}
|
||||
if (null == rootLayoutNode) {
|
||||
// root-layout node is not set. Create a default one.
|
||||
rootLayoutNode = (SMILRootLayoutElement) getOwnerDocument().createElement("root-layout");
|
||||
rootLayoutNode.setWidth(SmilUtil.ROOT_WIDTH);
|
||||
rootLayoutNode.setHeight(SmilUtil.ROOT_HEIGHT);
|
||||
appendChild(rootLayoutNode);
|
||||
}
|
||||
return rootLayoutNode;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.events.DocumentEvent;
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.events.EventImpl;
|
||||
|
||||
public class SmilMediaElementImpl extends SmilElementImpl implements
|
||||
SMILMediaElement {
|
||||
public final static String SMIL_MEDIA_START_EVENT = "SmilMediaStart";
|
||||
public final static String SMIL_MEDIA_END_EVENT = "SmilMediaEnd";
|
||||
public final static String SMIL_MEDIA_PAUSE_EVENT = "SmilMediaPause";
|
||||
public final static String SMIL_MEDIA_SEEK_EVENT = "SmilMediaSeek";
|
||||
private final static String TAG = "Mms:smil";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
|
||||
ElementTime mElementTime = new ElementTimeImpl(this) {
|
||||
private Event createEvent(String eventType) {
|
||||
DocumentEvent doc =
|
||||
(DocumentEvent)SmilMediaElementImpl.this.getOwnerDocument();
|
||||
Event event = doc.createEvent("Event");
|
||||
event.initEvent(eventType, false, false);
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Dispatching 'begin' event to "
|
||||
+ SmilMediaElementImpl.this.getTagName() + " "
|
||||
+ SmilMediaElementImpl.this.getSrc() + " at "
|
||||
+ System.currentTimeMillis());
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
private Event createEvent(String eventType, int seekTo) {
|
||||
DocumentEvent doc =
|
||||
(DocumentEvent)SmilMediaElementImpl.this.getOwnerDocument();
|
||||
EventImpl event = (EventImpl) doc.createEvent("Event");
|
||||
event.initEvent(eventType, false, false, seekTo);
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Dispatching 'begin' event to "
|
||||
+ SmilMediaElementImpl.this.getTagName() + " "
|
||||
+ SmilMediaElementImpl.this.getSrc() + " at "
|
||||
+ System.currentTimeMillis());
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
public boolean beginElement() {
|
||||
Event startEvent = createEvent(SMIL_MEDIA_START_EVENT);
|
||||
dispatchEvent(startEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
Event endEvent = createEvent(SMIL_MEDIA_END_EVENT);
|
||||
dispatchEvent(endEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
Event resumeEvent = createEvent(SMIL_MEDIA_START_EVENT);
|
||||
dispatchEvent(resumeEvent);
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
Event pauseEvent = createEvent(SMIL_MEDIA_PAUSE_EVENT);
|
||||
dispatchEvent(pauseEvent);
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
Event seekEvent = createEvent(SMIL_MEDIA_SEEK_EVENT, (int) seekTo);
|
||||
dispatchEvent(seekEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDur() {
|
||||
float dur = super.getDur();
|
||||
if (dur == 0) {
|
||||
// Duration is not specified, So get the implicit duration.
|
||||
String tag = getTagName();
|
||||
if (tag.equals("video") || tag.equals("audio")) {
|
||||
// Continuous media
|
||||
// FIXME Should get the duration of the media. "indefinite" instead here.
|
||||
dur = -1.0F;
|
||||
} else if (tag.equals("text") || tag.equals("img")) {
|
||||
// Discrete media
|
||||
dur = 0;
|
||||
} else {
|
||||
Log.w(TAG, "Unknown media type");
|
||||
}
|
||||
}
|
||||
return dur;
|
||||
}
|
||||
|
||||
@Override
|
||||
ElementTime getParentElementTime() {
|
||||
return ((SmilParElementImpl) mSmilElement.getParentNode()).mParTimeContainer;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
SmilMediaElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
/*
|
||||
* SMILMediaElement Interface
|
||||
*/
|
||||
|
||||
public String getAbstractAttr() {
|
||||
return this.getAttribute("abstract");
|
||||
}
|
||||
|
||||
public String getAlt() {
|
||||
return this.getAttribute("alt");
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return this.getAttribute("author");
|
||||
}
|
||||
|
||||
public String getClipBegin() {
|
||||
return this.getAttribute("clipBegin");
|
||||
}
|
||||
|
||||
public String getClipEnd() {
|
||||
return this.getAttribute("clipEnd");
|
||||
}
|
||||
|
||||
public String getCopyright() {
|
||||
return this.getAttribute("copyright");
|
||||
}
|
||||
|
||||
public String getLongdesc() {
|
||||
return this.getAttribute("longdesc");
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return this.getAttribute("port");
|
||||
}
|
||||
|
||||
public String getReadIndex() {
|
||||
return this.getAttribute("readIndex");
|
||||
}
|
||||
|
||||
public String getRtpformat() {
|
||||
return this.getAttribute("rtpformat");
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return this.getAttribute("src");
|
||||
}
|
||||
|
||||
public String getStripRepeat() {
|
||||
return this.getAttribute("stripRepeat");
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.getAttribute("title");
|
||||
}
|
||||
|
||||
public String getTransport() {
|
||||
return this.getAttribute("transport");
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.getAttribute("type");
|
||||
}
|
||||
|
||||
public void setAbstractAttr(String abstractAttr) throws DOMException {
|
||||
this.setAttribute("abstract", abstractAttr);
|
||||
}
|
||||
|
||||
public void setAlt(String alt) throws DOMException {
|
||||
this.setAttribute("alt", alt);
|
||||
}
|
||||
|
||||
public void setAuthor(String author) throws DOMException {
|
||||
this.setAttribute("author", author);
|
||||
}
|
||||
|
||||
public void setClipBegin(String clipBegin) throws DOMException {
|
||||
this.setAttribute("clipBegin", clipBegin);
|
||||
}
|
||||
|
||||
public void setClipEnd(String clipEnd) throws DOMException {
|
||||
this.setAttribute("clipEnd", clipEnd);
|
||||
}
|
||||
|
||||
public void setCopyright(String copyright) throws DOMException {
|
||||
this.setAttribute("copyright", copyright);
|
||||
}
|
||||
|
||||
public void setLongdesc(String longdesc) throws DOMException {
|
||||
this.setAttribute("longdesc", longdesc);
|
||||
|
||||
}
|
||||
|
||||
public void setPort(String port) throws DOMException {
|
||||
this.setAttribute("port", port);
|
||||
}
|
||||
|
||||
public void setReadIndex(String readIndex) throws DOMException {
|
||||
this.setAttribute("readIndex", readIndex);
|
||||
}
|
||||
|
||||
public void setRtpformat(String rtpformat) throws DOMException {
|
||||
this.setAttribute("rtpformat", rtpformat);
|
||||
}
|
||||
|
||||
public void setSrc(String src) throws DOMException {
|
||||
this.setAttribute("src", src);
|
||||
}
|
||||
|
||||
public void setStripRepeat(String stripRepeat) throws DOMException {
|
||||
this.setAttribute("stripRepeat", stripRepeat);
|
||||
}
|
||||
|
||||
public void setTitle(String title) throws DOMException {
|
||||
this.setAttribute("title", title);
|
||||
}
|
||||
|
||||
public void setTransport(String transport) throws DOMException {
|
||||
this.setAttribute("transport", transport);
|
||||
}
|
||||
|
||||
public void setType(String type) throws DOMException {
|
||||
this.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/*
|
||||
* TimeElement Interface
|
||||
*/
|
||||
|
||||
public boolean beginElement() {
|
||||
return mElementTime.beginElement();
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
return mElementTime.endElement();
|
||||
}
|
||||
|
||||
public TimeList getBegin() {
|
||||
return mElementTime.getBegin();
|
||||
}
|
||||
|
||||
public float getDur() {
|
||||
return mElementTime.getDur();
|
||||
}
|
||||
|
||||
public TimeList getEnd() {
|
||||
return mElementTime.getEnd();
|
||||
}
|
||||
|
||||
public short getFill() {
|
||||
return mElementTime.getFill();
|
||||
}
|
||||
|
||||
public short getFillDefault() {
|
||||
return mElementTime.getFillDefault();
|
||||
}
|
||||
|
||||
public float getRepeatCount() {
|
||||
return mElementTime.getRepeatCount();
|
||||
}
|
||||
|
||||
public float getRepeatDur() {
|
||||
return mElementTime.getRepeatDur();
|
||||
}
|
||||
|
||||
public short getRestart() {
|
||||
return mElementTime.getRestart();
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
mElementTime.pauseElement();
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
mElementTime.resumeElement();
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
mElementTime.seekElement(seekTo);
|
||||
}
|
||||
|
||||
public void setBegin(TimeList begin) throws DOMException {
|
||||
mElementTime.setBegin(begin);
|
||||
}
|
||||
|
||||
public void setDur(float dur) throws DOMException {
|
||||
mElementTime.setDur(dur);
|
||||
}
|
||||
|
||||
public void setEnd(TimeList end) throws DOMException {
|
||||
mElementTime.setEnd(end);
|
||||
}
|
||||
|
||||
public void setFill(short fill) throws DOMException {
|
||||
mElementTime.setFill(fill);
|
||||
}
|
||||
|
||||
public void setFillDefault(short fillDefault) throws DOMException {
|
||||
mElementTime.setFillDefault(fillDefault);
|
||||
}
|
||||
|
||||
public void setRepeatCount(float repeatCount) throws DOMException {
|
||||
mElementTime.setRepeatCount(repeatCount);
|
||||
}
|
||||
|
||||
public void setRepeatDur(float repeatDur) throws DOMException {
|
||||
mElementTime.setRepeatDur(repeatDur);
|
||||
}
|
||||
|
||||
public void setRestart(short restart) throws DOMException {
|
||||
mElementTime.setRestart(restart);
|
||||
}
|
||||
}
|
217
src/org/thoughtcrime/securesms/dom/smil/SmilParElementImpl.java
Normal file
217
src/org/thoughtcrime/securesms/dom/smil/SmilParElementImpl.java
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.events.DocumentEvent;
|
||||
import org.w3c.dom.events.Event;
|
||||
import org.w3c.dom.smil.ElementParallelTimeContainer;
|
||||
import org.w3c.dom.smil.ElementTime;
|
||||
import org.w3c.dom.smil.SMILParElement;
|
||||
import org.w3c.dom.smil.Time;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
public class SmilParElementImpl extends SmilElementImpl implements SMILParElement {
|
||||
public final static String SMIL_SLIDE_START_EVENT = "SmilSlideStart";
|
||||
public final static String SMIL_SLIDE_END_EVENT = "SmilSlideEnd";
|
||||
|
||||
ElementParallelTimeContainer mParTimeContainer =
|
||||
new ElementParallelTimeContainerImpl(this) {
|
||||
@Override
|
||||
public TimeList getBegin() {
|
||||
/*
|
||||
* For children of a sequence, the only legal value for begin is
|
||||
* a (single) non-negative offset value.
|
||||
*/
|
||||
TimeList beginTimeList = super.getBegin();
|
||||
if (beginTimeList.getLength() > 1) {
|
||||
ArrayList<Time> singleTimeContainer = new ArrayList<Time>();
|
||||
singleTimeContainer.add(beginTimeList.item(0));
|
||||
beginTimeList = new TimeListImpl(singleTimeContainer);
|
||||
}
|
||||
return beginTimeList;
|
||||
}
|
||||
|
||||
public NodeList getTimeChildren() {
|
||||
return getChildNodes();
|
||||
}
|
||||
|
||||
public boolean beginElement() {
|
||||
DocumentEvent doc = (DocumentEvent) SmilParElementImpl.this.getOwnerDocument();
|
||||
Event startEvent = doc.createEvent("Event");
|
||||
startEvent.initEvent(SMIL_SLIDE_START_EVENT, false, false);
|
||||
dispatchEvent(startEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
DocumentEvent doc = (DocumentEvent) SmilParElementImpl.this.getOwnerDocument();
|
||||
Event endEvent = doc.createEvent("Event");
|
||||
endEvent.initEvent(SMIL_SLIDE_END_EVENT, false, false);
|
||||
dispatchEvent(endEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
ElementTime getParentElementTime() {
|
||||
return ((SmilDocumentImpl) mSmilElement.getOwnerDocument()).mSeqTimeContainer;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
SmilParElementImpl(SmilDocumentImpl owner, String tagName)
|
||||
{
|
||||
super(owner, tagName.toUpperCase());
|
||||
}
|
||||
|
||||
int getBeginConstraints() {
|
||||
/*
|
||||
* For children of a sequence, the only legal value for begin is
|
||||
* a (single) non-negative offset value.
|
||||
*/
|
||||
return (TimeImpl.ALLOW_OFFSET_VALUE); // Do not set ALLOW_NEGATIVE_VALUE
|
||||
}
|
||||
|
||||
/*
|
||||
* ElementParallelTimeContainer
|
||||
*/
|
||||
|
||||
public String getEndSync() {
|
||||
return mParTimeContainer.getEndSync();
|
||||
}
|
||||
|
||||
public float getImplicitDuration() {
|
||||
return mParTimeContainer.getImplicitDuration();
|
||||
}
|
||||
|
||||
public void setEndSync(String endSync) throws DOMException {
|
||||
mParTimeContainer.setEndSync(endSync);
|
||||
}
|
||||
|
||||
public NodeList getActiveChildrenAt(float instant) {
|
||||
return mParTimeContainer.getActiveChildrenAt(instant);
|
||||
}
|
||||
|
||||
public NodeList getTimeChildren() {
|
||||
return mParTimeContainer.getTimeChildren();
|
||||
}
|
||||
|
||||
public boolean beginElement() {
|
||||
return mParTimeContainer.beginElement();
|
||||
}
|
||||
|
||||
public boolean endElement() {
|
||||
return mParTimeContainer.endElement();
|
||||
}
|
||||
|
||||
public TimeList getBegin() {
|
||||
return mParTimeContainer.getBegin();
|
||||
}
|
||||
|
||||
public float getDur() {
|
||||
return mParTimeContainer.getDur();
|
||||
}
|
||||
|
||||
public TimeList getEnd() {
|
||||
return mParTimeContainer.getEnd();
|
||||
}
|
||||
|
||||
public short getFill() {
|
||||
return mParTimeContainer.getFill();
|
||||
}
|
||||
|
||||
public short getFillDefault() {
|
||||
return mParTimeContainer.getFillDefault();
|
||||
}
|
||||
|
||||
public float getRepeatCount() {
|
||||
return mParTimeContainer.getRepeatCount();
|
||||
}
|
||||
|
||||
public float getRepeatDur() {
|
||||
return mParTimeContainer.getRepeatDur();
|
||||
}
|
||||
|
||||
public short getRestart() {
|
||||
return mParTimeContainer.getRestart();
|
||||
}
|
||||
|
||||
public void pauseElement() {
|
||||
mParTimeContainer.pauseElement();
|
||||
}
|
||||
|
||||
public void resumeElement() {
|
||||
mParTimeContainer.resumeElement();
|
||||
}
|
||||
|
||||
public void seekElement(float seekTo) {
|
||||
mParTimeContainer.seekElement(seekTo);
|
||||
}
|
||||
|
||||
public void setBegin(TimeList begin) throws DOMException {
|
||||
mParTimeContainer.setBegin(begin);
|
||||
}
|
||||
|
||||
public void setDur(float dur) throws DOMException {
|
||||
mParTimeContainer.setDur(dur);
|
||||
}
|
||||
|
||||
public void setEnd(TimeList end) throws DOMException {
|
||||
mParTimeContainer.setEnd(end);
|
||||
}
|
||||
|
||||
public void setFill(short fill) throws DOMException {
|
||||
mParTimeContainer.setFill(fill);
|
||||
}
|
||||
|
||||
public void setFillDefault(short fillDefault) throws DOMException {
|
||||
mParTimeContainer.setFillDefault(fillDefault);
|
||||
}
|
||||
|
||||
public void setRepeatCount(float repeatCount) throws DOMException {
|
||||
mParTimeContainer.setRepeatCount(repeatCount);
|
||||
}
|
||||
|
||||
public void setRepeatDur(float repeatDur) throws DOMException {
|
||||
mParTimeContainer.setRepeatDur(repeatDur);
|
||||
}
|
||||
|
||||
public void setRestart(short restart) throws DOMException {
|
||||
mParTimeContainer.setRestart(restart);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.smil.SMILRefElement;
|
||||
|
||||
public class SmilRefElementImpl extends SmilRegionMediaElementImpl implements
|
||||
SMILRefElement {
|
||||
|
||||
SmilRefElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SmilRegionElementImpl extends SmilElementImpl implements
|
||||
SMILRegionElement {
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
private static final String HIDDEN_ATTRIBUTE = "hidden";
|
||||
private static final String SLICE_ATTRIBUTE = "slice";
|
||||
private static final String SCROLL_ATTRIBUTE = "scroll";
|
||||
private static final String MEET_ATTRIBUTE = "meet";
|
||||
private static final String FILL_ATTRIBUTE = "fill";
|
||||
private static final String ID_ATTRIBUTE_NAME = "id";
|
||||
private static final String WIDTH_ATTRIBUTE_NAME = "width";
|
||||
private static final String TITLE_ATTRIBUTE_NAME = "title";
|
||||
private static final String HEIGHT_ATTRIBUTE_NAME = "height";
|
||||
private static final String BACKGROUND_COLOR_ATTRIBUTE_NAME = "backgroundColor";
|
||||
private static final String Z_INDEX_ATTRIBUTE_NAME = "z-index";
|
||||
private static final String TOP_ATTRIBUTE_NAME = "top";
|
||||
private static final String LEFT_ATTRIBUTE_NAME = "left";
|
||||
private static final String RIGHT_ATTRIBUTE_NAME = "right";
|
||||
private static final String BOTTOM_ATTRIBUTE_NAME = "bottom";
|
||||
private static final String FIT_ATTRIBUTE_NAME = "fit";
|
||||
private static final String TAG = "SmilRegionElementImpl";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
|
||||
SmilRegionElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
/*
|
||||
* SMILRegionElement Interface
|
||||
*/
|
||||
|
||||
public String getFit() {
|
||||
String fit = getAttribute(FIT_ATTRIBUTE_NAME);
|
||||
if (FILL_ATTRIBUTE.equalsIgnoreCase(fit)) {
|
||||
return FILL_ATTRIBUTE;
|
||||
} else if (MEET_ATTRIBUTE.equalsIgnoreCase(fit)) {
|
||||
return MEET_ATTRIBUTE;
|
||||
} else if (SCROLL_ATTRIBUTE.equalsIgnoreCase(fit)) {
|
||||
return SCROLL_ATTRIBUTE;
|
||||
} else if (SLICE_ATTRIBUTE.equalsIgnoreCase(fit)) {
|
||||
return SLICE_ATTRIBUTE;
|
||||
} else {
|
||||
return HIDDEN_ATTRIBUTE;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLeft() {
|
||||
try {
|
||||
return parseRegionLength(getAttribute(LEFT_ATTRIBUTE_NAME), true);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Left attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
int bbw = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
|
||||
int right = parseRegionLength(getAttribute(RIGHT_ATTRIBUTE_NAME), true);
|
||||
int width = parseRegionLength(getAttribute(WIDTH_ATTRIBUTE_NAME), true);
|
||||
return bbw - right - width;
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Right or width attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getTop() {
|
||||
try {
|
||||
return parseRegionLength(getAttribute(TOP_ATTRIBUTE_NAME), false);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Top attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
int bbh = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
|
||||
int bottom = parseRegionLength(getAttribute(BOTTOM_ATTRIBUTE_NAME), false);
|
||||
int height = parseRegionLength(getAttribute(HEIGHT_ATTRIBUTE_NAME), false);
|
||||
return bbh - bottom - height;
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Bottom or height attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getZIndex() {
|
||||
try {
|
||||
return Integer.parseInt(this.getAttribute(Z_INDEX_ATTRIBUTE_NAME));
|
||||
} catch (NumberFormatException _) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFit(String fit) throws DOMException {
|
||||
if (fit.equalsIgnoreCase(FILL_ATTRIBUTE)
|
||||
|| fit.equalsIgnoreCase(MEET_ATTRIBUTE)
|
||||
|| fit.equalsIgnoreCase(SCROLL_ATTRIBUTE)
|
||||
|| fit.equalsIgnoreCase(SLICE_ATTRIBUTE)) {
|
||||
this.setAttribute(FIT_ATTRIBUTE_NAME, fit.toLowerCase());
|
||||
} else {
|
||||
this.setAttribute(FIT_ATTRIBUTE_NAME, HIDDEN_ATTRIBUTE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLeft(int left) throws DOMException {
|
||||
this.setAttribute(LEFT_ATTRIBUTE_NAME, String.valueOf(left));
|
||||
}
|
||||
|
||||
public void setTop(int top) throws DOMException {
|
||||
this.setAttribute(TOP_ATTRIBUTE_NAME, String.valueOf(top));
|
||||
}
|
||||
|
||||
public void setZIndex(int zIndex) throws DOMException {
|
||||
if (zIndex > 0) {
|
||||
this.setAttribute(Z_INDEX_ATTRIBUTE_NAME, Integer.toString(zIndex));
|
||||
} else {
|
||||
this.setAttribute(Z_INDEX_ATTRIBUTE_NAME, Integer.toString(0));
|
||||
}
|
||||
}
|
||||
|
||||
public String getBackgroundColor() {
|
||||
return this.getAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
try {
|
||||
final int height = parseRegionLength(getAttribute(HEIGHT_ATTRIBUTE_NAME), false);
|
||||
return height == 0 ?
|
||||
((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight() :
|
||||
height;
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Height attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
int bbh = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
|
||||
try {
|
||||
bbh -= parseRegionLength(getAttribute(TOP_ATTRIBUTE_NAME), false);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Top attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
bbh -= parseRegionLength(getAttribute(BOTTOM_ATTRIBUTE_NAME), false);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Bottom attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
return bbh;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.getAttribute(TITLE_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
try {
|
||||
final int width = parseRegionLength(getAttribute(WIDTH_ATTRIBUTE_NAME), true);
|
||||
return width == 0 ?
|
||||
((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth() :
|
||||
width;
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Width attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
int bbw = ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
|
||||
try {
|
||||
bbw -= parseRegionLength(getAttribute(LEFT_ATTRIBUTE_NAME), true);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Left attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
bbw -= parseRegionLength(getAttribute(RIGHT_ATTRIBUTE_NAME), true);
|
||||
} catch (NumberFormatException _) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.v(TAG, "Right attribute is not set or incorrect.");
|
||||
}
|
||||
}
|
||||
return bbw;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(String backgroundColor) throws DOMException {
|
||||
this.setAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME, backgroundColor);
|
||||
}
|
||||
|
||||
public void setHeight(int height) throws DOMException {
|
||||
this.setAttribute(HEIGHT_ATTRIBUTE_NAME, String.valueOf(height) + "px");
|
||||
}
|
||||
|
||||
public void setTitle(String title) throws DOMException {
|
||||
this.setAttribute(TITLE_ATTRIBUTE_NAME, title);
|
||||
}
|
||||
|
||||
public void setWidth(int width) throws DOMException {
|
||||
this.setAttribute(WIDTH_ATTRIBUTE_NAME, String.valueOf(width) + "px");
|
||||
}
|
||||
|
||||
/*
|
||||
* SMILElement Interface
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.getAttribute(ID_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) throws DOMException {
|
||||
this.setAttribute(ID_ATTRIBUTE_NAME, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
private int parseRegionLength(String length, boolean horizontal) {
|
||||
if (length.endsWith("px")) {
|
||||
length = length.substring(0, length.indexOf("px"));
|
||||
return Integer.parseInt(length);
|
||||
} else if (length.endsWith("%")) {
|
||||
double value = 0.01*Integer.parseInt(length.substring(0, length.length() - 1));
|
||||
if (horizontal) {
|
||||
value *= ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getWidth();
|
||||
} else {
|
||||
value *= ((SMILDocument) getOwnerDocument()).getLayout().getRootLayout().getHeight();
|
||||
}
|
||||
return (int) Math.round(value);
|
||||
} else {
|
||||
return Integer.parseInt(length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()
|
||||
+ ": id=" + getId()
|
||||
+ ", width=" + getWidth()
|
||||
+ ", height=" + getHeight()
|
||||
+ ", left=" + getLeft()
|
||||
+ ", top=" + getTop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.w3c.dom.smil.SMILRegionMediaElement;
|
||||
|
||||
public class SmilRegionMediaElementImpl extends SmilMediaElementImpl implements
|
||||
SMILRegionMediaElement {
|
||||
private SMILRegionElement mRegion;
|
||||
|
||||
SmilRegionMediaElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
public SMILRegionElement getRegion() {
|
||||
if (mRegion == null) {
|
||||
SMILDocument doc = (SMILDocument)this.getOwnerDocument();
|
||||
NodeList regions = doc.getLayout().getElementsByTagName("region");
|
||||
SMILRegionElement region = null;
|
||||
for (int i = 0; i < regions.getLength(); i++) {
|
||||
region = (SMILRegionElement)regions.item(i);
|
||||
if (region.getId().equals(this.getAttribute("region"))) {
|
||||
mRegion = region;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mRegion;
|
||||
}
|
||||
|
||||
public void setRegion(SMILRegionElement region) {
|
||||
this.setAttribute("region", region.getId());
|
||||
mRegion = region;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.smil.SMILRootLayoutElement;
|
||||
|
||||
public class SmilRootLayoutElementImpl extends SmilElementImpl implements
|
||||
SMILRootLayoutElement {
|
||||
|
||||
private static final String WIDTH_ATTRIBUTE_NAME = "width";
|
||||
private static final String HEIGHT_ATTRIBUTE_NAME = "height";
|
||||
private static final String BACKGROUND_COLOR_ATTRIBUTE_NAME = "backgroundColor";
|
||||
private static final String TITLE_ATTRIBUTE_NAME = "title";
|
||||
|
||||
SmilRootLayoutElementImpl(SmilDocumentImpl owner, String tagName) {
|
||||
super(owner, tagName);
|
||||
}
|
||||
|
||||
public String getBackgroundColor() {
|
||||
return this.getAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
String heightString = this.getAttribute(HEIGHT_ATTRIBUTE_NAME);
|
||||
return parseAbsoluteLength(heightString);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.getAttribute(TITLE_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
String widthString = this.getAttribute(WIDTH_ATTRIBUTE_NAME);
|
||||
return parseAbsoluteLength(widthString);
|
||||
}
|
||||
|
||||
public void setBackgroundColor(String backgroundColor) throws DOMException {
|
||||
this.setAttribute(BACKGROUND_COLOR_ATTRIBUTE_NAME, backgroundColor);
|
||||
}
|
||||
|
||||
public void setHeight(int height) throws DOMException {
|
||||
this.setAttribute(HEIGHT_ATTRIBUTE_NAME, String.valueOf(height) + "px");
|
||||
|
||||
}
|
||||
|
||||
public void setTitle(String title) throws DOMException {
|
||||
this.setAttribute(TITLE_ATTRIBUTE_NAME, title);
|
||||
}
|
||||
|
||||
public void setWidth(int width) throws DOMException {
|
||||
this.setAttribute(WIDTH_ATTRIBUTE_NAME, String.valueOf(width) + "px");
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
|
||||
private int parseAbsoluteLength(String length) {
|
||||
if (length.endsWith("px")) {
|
||||
length = length.substring(0, length.indexOf("px"));
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(length);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
295
src/org/thoughtcrime/securesms/dom/smil/TimeImpl.java
Normal file
295
src/org/thoughtcrime/securesms/dom/smil/TimeImpl.java
Normal file
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Esmertec AG.
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.smil.Time;
|
||||
|
||||
public class TimeImpl implements Time {
|
||||
static final int ALLOW_INDEFINITE_VALUE = (1 << 0);
|
||||
static final int ALLOW_OFFSET_VALUE = (1 << 1);
|
||||
static final int ALLOW_SYNCBASE_VALUE = (1 << 2);
|
||||
static final int ALLOW_SYNCTOPREV_VALUE = (1 << 3);
|
||||
static final int ALLOW_EVENT_VALUE = (1 << 4);
|
||||
static final int ALLOW_MARKER_VALUE = (1 << 5);
|
||||
static final int ALLOW_WALLCLOCK_VALUE = (1 << 6);
|
||||
static final int ALLOW_NEGATIVE_VALUE = (1 << 7);
|
||||
static final int ALLOW_ALL = 0xFF;
|
||||
|
||||
short mTimeType;
|
||||
boolean mResolved;
|
||||
double mResolvedOffset;
|
||||
|
||||
/**
|
||||
* Creates a TimeImpl representation of a time-value represented as a String.
|
||||
* Time-values have the following syntax:
|
||||
* <p>
|
||||
* <pre>
|
||||
* Time-val ::= ( smil-1.0-syncbase-value
|
||||
* | "indefinite"
|
||||
* | offset-value
|
||||
* | syncbase-value
|
||||
* | syncToPrev-value
|
||||
* | event-value
|
||||
* | media-marker-value
|
||||
* | wallclock-sync-value )
|
||||
* Smil-1.0-syncbase-value ::=
|
||||
* "id(" id-ref ")" ( "(" ( "begin" | "end" | clock-value ) ")" )?
|
||||
* Offset-value ::= ( "+" | "-" )? clock-value
|
||||
* Syncbase-value ::= ( id-ref "." ( "begin" | "end" ) ) ( ( "+" | "-" ) clock-value )?
|
||||
* SyncToPrev-value ::= ( "prev.begin" | "prev.end" ) ( ( "+" | "-" ) clock-value )?
|
||||
* Event-value ::= ( id-ref "." )? ( event-ref ) ( ( "+" | "-" ) clock-value )?
|
||||
* Media-marker-value ::= id-ref ".marker(" marker-name ")"
|
||||
* Wallclock-sync-value ::= "wallclock(" wallclock-value ")"
|
||||
* </pre>
|
||||
*
|
||||
* @param timeValue A String in the representation specified above
|
||||
* @param constraints Any combination of the #ALLOW_* flags
|
||||
* @return A TimeImpl instance representing
|
||||
* @exception java.lang.IllegalArgumentException if the timeValue input
|
||||
* parameter does not comply with the defined syntax
|
||||
* @exception java.lang.NullPointerException if the timekValue string is
|
||||
* <code>null</code>
|
||||
*/
|
||||
TimeImpl(String timeValue, int constraints) {
|
||||
/*
|
||||
* We do not support yet:
|
||||
* - smil-1.0-syncbase-value
|
||||
* - syncbase-value
|
||||
* - syncToPrev-value
|
||||
* - event-value
|
||||
* - Media-marker-value
|
||||
* - Wallclock-sync-value
|
||||
*/
|
||||
// Will throw NullPointerException if timeValue is null
|
||||
if (timeValue.equals("indefinite")
|
||||
&& ((constraints & ALLOW_INDEFINITE_VALUE) != 0) ) {
|
||||
mTimeType = SMIL_TIME_INDEFINITE;
|
||||
} else if ((constraints & ALLOW_OFFSET_VALUE) != 0) {
|
||||
int sign = 1;
|
||||
if (timeValue.startsWith("+")) {
|
||||
timeValue = timeValue.substring(1);
|
||||
} else if (timeValue.startsWith("-")) {
|
||||
timeValue = timeValue.substring(1);
|
||||
sign = -1;
|
||||
}
|
||||
mResolvedOffset = sign*parseClockValue(timeValue)/1000.0;
|
||||
mResolved = true;
|
||||
mTimeType = SMIL_TIME_OFFSET;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported time value");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a String representation of a clock value into the float
|
||||
* representation used in this API.
|
||||
* <p>
|
||||
* Clock values have the following syntax:
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>
|
||||
* Clock-val ::= ( Full-clock-val | Partial-clock-val | Timecount-val )
|
||||
* Full-clock-val ::= Hours ":" Minutes ":" Seconds ("." Fraction)?
|
||||
* Partial-clock-val ::= Minutes ":" Seconds ("." Fraction)?
|
||||
* Timecount-val ::= Timecount ("." Fraction)? (Metric)?
|
||||
* Metric ::= "h" | "min" | "s" | "ms"
|
||||
* Hours ::= DIGIT+; any positive number
|
||||
* Minutes ::= 2DIGIT; range from 00 to 59
|
||||
* Seconds ::= 2DIGIT; range from 00 to 59
|
||||
* Fraction ::= DIGIT+
|
||||
* Timecount ::= DIGIT+
|
||||
* 2DIGIT ::= DIGIT DIGIT
|
||||
* DIGIT ::= [0-9]
|
||||
* </pre>
|
||||
*
|
||||
* @param clockValue A String in the representation specified above
|
||||
* @return A float value in milliseconds that matches the string
|
||||
* representation given as the parameter
|
||||
* @exception java.lang.IllegalArgumentException if the clockValue input
|
||||
* parameter does not comply with the defined syntax
|
||||
* @exception java.lang.NullPointerException if the clockValue string is
|
||||
* <code>null</code>
|
||||
*/
|
||||
public static float parseClockValue(String clockValue) {
|
||||
try {
|
||||
float result = 0;
|
||||
|
||||
// Will throw NullPointerException if clockValue is null
|
||||
clockValue = clockValue.trim();
|
||||
|
||||
// Handle first 'Timecount-val' cases with metric
|
||||
if (clockValue.endsWith("ms")) {
|
||||
result = parseFloat(clockValue, 2, true);
|
||||
} else if (clockValue.endsWith("s")) {
|
||||
result = 1000*parseFloat(clockValue, 1, true);
|
||||
} else if (clockValue.endsWith("min")) {
|
||||
result = 60000*parseFloat(clockValue, 3, true);
|
||||
} else if (clockValue.endsWith("h")) {
|
||||
result = 3600000*parseFloat(clockValue, 1, true);
|
||||
} else {
|
||||
// Handle Timecount-val without metric
|
||||
try {
|
||||
return parseFloat(clockValue, 0, true) * 1000;
|
||||
} catch (NumberFormatException _) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Split in {[Hours], Minutes, Seconds}
|
||||
String[] timeValues = clockValue.split(":");
|
||||
|
||||
// Read Hours if present and remember location of Minutes
|
||||
int indexOfMinutes;
|
||||
if (timeValues.length == 2) {
|
||||
indexOfMinutes = 0;
|
||||
} else if (timeValues.length == 3) {
|
||||
result = 3600000*(int)parseFloat(timeValues[0], 0, false);
|
||||
indexOfMinutes = 1;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// Read Minutes
|
||||
int minutes = (int)parseFloat(timeValues[indexOfMinutes], 0, false);
|
||||
if ((minutes >= 00) && (minutes <= 59)) {
|
||||
result += 60000*minutes;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// Read Seconds
|
||||
float seconds = parseFloat(timeValues[indexOfMinutes + 1], 0, true);
|
||||
if ((seconds >= 00) && (seconds < 60)) {
|
||||
result += 60000*seconds;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a value formatted as follows:
|
||||
* <p>
|
||||
* <pre>
|
||||
* Value ::= Number ("." Decimal)? (Text)?
|
||||
* Number ::= DIGIT+; any positive number
|
||||
* Decimal ::= DIGIT+; any positive number
|
||||
* Text ::= CHAR*; any sequence of chars
|
||||
* DIGIT ::= [0-9]
|
||||
* </pre>
|
||||
* @param value The Value to parse
|
||||
* @param ignoreLast The size of Text to ignore
|
||||
* @param parseDecimal Whether Decimal is expected
|
||||
* @return The float value without Text, rounded to 3 digits after '.'
|
||||
* @throws IllegalArgumentException if Decimal was not expected but encountered
|
||||
*/
|
||||
private static float parseFloat(String value, int ignoreLast, boolean parseDecimal) {
|
||||
// Ignore last characters
|
||||
value = value.substring(0, value.length() - ignoreLast);
|
||||
|
||||
float result;
|
||||
int indexOfComma = value.indexOf('.');
|
||||
if (indexOfComma != -1) {
|
||||
if (!parseDecimal) {
|
||||
throw new IllegalArgumentException("int value contains decimal");
|
||||
}
|
||||
// Ensure that there are at least 3 decimals
|
||||
value = value + "000";
|
||||
// Read value up to 3 decimals and cut the rest
|
||||
result = Float.parseFloat(value.substring(0, indexOfComma));
|
||||
result += Float.parseFloat(
|
||||
value.substring(indexOfComma + 1, indexOfComma + 4))/1000;
|
||||
} else {
|
||||
result = Integer.parseInt(value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Time Interface
|
||||
*/
|
||||
|
||||
public boolean getBaseBegin() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public Element getBaseElement() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getEvent() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getMarker() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getOffset() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean getResolved() {
|
||||
return mResolved;
|
||||
}
|
||||
|
||||
public double getResolvedOffset() {
|
||||
return mResolvedOffset;
|
||||
}
|
||||
|
||||
public short getTimeType() {
|
||||
return mTimeType;
|
||||
}
|
||||
|
||||
public void setBaseBegin(boolean baseBegin) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setBaseElement(Element baseElement) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setEvent(String event) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setMarker(String marker) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setOffset(double offset) throws DOMException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
53
src/org/thoughtcrime/securesms/dom/smil/TimeListImpl.java
Normal file
53
src/org/thoughtcrime/securesms/dom/smil/TimeListImpl.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.w3c.dom.smil.Time;
|
||||
import org.w3c.dom.smil.TimeList;
|
||||
|
||||
public class TimeListImpl implements TimeList {
|
||||
private final ArrayList<Time> mTimes;
|
||||
|
||||
/*
|
||||
* Internal Interface
|
||||
*/
|
||||
TimeListImpl(ArrayList<Time> times) {
|
||||
mTimes = times;
|
||||
}
|
||||
|
||||
/*
|
||||
* TimeList Interface
|
||||
*/
|
||||
|
||||
public int getLength() {
|
||||
return mTimes.size();
|
||||
}
|
||||
|
||||
public Time item(int index) {
|
||||
Time time = null;
|
||||
try {
|
||||
time = mTimes.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// Do nothing and return null
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Esmertec AG.
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.dom.smil.parser;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
|
||||
public class SmilXmlSerializer {
|
||||
public static void serialize(SMILDocument smilDoc, OutputStream out) {
|
||||
try {
|
||||
Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"), 2048);
|
||||
|
||||
writeElement(writer, smilDoc.getDocumentElement());
|
||||
writer.flush();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeElement(Writer writer, Element element)
|
||||
throws IOException {
|
||||
writer.write('<');
|
||||
writer.write(element.getTagName());
|
||||
|
||||
if (element.hasAttributes()) {
|
||||
NamedNodeMap attributes = element.getAttributes();
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
Attr attribute = (Attr)attributes.item(i);
|
||||
writer.write(" " + attribute.getName());
|
||||
writer.write("=\"" + attribute.getValue() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Might throw ClassCastException
|
||||
SMILElement childElement = (SMILElement) element.getFirstChild();
|
||||
|
||||
if (childElement != null) {
|
||||
writer.write('>');
|
||||
|
||||
do {
|
||||
writeElement(writer, childElement);
|
||||
childElement = (SMILElement) childElement.getNextSibling();
|
||||
} while (childElement != null);
|
||||
|
||||
writer.write("</");
|
||||
writer.write(element.getTagName());
|
||||
writer.write('>');
|
||||
} else {
|
||||
writer.write("/>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,16 +19,18 @@ package org.thoughtcrime.securesms.mms;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.w3c.dom.smil.SMILRegionMediaElement;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore.Audio;
|
||||
import android.widget.ImageView;
|
||||
|
||||
public class AudioSlide extends Slide {
|
||||
|
||||
|
@ -49,7 +51,17 @@ public class AudioSlide extends Slide {
|
|||
public boolean hasAudio() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SMILRegionElement getSmilRegion(SMILDocument document) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMILMediaElement getMediaElement(SMILDocument document) {
|
||||
return SmilUtil.createMediaElement("audio", document, new String(getPart().getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
return context.getResources().getDrawable(R.drawable.ic_menu_add_sound);
|
||||
|
@ -81,5 +93,4 @@ public class AudioSlide extends Slide {
|
|||
|
||||
return part;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
|
|||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -59,7 +63,7 @@ public class ImageSlide extends Slide {
|
|||
public ImageSlide(Context context, Uri uri) throws IOException, BitmapDecodingException {
|
||||
super(context, constructPartFromUri(context, uri));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
Drawable thumbnail = getCachedThumbnail();
|
||||
|
@ -161,12 +165,29 @@ public class ImageSlide extends Slide {
|
|||
public boolean hasImage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SMILRegionElement getSmilRegion(SMILDocument document) {
|
||||
SMILRegionElement region = (SMILRegionElement) document.createElement("region");
|
||||
region.setId("Image");
|
||||
region.setLeft(0);
|
||||
region.setTop(0);
|
||||
region.setWidth(SmilUtil.ROOT_WIDTH);
|
||||
region.setHeight(SmilUtil.ROOT_HEIGHT);
|
||||
region.setFit("meet");
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMILMediaElement getMediaElement(SMILDocument document) {
|
||||
return SmilUtil.createMediaElement("img", document, new String(getPart().getName()));
|
||||
}
|
||||
|
||||
private static PduPart constructPartFromUri(Context context, Uri uri)
|
||||
throws IOException, BitmapDecodingException
|
||||
{
|
||||
PduPart part = new PduPart();
|
||||
byte[] data = BitmapUtil.createScaledBytes(context, uri, 640, 480, (300 * 1024) - 5000);
|
||||
byte[] data = BitmapUtil.createScaledBytes(context, uri, 1280, 1280, MAX_MESSAGE_SIZE);
|
||||
|
||||
part.setData(data);
|
||||
part.setDataUri(uri);
|
||||
|
|
|
@ -20,6 +20,9 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.providers.PartProvider;
|
||||
|
@ -36,61 +39,61 @@ import ws.com.google.android.mms.pdu.PduPart;
|
|||
|
||||
public abstract class Slide {
|
||||
|
||||
protected static final int MAX_MESSAGE_SIZE = 1048576;
|
||||
|
||||
protected static final int MAX_MESSAGE_SIZE = 280 * 1024;
|
||||
|
||||
protected final PduPart part;
|
||||
protected final Context context;
|
||||
protected MasterSecret masterSecret;
|
||||
|
||||
|
||||
public Slide(Context context, PduPart part) {
|
||||
this.part = part;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
public Slide(Context context, MasterSecret masterSecret, PduPart part) {
|
||||
this(context, part);
|
||||
this.masterSecret = masterSecret;
|
||||
}
|
||||
|
||||
|
||||
public InputStream getPartDataInputStream() throws FileNotFoundException {
|
||||
Uri partUri = part.getDataUri();
|
||||
|
||||
|
||||
Log.w("Slide", "Loading Part URI: " + partUri);
|
||||
|
||||
|
||||
if (PartProvider.isAuthority(partUri))
|
||||
return DatabaseFactory.getEncryptingPartDatabase(context, masterSecret).getPartStream(ContentUris.parseId(partUri));
|
||||
else
|
||||
return context.getContentResolver().openInputStream(partUri);
|
||||
}
|
||||
|
||||
|
||||
protected static long getMediaSize(Context context, Uri uri) throws IOException {
|
||||
InputStream in = context.getContentResolver().openInputStream(uri);
|
||||
long size = 0;
|
||||
long size = 0;
|
||||
byte[] buffer = new byte[512];
|
||||
int read;
|
||||
|
||||
|
||||
while ((read = in.read(buffer)) != -1)
|
||||
size += read;
|
||||
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
protected byte[] getPartData() {
|
||||
if (part.getData() != null)
|
||||
return part.getData();
|
||||
|
||||
|
||||
long partId = ContentUris.parseId(part.getDataUri());
|
||||
return DatabaseFactory.getEncryptingPartDatabase(context, masterSecret).getPart(partId, true).getData();
|
||||
}
|
||||
|
||||
|
||||
public String getContentType() {
|
||||
return new String(part.getContentType());
|
||||
}
|
||||
|
||||
|
||||
public Uri getUri() {
|
||||
return part.getDataUri();
|
||||
}
|
||||
|
||||
|
||||
public Drawable getThumbnail(int maxWidth, int maxHeight) {
|
||||
throw new AssertionError("getThumbnail() called on non-thumbnail producing slide!");
|
||||
}
|
||||
|
@ -102,28 +105,32 @@ public abstract class Slide {
|
|||
public boolean hasImage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasVideo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasAudio() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Bitmap getImage() {
|
||||
throw new AssertionError("getImage() called on non-image slide!");
|
||||
}
|
||||
|
||||
|
||||
public boolean hasText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public String getText() {
|
||||
throw new AssertionError("getText() called on non-text slide!");
|
||||
}
|
||||
|
||||
|
||||
public PduPart getPart() {
|
||||
return part;
|
||||
}
|
||||
|
||||
public abstract SMILRegionElement getSmilRegion(SMILDocument document);
|
||||
|
||||
public abstract SMILMediaElement getMediaElement(SMILDocument document);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,11 @@ package org.thoughtcrime.securesms.mms;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.smil.parser.SmilXmlSerializer;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -27,9 +30,9 @@ import java.util.List;
|
|||
import ws.com.google.android.mms.ContentType;
|
||||
import ws.com.google.android.mms.pdu.CharacterSets;
|
||||
import ws.com.google.android.mms.pdu.PduBody;
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
|
||||
public class SlideDeck {
|
||||
|
||||
private final List<Slide> slides = new LinkedList<Slide>();
|
||||
|
||||
public SlideDeck(Context context, MasterSecret masterSecret, PduBody body) {
|
||||
|
@ -44,7 +47,7 @@ public class SlideDeck {
|
|||
slides.add(new AudioSlide(context, body.getPart(i)));
|
||||
else if (ContentType.isTextType(contentType))
|
||||
slides.add(new TextSlide(context, masterSecret, body.getPart(i)));
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
throw new AssertionError(uee);
|
||||
}
|
||||
|
@ -52,7 +55,7 @@ public class SlideDeck {
|
|||
|
||||
public SlideDeck() {
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
slides.clear();
|
||||
}
|
||||
|
@ -63,7 +66,16 @@ public class SlideDeck {
|
|||
for (Slide slide : slides) {
|
||||
body.addPart(slide.getPart());
|
||||
}
|
||||
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
SmilXmlSerializer.serialize(SmilUtil.createSmilDocument(this), out);
|
||||
PduPart smilPart = new PduPart();
|
||||
smilPart.setContentId("smil".getBytes());
|
||||
smilPart.setContentLocation("smil.xml".getBytes());
|
||||
smilPart.setContentType(ContentType.APP_SMIL.getBytes());
|
||||
smilPart.setData(out.toByteArray());
|
||||
body.addPart(0, smilPart);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@ import android.content.Context;
|
|||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
|
||||
|
@ -74,7 +78,24 @@ public class TextSlide extends Slide {
|
|||
return new String(getPartData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SMILRegionElement getSmilRegion(SMILDocument document) {
|
||||
SMILRegionElement region = (SMILRegionElement) document.createElement("region");
|
||||
region.setId("Text");
|
||||
region.setLeft(0);
|
||||
region.setTop(SmilUtil.ROOT_HEIGHT);
|
||||
region.setWidth(SmilUtil.ROOT_WIDTH);
|
||||
region.setHeight(50);
|
||||
region.setFit("meet");
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMILMediaElement getMediaElement(SMILDocument document) {
|
||||
return SmilUtil.createMediaElement("text", document, new String(getPart().getName()));
|
||||
}
|
||||
|
||||
private static PduPart getPartForMessage(String message) {
|
||||
PduPart part = new PduPart();
|
||||
|
||||
|
|
|
@ -19,18 +19,19 @@ package org.thoughtcrime.securesms.mms;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.SmilUtil;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
|
||||
import ws.com.google.android.mms.pdu.PduPart;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
|
||||
public class VideoSlide extends Slide {
|
||||
|
||||
|
@ -41,7 +42,7 @@ public class VideoSlide extends Slide {
|
|||
public VideoSlide(Context context, Uri uri) throws IOException, MediaTooLargeException {
|
||||
super(context, constructPartFromUri(context, uri));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Drawable getThumbnail(int width, int height) {
|
||||
return context.getResources().getDrawable(R.drawable.ic_launcher_video_player);
|
||||
|
@ -51,12 +52,29 @@ public class VideoSlide extends Slide {
|
|||
public boolean hasImage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasVideo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SMILRegionElement getSmilRegion(SMILDocument document) {
|
||||
SMILRegionElement region = (SMILRegionElement) document.createElement("region");
|
||||
region.setId("Image");
|
||||
region.setLeft(0);
|
||||
region.setTop(0);
|
||||
region.setWidth(SmilUtil.ROOT_WIDTH);
|
||||
region.setHeight(SmilUtil.ROOT_HEIGHT);
|
||||
region.setFit("meet");
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMILMediaElement getMediaElement(SMILDocument document) {
|
||||
return SmilUtil.createMediaElement("video", document, new String(getPart().getName()));
|
||||
}
|
||||
|
||||
private static PduPart constructPartFromUri(Context context, Uri uri) throws IOException, MediaTooLargeException {
|
||||
PduPart part = new PduPart();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
|
75
src/org/thoughtcrime/securesms/util/SmilUtil.java
Normal file
75
src/org/thoughtcrime/securesms/util/SmilUtil.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.dom.smil.SmilDocumentImpl;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.w3c.dom.smil.SMILDocument;
|
||||
import org.w3c.dom.smil.SMILElement;
|
||||
import org.w3c.dom.smil.SMILLayoutElement;
|
||||
import org.w3c.dom.smil.SMILMediaElement;
|
||||
import org.w3c.dom.smil.SMILParElement;
|
||||
import org.w3c.dom.smil.SMILRegionElement;
|
||||
import org.w3c.dom.smil.SMILRegionMediaElement;
|
||||
import org.w3c.dom.smil.SMILRootLayoutElement;
|
||||
|
||||
public class SmilUtil {
|
||||
private static final String TAG = SmilUtil.class.getSimpleName();
|
||||
|
||||
public static final int ROOT_HEIGHT = 1024;
|
||||
public static final int ROOT_WIDTH = 1024;
|
||||
|
||||
public static SMILDocument createSmilDocument(SlideDeck deck) {
|
||||
Log.w(TAG, "Creating SMIL document from SlideDeck.");
|
||||
|
||||
SMILDocument document = new SmilDocumentImpl();
|
||||
|
||||
SMILElement smilElement = (SMILElement) document.createElement("smil");
|
||||
document.appendChild(smilElement);
|
||||
|
||||
SMILElement headElement = (SMILElement) document.createElement("head");
|
||||
smilElement.appendChild(headElement);
|
||||
|
||||
SMILLayoutElement layoutElement = (SMILLayoutElement) document.createElement("layout");
|
||||
headElement.appendChild(layoutElement);
|
||||
|
||||
SMILRootLayoutElement rootLayoutElement = (SMILRootLayoutElement) document.createElement("root-layout");
|
||||
rootLayoutElement.setWidth(ROOT_WIDTH);
|
||||
rootLayoutElement.setHeight(ROOT_HEIGHT);
|
||||
layoutElement.appendChild(rootLayoutElement);
|
||||
|
||||
SMILElement bodyElement = (SMILElement) document.createElement("body");
|
||||
smilElement.appendChild(bodyElement);
|
||||
|
||||
SMILParElement par = (SMILParElement) document.createElement("par");
|
||||
bodyElement.appendChild(par);
|
||||
|
||||
for (Slide slide : deck.getSlides()) {
|
||||
SMILRegionElement regionElement = slide.getSmilRegion(document);
|
||||
SMILMediaElement mediaElement = slide.getMediaElement(document);
|
||||
|
||||
if (regionElement != null) {
|
||||
((SMILRegionMediaElement)mediaElement).setRegion(regionElement);
|
||||
layoutElement.appendChild(regionElement);
|
||||
}
|
||||
par.appendChild(mediaElement);
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static SMILMediaElement createMediaElement(String tag, SMILDocument document, String src) {
|
||||
SMILMediaElement mediaElement = (SMILMediaElement) document.createElement(tag);
|
||||
mediaElement.setSrc(escapeXML(src));
|
||||
return mediaElement;
|
||||
}
|
||||
|
||||
private static String escapeXML(String str) {
|
||||
return str.replaceAll("&","&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll("\"", """)
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue