diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 850def0b79..f486b08f11 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="org.thoughtcrime.securesms"> - + (messageId, threadId); } - public Optional> getNotification(long messageId) { + public Optional getNotification(long messageId) { Cursor cursor = null; try { cursor = rawQuery(RAW_ID_WHERE, new String[] {String.valueOf(messageId)}); if (cursor != null && cursor.moveToNext()) { - PduHeaders headers = new PduHeaders(); - PduHeadersBuilder builder = new PduHeadersBuilder(headers, cursor); - builder.addText(CONTENT_LOCATION, PduHeaders.CONTENT_LOCATION); - builder.addLong(NORMALIZED_DATE_SENT, PduHeaders.DATE); - builder.addLong(EXPIRY, PduHeaders.EXPIRY); - builder.addLong(MESSAGE_SIZE, PduHeaders.MESSAGE_SIZE); - builder.addText(TRANSACTION_ID, PduHeaders.TRANSACTION_ID); - - return Optional.of(new Pair<>(new NotificationInd(headers), - cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID)))); + return Optional.of(new MmsNotificationInfo(cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_LOCATION)), + cursor.getString(cursor.getColumnIndexOrThrow(TRANSACTION_ID)), + cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID)))); } else { return Optional.absent(); } @@ -820,22 +812,21 @@ public class MmsDatabase extends MessagingDatabase { SQLiteDatabase db = databaseHelper.getWritableDatabase(); MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context); long threadId = getThreadIdFor(notification); - PduHeaders headers = notification.getPduHeaders(); ContentValues contentValues = new ContentValues(); ContentValuesBuilder contentBuilder = new ContentValuesBuilder(contentValues); + Log.w(TAG, "Message received type: " + notification.getMessageType()); - Log.w(TAG, "Message received type: " + headers.getOctet(PduHeaders.MESSAGE_TYPE)); - contentBuilder.add(CONTENT_LOCATION, headers.getTextString(PduHeaders.CONTENT_LOCATION)); - contentBuilder.add(DATE_SENT, headers.getLongInteger(PduHeaders.DATE) * 1000L); - contentBuilder.add(EXPIRY, headers.getLongInteger(PduHeaders.EXPIRY)); - contentBuilder.add(MESSAGE_SIZE, headers.getLongInteger(PduHeaders.MESSAGE_SIZE)); - contentBuilder.add(TRANSACTION_ID, headers.getTextString(PduHeaders.TRANSACTION_ID)); - contentBuilder.add(MESSAGE_TYPE, headers.getOctet(PduHeaders.MESSAGE_TYPE)); + contentBuilder.add(CONTENT_LOCATION, notification.getContentLocation()); + contentBuilder.add(DATE_SENT, System.currentTimeMillis()); + contentBuilder.add(EXPIRY, notification.getExpiry()); + contentBuilder.add(MESSAGE_SIZE, notification.getMessageSize()); + contentBuilder.add(TRANSACTION_ID, notification.getTransactionId()); + contentBuilder.add(MESSAGE_TYPE, notification.getMessageType()); - if (headers.getEncodedStringValue(PduHeaders.FROM) != null) { - contentBuilder.add(ADDRESS, headers.getEncodedStringValue(PduHeaders.FROM).getTextString()); + if (notification.getFrom() != null) { + contentBuilder.add(ADDRESS, notification.getFrom().getTextString()); } else { contentBuilder.add(ADDRESS, null); } @@ -852,7 +843,7 @@ public class MmsDatabase extends MessagingDatabase { long messageId = db.insert(TABLE_NAME, null, contentValues); - if (headers.getEncodedStringValue(PduHeaders.FROM) != null) { + if (notification.getFrom() != null) { addressDatabase.insertAddressesForId(messageId, MmsAddresses.forFrom(Util.toIsoString(notification.getFrom().getTextString()))); } @@ -1129,6 +1120,30 @@ public class MmsDatabase extends MessagingDatabase { public static final int DOWNLOAD_APN_UNAVAILABLE = 6; } + public static class MmsNotificationInfo { + private final String contentLocation; + private final String transactionId; + private final int subscriptionId; + + public MmsNotificationInfo(String contentLocation, String transactionId, int subscriptionId) { + this.contentLocation = contentLocation; + this.transactionId = transactionId; + this.subscriptionId = subscriptionId; + } + + public String getContentLocation() { + return contentLocation; + } + + public String getTransactionId() { + return transactionId; + } + + public int getSubscriptionId() { + return subscriptionId; + } + } + public class OutgoingMessageReader { private final OutgoingMediaMessage message; diff --git a/src/org/thoughtcrime/securesms/database/PduHeadersBuilder.java b/src/org/thoughtcrime/securesms/database/PduHeadersBuilder.java deleted file mode 100644 index 7fd1c0494d..0000000000 --- a/src/org/thoughtcrime/securesms/database/PduHeadersBuilder.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.database; - -import android.database.Cursor; -import android.util.Log; - -import ws.com.google.android.mms.InvalidHeaderValueException; -import ws.com.google.android.mms.pdu.CharacterSets; -import ws.com.google.android.mms.pdu.EncodedStringValue; -import ws.com.google.android.mms.pdu.PduHeaders; - -import java.io.UnsupportedEncodingException; - -public class PduHeadersBuilder { - - private final PduHeaders headers; - private final Cursor cursor; - - public PduHeadersBuilder(PduHeaders headers, Cursor cursor) { - this.headers = headers; - this.cursor = cursor; - } - - public PduHeaders getHeaders() { - return headers; - } - - public void addLong(String key, int headersKey) { - int columnIndex = cursor.getColumnIndexOrThrow(key); - - if (!cursor.isNull(columnIndex)) - headers.setLongInteger(cursor.getLong(columnIndex), headersKey); - } - - public void addOctet(String key, int headersKey) throws InvalidHeaderValueException { - int columnIndex = cursor.getColumnIndexOrThrow(key); - - if (!cursor.isNull(columnIndex)) - headers.setOctet(cursor.getInt(columnIndex), headersKey); - } - - public void addText(String key, int headersKey) { - String value = cursor.getString(cursor.getColumnIndexOrThrow(key)); - if (value != null && value.trim().length() > 0) - headers.setTextString(getBytes(value), headersKey); - } - public void add(String key, String charsetKey, int headersKey) { - String value = cursor.getString(cursor.getColumnIndexOrThrow(key)); - - if (value != null && value.trim().length() > 0) { - int charsetValue = cursor.getInt(cursor.getColumnIndexOrThrow(charsetKey)); - EncodedStringValue encodedValue = new EncodedStringValue(charsetValue, getBytes(value)); - headers.setEncodedStringValue(encodedValue, headersKey); - } - } - - private byte[] getBytes(String data) { - try { - return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - Log.e("PduHeadersBuilder", "ISO_8859_1 must be supported!", e); - return new byte[0]; - } - } -} diff --git a/src/org/thoughtcrime/securesms/dom/AttrImpl.java b/src/org/thoughtcrime/securesms/dom/AttrImpl.java deleted file mode 100644 index e13e9e25bf..0000000000 --- a/src/org/thoughtcrime/securesms/dom/AttrImpl.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 Text> 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; - } -} diff --git a/src/org/thoughtcrime/securesms/dom/DocumentImpl.java b/src/org/thoughtcrime/securesms/dom/DocumentImpl.java deleted file mode 100644 index 08816627a7..0000000000 --- a/src/org/thoughtcrime/securesms/dom/DocumentImpl.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/ElementImpl.java b/src/org/thoughtcrime/securesms/dom/ElementImpl.java deleted file mode 100644 index 583858f4ee..0000000000 --- a/src/org/thoughtcrime/securesms/dom/ElementImpl.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/NamedNodeMapImpl.java b/src/org/thoughtcrime/securesms/dom/NamedNodeMapImpl.java deleted file mode 100644 index 9eff2dfe74..0000000000 --- a/src/org/thoughtcrime/securesms/dom/NamedNodeMapImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 mNodes = new Vector(); - - 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; - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/NodeImpl.java b/src/org/thoughtcrime/securesms/dom/NodeImpl.java deleted file mode 100644 index 1b38e63105..0000000000 --- a/src/org/thoughtcrime/securesms/dom/NodeImpl.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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 mChildNodes = new Vector(); - 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 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 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; - } -} diff --git a/src/org/thoughtcrime/securesms/dom/NodeListImpl.java b/src/org/thoughtcrime/securesms/dom/NodeListImpl.java deleted file mode 100644 index 9ac9161587..0000000000 --- a/src/org/thoughtcrime/securesms/dom/NodeListImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 mSearchNodes; - private ArrayList 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 Node 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 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: - * - * Visit root. - * Traverse children from left to right in preorder. - * - * 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(); - } 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(); - } - } -} diff --git a/src/org/thoughtcrime/securesms/dom/events/EventImpl.java b/src/org/thoughtcrime/securesms/dom/events/EventImpl.java deleted file mode 100644 index 24c3ef6282..0000000000 --- a/src/org/thoughtcrime/securesms/dom/events/EventImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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; - } -} diff --git a/src/org/thoughtcrime/securesms/dom/events/EventTargetImpl.java b/src/org/thoughtcrime/securesms/dom/events/EventTargetImpl.java deleted file mode 100644 index b629b6e9ca..0000000000 --- a/src/org/thoughtcrime/securesms/dom/events/EventTargetImpl.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 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(); - } - 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; - } - } - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/ElementParallelTimeContainerImpl.java b/src/org/thoughtcrime/securesms/dom/smil/ElementParallelTimeContainerImpl.java deleted file mode 100644 index 7a1d15d965..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/ElementParallelTimeContainerImpl.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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 activeChildren = new ArrayList(); - 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/ElementSequentialTimeContainerImpl.java b/src/org/thoughtcrime/securesms/dom/smil/ElementSequentialTimeContainerImpl.java deleted file mode 100644 index 5ef5837a07..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/ElementSequentialTimeContainerImpl.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 nodes = new ArrayList(); - 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; - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/ElementTimeContainerImpl.java b/src/org/thoughtcrime/securesms/dom/smil/ElementTimeContainerImpl.java deleted file mode 100644 index 63c64b8603..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/ElementTimeContainerImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/ElementTimeImpl.java b/src/org/thoughtcrime/securesms/dom/smil/ElementTimeImpl.java deleted file mode 100644 index 3c50600056..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/ElementTimeImpl.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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 null 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 beginTimeList = new ArrayList(); - // 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 endTimeList = new ArrayList(); - - 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"); - } - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilDocumentImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilDocumentImpl.java deleted file mode 100644 index a4af0bdd66..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilDocumentImpl.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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 HEAD - 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"); - } - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilElementImpl.java deleted file mode 100644 index f050f46f68..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilElementImpl.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 - - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilLayoutElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilLayoutElementImpl.java deleted file mode 100644 index 102c547643..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilLayoutElementImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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; - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilMediaElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilMediaElementImpl.java deleted file mode 100644 index 71a16d58dd..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilMediaElementImpl.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilParElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilParElementImpl.java deleted file mode 100644 index 71bac5ec85..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilParElementImpl.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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 singleTimeContainer = new ArrayList(); - 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); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilRefElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilRefElementImpl.java deleted file mode 100644 index f2cbfa5d3e..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilRefElementImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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); - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilRegionElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilRegionElementImpl.java deleted file mode 100644 index 8485e1fb6d..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilRegionElementImpl.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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(); - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilRegionMediaElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilRegionMediaElementImpl.java deleted file mode 100644 index 85b5890c3d..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilRegionMediaElementImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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; - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/SmilRootLayoutElementImpl.java b/src/org/thoughtcrime/securesms/dom/smil/SmilRootLayoutElementImpl.java deleted file mode 100644 index 4b59606c94..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/SmilRootLayoutElementImpl.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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; - } - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/TimeImpl.java b/src/org/thoughtcrime/securesms/dom/smil/TimeImpl.java deleted file mode 100644 index 7b525d847d..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/TimeImpl.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * 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: - * - * - * 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 ")" - * - * - * @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 - * null - */ - 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. - * - * Clock values have the following syntax: - * - * - * - * 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] - * - * - * @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 - * null - */ - 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: - * - * - * Value ::= Number ("." Decimal)? (Text)? - * Number ::= DIGIT+; any positive number - * Decimal ::= DIGIT+; any positive number - * Text ::= CHAR*; any sequence of chars - * DIGIT ::= [0-9] - * - * @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 - - } -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/TimeListImpl.java b/src/org/thoughtcrime/securesms/dom/smil/TimeListImpl.java deleted file mode 100644 index 7e809e00e0..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/TimeListImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 mTimes; - - /* - * Internal Interface - */ - TimeListImpl(ArrayList 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; - } - -} diff --git a/src/org/thoughtcrime/securesms/dom/smil/parser/SmilXmlSerializer.java b/src/org/thoughtcrime/securesms/dom/smil/parser/SmilXmlSerializer.java deleted file mode 100644 index 52f6391c62..0000000000 --- a/src/org/thoughtcrime/securesms/dom/smil/parser/SmilXmlSerializer.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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("/>"); - } - } -} - diff --git a/src/org/thoughtcrime/securesms/groups/GroupManager.java b/src/org/thoughtcrime/securesms/groups/GroupManager.java index f2c6ce6bf3..91de70aba3 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/src/org/thoughtcrime/securesms/groups/GroupManager.java @@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.util.BitmapUtil; import org.thoughtcrime.securesms.util.GroupUtil; +import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.api.util.InvalidNumberException; @@ -32,8 +33,6 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.Set; -import ws.com.google.android.mms.ContentType; - public class GroupManager { public static @NonNull GroupActionResult createGroup(@NonNull Context context, @NonNull MasterSecret masterSecret, @@ -104,7 +103,7 @@ public class GroupManager { if (avatar != null) { Uri avatarUri = SingleUseBlobProvider.getInstance().createUri(avatar); - avatarAttachment = new UriAttachment(avatarUri, ContentType.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null); + avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null); } OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0); diff --git a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java index 4b749303b8..544d7c679d 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java +++ b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java @@ -37,7 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; -import ws.com.google.android.mms.MmsException; +import org.thoughtcrime.securesms.mms.MmsException; import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer; diff --git a/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java index 1360a3ab68..ffed1f737a 100644 --- a/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.java @@ -36,7 +36,7 @@ import java.io.InputStream; import javax.inject.Inject; -import ws.com.google.android.mms.MmsException; +import org.thoughtcrime.securesms.mms.MmsException; public class AttachmentDownloadJob extends MasterSecretJob implements InjectableType { private static final long serialVersionUID = 1L; diff --git a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java index 408b1451df..7dfeda0421 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsDownloadJob.java @@ -3,7 +3,12 @@ package org.thoughtcrime.securesms.jobs; import android.content.Context; import android.net.Uri; import android.util.Log; -import android.util.Pair; + +import com.google.android.mms.pdu_alt.CharacterSets; +import com.google.android.mms.pdu_alt.EncodedStringValue; +import com.google.android.mms.pdu_alt.PduBody; +import com.google.android.mms.pdu_alt.PduPart; +import com.google.android.mms.pdu_alt.RetrieveConf; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; @@ -32,16 +37,12 @@ import org.whispersystems.libsignal.NoSessionException; import org.whispersystems.libsignal.util.guava.Optional; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; -import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.EncodedStringValue; -import ws.com.google.android.mms.pdu.NotificationInd; -import ws.com.google.android.mms.pdu.PduBody; -import ws.com.google.android.mms.pdu.PduPart; -import ws.com.google.android.mms.pdu.RetrieveConf; +import org.thoughtcrime.securesms.mms.MmsException; public class MmsDownloadJob extends MasterSecretJob { @@ -75,8 +76,8 @@ public class MmsDownloadJob extends MasterSecretJob { @Override public void onRun(MasterSecret masterSecret) { - MmsDatabase database = DatabaseFactory.getMmsDatabase(context); - Optional> notification = database.getNotification(messageId); + MmsDatabase database = DatabaseFactory.getMmsDatabase(context); + Optional notification = database.getNotification(messageId); if (!notification.isPresent()) { Log.w(TAG, "No notification for ID: " + messageId); @@ -84,24 +85,30 @@ public class MmsDownloadJob extends MasterSecretJob { } try { - if (notification.get().first.getContentLocation() == null) { + if (notification.get().getContentLocation() == null) { throw new MmsException("Notification content location was null."); } database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_CONNECTING); - String contentLocation = new String(notification.get().first.getContentLocation()); - byte[] transactionId = notification.get().first.getTransactionId(); + String contentLocation = notification.get().getContentLocation(); + byte[] transactionId = new byte[0]; + + try { + transactionId = notification.get().getTransactionId().getBytes(CharacterSets.MIMENAME_ISO_8859_1); + } catch (UnsupportedEncodingException e) { + Log.w(TAG, e); + } Log.w(TAG, "Downloading mms at " + Uri.parse(contentLocation).getHost()); - RetrieveConf retrieveConf = new CompatMmsConnection(context).retrieve(contentLocation, transactionId, notification.get().second); + RetrieveConf retrieveConf = new CompatMmsConnection(context).retrieve(contentLocation, transactionId, notification.get().getSubscriptionId()); if (retrieveConf == null) { throw new MmsException("RetrieveConf was null"); } - storeRetrievedMms(masterSecret, contentLocation, messageId, threadId, retrieveConf, notification.get().second); + storeRetrievedMms(masterSecret, contentLocation, messageId, threadId, retrieveConf, notification.get().getSubscriptionId()); } catch (ApnUnavailableException e) { Log.w(TAG, e); handleDownloadError(masterSecret, messageId, threadId, MmsDatabase.Status.DOWNLOAD_APN_UNAVAILABLE, diff --git a/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java b/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java index 7bb413f6e2..c1c19eddc0 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsReceiveJob.java @@ -4,6 +4,11 @@ import android.content.Context; import android.util.Log; import android.util.Pair; +import com.google.android.mms.pdu_alt.GenericPdu; +import com.google.android.mms.pdu_alt.NotificationInd; +import com.google.android.mms.pdu_alt.PduHeaders; +import com.google.android.mms.pdu_alt.PduParser; + import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsDatabase; @@ -12,11 +17,6 @@ import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.jobqueue.JobParameters; -import ws.com.google.android.mms.pdu.GenericPdu; -import ws.com.google.android.mms.pdu.NotificationInd; -import ws.com.google.android.mms.pdu.PduHeaders; -import ws.com.google.android.mms.pdu.PduParser; - public class MmsReceiveJob extends ContextJob { private static final long serialVersionUID = 1L; diff --git a/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java b/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java index 3fe2351630..0435d7a309 100644 --- a/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MmsSendJob.java @@ -3,13 +3,27 @@ package org.thoughtcrime.securesms.jobs; import android.content.Context; import android.text.TextUtils; import android.util.Log; +import android.webkit.MimeTypeMap; + +import com.android.mms.dom.smil.parser.SmilXmlSerializer; +import com.google.android.mms.ContentType; +import com.google.android.mms.InvalidHeaderValueException; +import com.google.android.mms.pdu_alt.CharacterSets; +import com.google.android.mms.pdu_alt.EncodedStringValue; +import com.google.android.mms.pdu_alt.PduBody; +import com.google.android.mms.pdu_alt.PduComposer; +import com.google.android.mms.pdu_alt.PduHeaders; +import com.google.android.mms.pdu_alt.PduPart; +import com.google.android.mms.pdu_alt.SendConf; +import com.google.android.mms.pdu_alt.SendReq; +import com.google.android.mms.smil.SmilHelper; +import com.klinker.android.send_message.Utils; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.NoSuchMessageException; -import org.thoughtcrime.securesms.database.ThreadDatabase.DistributionTypes; import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement; import org.thoughtcrime.securesms.mms.CompatMmsConnection; import org.thoughtcrime.securesms.mms.MediaConstraints; @@ -22,26 +36,16 @@ import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.Hex; import org.thoughtcrime.securesms.util.NumberUtil; -import org.thoughtcrime.securesms.util.SmilUtil; -import org.thoughtcrime.securesms.util.TelephonyUtil; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.jobqueue.JobParameters; import org.whispersystems.jobqueue.requirements.NetworkRequirement; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.CharacterSets; -import ws.com.google.android.mms.pdu.EncodedStringValue; -import ws.com.google.android.mms.pdu.PduBody; -import ws.com.google.android.mms.pdu.PduComposer; -import ws.com.google.android.mms.pdu.PduHeaders; -import ws.com.google.android.mms.pdu.PduPart; -import ws.com.google.android.mms.pdu.SendConf; -import ws.com.google.android.mms.pdu.SendReq; +import org.thoughtcrime.securesms.mms.MmsException; public class MmsSendJob extends SendJob { @@ -64,8 +68,7 @@ public class MmsSendJob extends SendJob { @Override public void onAdded() { -// MmsDatabase database = DatabaseFactory.getMmsDatabase(context); -// database.markAsSending(messageId); + } @Override @@ -109,14 +112,6 @@ public class MmsSendJob extends SendJob { private byte[] getPduBytes(SendReq message) throws IOException, UndeliverableMessageException, InsecureFallbackApprovalException { - String number = TelephonyUtil.getManager(context).getLine1Number(); - - message.setBody(SmilUtil.getSmilBody(message.getBody())); - - if (!TextUtils.isEmpty(number)) { - message.setFrom(new EncodedStringValue(number)); - } - byte[] pduBytes = new PduComposer(context, message).make(); if (pduBytes == null) { @@ -174,51 +169,100 @@ public class MmsSendJob extends SendJob { private SendReq constructSendPdu(MasterSecret masterSecret, OutgoingMediaMessage message) throws UndeliverableMessageException { - SendReq sendReq = new SendReq(); - PduBody body = new PduBody(); - List numbers = message.getRecipients().toNumberStringList(true); + SendReq req = new SendReq(); + String lineNumber = Utils.getMyPhoneNumber(context); + List numbers = message.getRecipients().toNumberStringList(true); + MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(message.getSubscriptionId()); + List scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments()); - for (String number : numbers) { - if (message.getDistributionType() == DistributionTypes.CONVERSATION) { - sendReq.addTo(new EncodedStringValue(Util.toIsoBytes(number))); - } else { - sendReq.addBcc(new EncodedStringValue(Util.toIsoBytes(number))); - } + if (!TextUtils.isEmpty(lineNumber)) { + req.setFrom(new EncodedStringValue(lineNumber)); } - sendReq.setDate(message.getSentTimeMillis() / 1000L); + for (String recipient : numbers) { + req.addTo(new EncodedStringValue(recipient)); + } + + req.setDate(System.currentTimeMillis() / 1000); + + PduBody body = new PduBody(); + int size = 0; if (!TextUtils.isEmpty(message.getBody())) { PduPart part = new PduPart(); + String name = String.valueOf(System.currentTimeMillis()); part.setData(Util.toUtf8Bytes(message.getBody())); part.setCharset(CharacterSets.UTF_8); part.setContentType(ContentType.TEXT_PLAIN.getBytes()); - part.setContentId((System.currentTimeMillis()+"").getBytes()); - part.setName(("Text"+System.currentTimeMillis()).getBytes()); + part.setContentId(name.getBytes()); + part.setContentLocation((name + ".txt").getBytes()); + part.setName((name + ".txt").getBytes()); body.addPart(part); + size += getPartSize(part); } - List scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.MMS_CONSTRAINTS, message.getAttachments()); - for (Attachment attachment : scaledAttachments) { try { if (attachment.getDataUri() == null) throw new IOException("Assertion failed, attachment for outgoing MMS has no data!"); - PduPart part = new PduPart(); + String fileName = attachment.getFileName(); + PduPart part = new PduPart(); + + if (fileName == null) { + fileName = String.valueOf(Math.abs(Util.getSecureRandom().nextLong())); + String fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.getContentType()); + + if (fileExtension != null) fileName = fileName + "." + fileExtension; + } + + if (attachment.getContentType().startsWith("text")) { + part.setCharset(CharacterSets.UTF_8); + } + + part.setContentType(attachment.getContentType().getBytes()); + part.setContentLocation(fileName.getBytes()); + part.setName(fileName.getBytes()); + + int index = fileName.lastIndexOf("."); + String contentId = (index == -1) ? fileName : fileName.substring(0, index); + part.setContentId(contentId.getBytes()); part.setData(Util.readFully(PartAuthority.getAttachmentStream(context, masterSecret, attachment.getDataUri()))); - part.setContentType(Util.toIsoBytes(attachment.getContentType())); - part.setContentId((System.currentTimeMillis() + "").getBytes()); - part.setName((System.currentTimeMillis() + "").getBytes()); body.addPart(part); + size += getPartSize(part); } catch (IOException e) { Log.w(TAG, e); } } - sendReq.setBody(body); - return sendReq; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + SmilXmlSerializer.serialize(SmilHelper.createSmilDocument(body), 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); + + req.setBody(body); + req.setMessageSize(size); + req.setMessageClass(PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes()); + req.setExpiry(7 * 24 * 60 * 60); + + try { + req.setPriority(PduHeaders.PRIORITY_NORMAL); + req.setDeliveryReport(PduHeaders.VALUE_NO); + req.setReadReport(PduHeaders.VALUE_NO); + } catch (InvalidHeaderValueException e) {} + + return req; + } + + private long getPartSize(PduPart part) { + return part.getName().length + part.getContentLocation().length + + part.getContentType().length + part.getData().length + + part.getContentId().length; } private void notifyMediaMessageDeliveryFailed(Context context, long messageId) { diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index a88cf42267..bcb3d8f59f 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -7,7 +7,6 @@ import android.util.Log; import android.util.Pair; import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.attachments.PointerAttachment; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; @@ -77,11 +76,10 @@ import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptM import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import ws.com.google.android.mms.MmsException; +import org.thoughtcrime.securesms.mms.MmsException; public class PushDecryptJob extends ContextJob { diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index b4fe814013..dd9709719c 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.database.documents.NetworkFailure; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement; import org.thoughtcrime.securesms.mms.MediaConstraints; +import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.recipients.Recipient; @@ -40,8 +41,6 @@ import java.util.List; import javax.inject.Inject; -import ws.com.google.android.mms.MmsException; - import static org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory; public class PushGroupSendJob extends PushSendJob implements InjectableType { @@ -139,7 +138,8 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType { SignalServiceMessageSender messageSender = messageSenderFactory.create(); byte[] groupId = GroupUtil.getDecodedId(message.getRecipients().getPrimaryRecipient().getNumber()); Recipients recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false); - List scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.PUSH_CONSTRAINTS, message.getAttachments()); + MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints(); + List scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments()); List attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments); List addresses; diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 4964547827..d0d63ab294 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -32,7 +32,7 @@ import java.util.List; import javax.inject.Inject; -import ws.com.google.android.mms.MmsException; +import org.thoughtcrime.securesms.mms.MmsException; import static org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory; @@ -119,7 +119,8 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { try { SignalServiceAddress address = getPushAddress(message.getRecipients().getPrimaryRecipient().getNumber()); - List scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.PUSH_CONSTRAINTS, message.getAttachments()); + MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints(); + List scaledAttachments = scaleAttachments(masterSecret, mediaConstraints, message.getAttachments()); List attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments); SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder() .withBody(message.getBody()) diff --git a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java index 6462bd3574..78d09612be 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -30,8 +30,6 @@ import java.io.InputStream; import java.util.LinkedList; import java.util.List; -import ws.com.google.android.mms.ContentType; - public abstract class PushSendJob extends SendJob { private static final String TAG = PushSendJob.class.getSimpleName(); diff --git a/src/org/thoughtcrime/securesms/jobs/SendJob.java b/src/org/thoughtcrime/securesms/jobs/SendJob.java index c0c632c8ac..795d4ca128 100644 --- a/src/org/thoughtcrime/securesms/jobs/SendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/SendJob.java @@ -7,23 +7,19 @@ import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.TextSecureExpiredException; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.crypto.MasterSecret; -import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.mms.MediaConstraints; import org.thoughtcrime.securesms.mms.MediaStream; +import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; -import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.jobqueue.JobParameters; import java.io.IOException; -import java.io.InputStream; import java.util.LinkedList; import java.util.List; -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.MmsException; - public abstract class SendJob extends MasterSecretJob { private final static String TAG = SendJob.class.getSimpleName(); diff --git a/src/org/thoughtcrime/securesms/jobs/requirements/MediaNetworkRequirement.java b/src/org/thoughtcrime/securesms/jobs/requirements/MediaNetworkRequirement.java index 24aaa19c7d..cf74676ac2 100644 --- a/src/org/thoughtcrime/securesms/jobs/requirements/MediaNetworkRequirement.java +++ b/src/org/thoughtcrime/securesms/jobs/requirements/MediaNetworkRequirement.java @@ -19,8 +19,6 @@ import org.whispersystems.jobqueue.requirements.Requirement; import java.util.Collections; import java.util.Set; -import ws.com.google.android.mms.ContentType; - public class MediaNetworkRequirement implements Requirement, ContextDependent { private static final long serialVersionUID = 0L; private static final String TAG = MediaNetworkRequirement.class.getSimpleName(); @@ -112,8 +110,8 @@ public class MediaNetworkRequirement implements Requirement, ContextDependent { private boolean isNonDocumentType(String contentType) { return - ContentType.isImageType(contentType) || - ContentType.isVideoType(contentType) || - ContentType.isAudioType(contentType); + MediaUtil.isImageType(contentType) || + MediaUtil.isVideoType(contentType) || + MediaUtil.isAudioType(contentType); } } diff --git a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java index 9488a29e51..cf45e95562 100644 --- a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java +++ b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java @@ -35,7 +35,6 @@ import android.util.Log; import android.view.View; import android.widget.Toast; -import com.bumptech.glide.Glide; import com.google.android.gms.common.GooglePlayServicesNotAvailableException; import com.google.android.gms.common.GooglePlayServicesRepairableException; import com.google.android.gms.location.places.ui.PlacePicker; @@ -67,7 +66,6 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutionException; -import ws.com.google.android.mms.ContentType; public class AttachmentManager { @@ -192,7 +190,7 @@ public class AttachmentManager { public void onSuccess(@NonNull Bitmap result) { byte[] blob = BitmapUtil.toByteArray(result); Uri uri = PersistentBlobProvider.getInstance(context) - .create(masterSecret, blob, ContentType.IMAGE_PNG); + .create(masterSecret, blob, MediaUtil.IMAGE_PNG); LocationSlide locationSlide = new LocationSlide(context, uri, blob.length, place); setSlide(locationSlide); @@ -204,7 +202,8 @@ public class AttachmentManager { public void setMedia(@NonNull final MasterSecret masterSecret, @NonNull final Uri uri, @NonNull final MediaType mediaType, - @NonNull final MediaConstraints constraints) { + @NonNull final MediaConstraints constraints) + { inflateStub(); new AsyncTask() { @@ -350,7 +349,7 @@ public class AttachmentManager { if (captureIntent.resolveActivity(activity.getPackageManager()) != null) { if (captureUri == null) { captureUri = PersistentBlobProvider.getInstance(context) - .createForExternal(ContentType.IMAGE_JPEG); + .createForExternal(MediaUtil.IMAGE_JPEG); } Log.w(TAG, "captureUri path is " + captureUri.getPath()); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, captureUri); @@ -462,11 +461,11 @@ public class AttachmentManager { } public static @Nullable MediaType from(final @Nullable String mimeType) { - if (TextUtils.isEmpty(mimeType)) return null; - if (MediaUtil.isGif(mimeType)) return GIF; - if (ContentType.isImageType(mimeType)) return IMAGE; - if (ContentType.isAudioType(mimeType)) return AUDIO; - if (ContentType.isVideoType(mimeType)) return VIDEO; + if (TextUtils.isEmpty(mimeType)) return null; + if (MediaUtil.isGif(mimeType)) return GIF; + if (MediaUtil.isImageType(mimeType)) return IMAGE; + if (MediaUtil.isAudioType(mimeType)) return AUDIO; + if (MediaUtil.isVideoType(mimeType)) return VIDEO; return null; } diff --git a/src/org/thoughtcrime/securesms/mms/AudioSlide.java b/src/org/thoughtcrime/securesms/mms/AudioSlide.java index 79419af336..0906479376 100644 --- a/src/org/thoughtcrime/securesms/mms/AudioSlide.java +++ b/src/org/thoughtcrime/securesms/mms/AudioSlide.java @@ -27,17 +27,14 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.ResUtil; -import java.io.IOException; - -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.pdu.PduPart; public class AudioSlide extends Slide { public AudioSlide(Context context, Uri uri, long dataSize) { - super(context, constructAttachmentFromUri(context, uri, ContentType.AUDIO_UNSPECIFIED, dataSize, false, null)); + super(context, constructAttachmentFromUri(context, uri, MediaUtil.AUDIO_UNSPECIFIED, dataSize, false, null)); } public AudioSlide(Context context, Uri uri, long dataSize, String contentType) { diff --git a/src/org/thoughtcrime/securesms/mms/CompatMmsConnection.java b/src/org/thoughtcrime/securesms/mms/CompatMmsConnection.java index 080a75f542..1367b7e312 100644 --- a/src/org/thoughtcrime/securesms/mms/CompatMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/CompatMmsConnection.java @@ -1,22 +1,20 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; -import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; +import com.google.android.mms.pdu_alt.PduHeaders; +import com.google.android.mms.pdu_alt.RetrieveConf; +import com.google.android.mms.pdu_alt.SendConf; + import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import java.io.IOException; -import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.PduHeaders; -import ws.com.google.android.mms.pdu.RetrieveConf; -import ws.com.google.android.mms.pdu.SendConf; - public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsConnection { private static final String TAG = CompatMmsConnection.class.getSimpleName(); @@ -31,7 +29,18 @@ public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsCo public SendConf send(@NonNull byte[] pduBytes, int subscriptionId) throws UndeliverableMessageException { - if (subscriptionId == -1 || VERSION.SDK_INT < 22) { + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + try { + Log.w(TAG, "Sending via Lollipop API"); + return new OutgoingLollipopMmsConnection(context).send(pduBytes, subscriptionId); + } catch (UndeliverableMessageException e) { + Log.w(TAG, e); + } + } + + Log.w(TAG, "Falling back to legacy connection..."); + + if (subscriptionId == -1) { Log.w(TAG, "Sending via legacy connection"); try { SendConf result = new OutgoingLegacyMmsConnection(context).send(pduBytes, subscriptionId); @@ -46,11 +55,7 @@ public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsCo } } - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - return new OutgoingLollipopMmsConnection(context).send(pduBytes, subscriptionId); - } else { - throw new UndeliverableMessageException("Lollipop API not available to try..."); - } + throw new UndeliverableMessageException("Both lollipop and legacy connections failed..."); } @Nullable @@ -60,8 +65,13 @@ public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsCo int subscriptionId) throws MmsException, MmsRadioException, ApnUnavailableException, IOException { - if (VERSION.SDK_INT < 22 || subscriptionId == -1) { - Log.w(TAG, "Receiving via legacy connection"); + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + Log.w(TAG, "Receiving via Lollipop API"); + return new IncomingLollipopMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); + } + + if (subscriptionId == -1) { + Log.w(TAG, "Falling back to receiving via legacy connection"); try { return new IncomingLegacyMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); } catch (MmsRadioException | ApnUnavailableException | IOException e) { @@ -69,11 +79,6 @@ public class CompatMmsConnection implements OutgoingMmsConnection, IncomingMmsCo } } - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - Log.w(TAG, "Falling back to try receiving via Lollipop API"); - return new IncomingLollipopMmsConnection(context).retrieve(contentLocation, transactionId, subscriptionId); - } else { - throw new IOException("Not able to use Lollipop APIs, giving up..."); - } + throw new IOException("Both lollipop and fallback APIs failed..."); } } diff --git a/src/org/thoughtcrime/securesms/mms/GifSlide.java b/src/org/thoughtcrime/securesms/mms/GifSlide.java index f7d5acb2ab..df6c5c1da4 100644 --- a/src/org/thoughtcrime/securesms/mms/GifSlide.java +++ b/src/org/thoughtcrime/securesms/mms/GifSlide.java @@ -5,13 +5,7 @@ import android.net.Uri; import android.support.annotation.Nullable; import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.crypto.MasterSecret; - -import java.io.IOException; -import java.io.InputStream; - -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.pdu.PduPart; +import org.thoughtcrime.securesms.util.MediaUtil; public class GifSlide extends ImageSlide { @@ -20,7 +14,7 @@ public class GifSlide extends ImageSlide { } public GifSlide(Context context, Uri uri, long size) { - super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_GIF, size, true, null)); + super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_GIF, size, true, null)); } @Override diff --git a/src/org/thoughtcrime/securesms/mms/ImageSlide.java b/src/org/thoughtcrime/securesms/mms/ImageSlide.java index af0a0690d0..7f3bca1595 100644 --- a/src/org/thoughtcrime/securesms/mms/ImageSlide.java +++ b/src/org/thoughtcrime/securesms/mms/ImageSlide.java @@ -24,8 +24,7 @@ import android.support.annotation.NonNull; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.attachments.Attachment; - -import ws.com.google.android.mms.ContentType; +import org.thoughtcrime.securesms.util.MediaUtil; public class ImageSlide extends Slide { @@ -36,7 +35,7 @@ public class ImageSlide extends Slide { } public ImageSlide(Context context, Uri uri, long size) { - super(context, constructAttachmentFromUri(context, uri, ContentType.IMAGE_JPEG, size, true, null)); + super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_JPEG, size, true, null)); } @Override diff --git a/src/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java b/src/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java index e4ccdb86f9..0eb7bc055a 100644 --- a/src/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/IncomingLegacyMmsConnection.java @@ -22,6 +22,13 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; +import com.google.android.mms.InvalidHeaderValueException; +import com.google.android.mms.pdu_alt.NotifyRespInd; +import com.google.android.mms.pdu_alt.PduComposer; +import com.google.android.mms.pdu_alt.PduHeaders; +import com.google.android.mms.pdu_alt.PduParser; +import com.google.android.mms.pdu_alt.RetrieveConf; + import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -31,12 +38,6 @@ import org.apache.http.client.methods.HttpUriRequest; import java.io.IOException; import java.util.Arrays; -import ws.com.google.android.mms.InvalidHeaderValueException; -import ws.com.google.android.mms.pdu.NotifyRespInd; -import ws.com.google.android.mms.pdu.PduComposer; -import ws.com.google.android.mms.pdu.PduHeaders; -import ws.com.google.android.mms.pdu.PduParser; -import ws.com.google.android.mms.pdu.RetrieveConf; @SuppressWarnings("deprecation") public class IncomingLegacyMmsConnection extends LegacyMmsConnection implements IncomingMmsConnection { diff --git a/src/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java b/src/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java index 984c0b2f35..608ac2f739 100644 --- a/src/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java @@ -26,18 +26,16 @@ import android.support.annotation.Nullable; import android.telephony.SmsManager; import android.util.Log; +import com.google.android.mms.pdu_alt.PduParser; +import com.google.android.mms.pdu_alt.RetrieveConf; + import org.thoughtcrime.securesms.providers.MmsBodyProvider; -import org.thoughtcrime.securesms.util.Hex; import org.thoughtcrime.securesms.util.Util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.concurrent.TimeoutException; -import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.PduParser; -import ws.com.google.android.mms.pdu.RetrieveConf; - public class IncomingLollipopMmsConnection extends LollipopMmsConnection implements IncomingMmsConnection { public static final String ACTION = IncomingLollipopMmsConnection.class.getCanonicalName() + "MMS_DOWNLOADED_ACTION"; @@ -89,7 +87,7 @@ public class IncomingLollipopMmsConnection extends LollipopMmsConnection impleme Util.copy(pointer.getInputStream(), baos); pointer.close(); - Log.w(TAG, baos.size() + "-byte response: " + Hex.dump(baos.toByteArray())); + Log.w(TAG, baos.size() + "-byte response: ");// + Hex.dump(baos.toByteArray())); return (RetrieveConf) new PduParser(baos.toByteArray()).parse(); } catch (IOException | TimeoutException e) { diff --git a/src/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java b/src/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java index d29724511b..96527e5162 100644 --- a/src/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java @@ -3,11 +3,11 @@ package org.thoughtcrime.securesms.mms; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.google.android.mms.pdu_alt.RetrieveConf; + import java.io.IOException; -import ws.com.google.android.mms.MmsException; -import ws.com.google.android.mms.pdu.RetrieveConf; - public interface IncomingMmsConnection { - @Nullable RetrieveConf retrieve(@NonNull String contentLocation, byte[] transactionId, int subscriptionId) throws MmsException, MmsRadioException, ApnUnavailableException, IOException; + @Nullable + RetrieveConf retrieve(@NonNull String contentLocation, byte[] transactionId, int subscriptionId) throws MmsException, MmsRadioException, ApnUnavailableException, IOException; } diff --git a/src/org/thoughtcrime/securesms/mms/MediaConstraints.java b/src/org/thoughtcrime/securesms/mms/MediaConstraints.java index ecee9337b7..9b965c1692 100644 --- a/src/org/thoughtcrime/securesms/mms/MediaConstraints.java +++ b/src/org/thoughtcrime/securesms/mms/MediaConstraints.java @@ -18,33 +18,33 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import ws.com.google.android.mms.ContentType; - public abstract class MediaConstraints { private static final String TAG = MediaConstraints.class.getSimpleName(); - public static MediaConstraints MMS_CONSTRAINTS = new MmsMediaConstraints(); - public static MediaConstraints PUSH_CONSTRAINTS = new PushMediaConstraints(); + public static MediaConstraints getPushMediaConstraints() { + return new PushMediaConstraints(); + } + + public static MediaConstraints getMmsMediaConstraints(int subscriptionId) { + return new MmsMediaConstraints(subscriptionId); + } public abstract int getImageMaxWidth(Context context); public abstract int getImageMaxHeight(Context context); - public abstract int getImageMaxSize(); + public abstract int getImageMaxSize(Context context); - public abstract int getGifMaxSize(); - - public abstract int getVideoMaxSize(); - - public abstract int getAudioMaxSize(); - - public abstract int getDocumentMaxSize(); + public abstract int getGifMaxSize(Context context); + public abstract int getVideoMaxSize(Context context); + public abstract int getAudioMaxSize(Context context); + public abstract int getDocumentMaxSize(Context context); public boolean isSatisfied(@NonNull Context context, @NonNull MasterSecret masterSecret, @NonNull Attachment attachment) { try { - return (MediaUtil.isGif(attachment) && attachment.getSize() <= getGifMaxSize() && isWithinBounds(context, masterSecret, attachment.getDataUri())) || - (MediaUtil.isImage(attachment) && attachment.getSize() <= getImageMaxSize() && isWithinBounds(context, masterSecret, attachment.getDataUri())) || - (MediaUtil.isAudio(attachment) && attachment.getSize() <= getAudioMaxSize()) || - (MediaUtil.isVideo(attachment) && attachment.getSize() <= getVideoMaxSize()) || - (MediaUtil.isFile(attachment) && attachment.getSize() <= getDocumentMaxSize()); + return (MediaUtil.isGif(attachment) && attachment.getSize() <= getGifMaxSize(context) && isWithinBounds(context, masterSecret, attachment.getDataUri())) || + (MediaUtil.isImage(attachment) && attachment.getSize() <= getImageMaxSize(context) && isWithinBounds(context, masterSecret, attachment.getDataUri())) || + (MediaUtil.isAudio(attachment) && attachment.getSize() <= getAudioMaxSize(context)) || + (MediaUtil.isVideo(attachment) && attachment.getSize() <= getVideoMaxSize(context)) || + (MediaUtil.isFile(attachment) && attachment.getSize() <= getDocumentMaxSize(context)); } catch (IOException ioe) { Log.w(TAG, "Failed to determine if media's constraints are satisfied.", ioe); return false; @@ -78,7 +78,7 @@ public abstract class MediaConstraints { try { // XXX - This is loading everything into memory! We want the send path to be stream-like. return new MediaStream(new ByteArrayInputStream(BitmapUtil.createScaledBytes(context, new DecryptableUri(masterSecret, attachment.getDataUri()), this)), - ContentType.IMAGE_JPEG); + MediaUtil.IMAGE_JPEG); } catch (BitmapDecodingException e) { throw new IOException(e); } diff --git a/src/org/thoughtcrime/securesms/mms/MmsConfigManager.java b/src/org/thoughtcrime/securesms/mms/MmsConfigManager.java new file mode 100644 index 0000000000..9f607e597b --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/MmsConfigManager.java @@ -0,0 +1,53 @@ +package org.thoughtcrime.securesms.mms; + + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.support.annotation.Nullable; +import android.support.annotation.WorkerThread; + +import com.android.mms.service_alt.MmsConfig; + +import org.thoughtcrime.securesms.util.dualsim.SubscriptionInfoCompat; +import org.thoughtcrime.securesms.util.dualsim.SubscriptionManagerCompat; +import org.whispersystems.libsignal.util.guava.Optional; + +import java.util.HashMap; +import java.util.Map; + +public class MmsConfigManager { + + private static Map mmsConfigMap = new HashMap<>(); + + @WorkerThread + public synchronized static @Nullable MmsConfig getMmsConfig(Context context, int subscriptionId) { + if (mmsConfigMap.containsKey(subscriptionId)) { + return mmsConfigMap.get(subscriptionId); + } + + MmsConfig loadedConfig = loadMmsConfig(context, subscriptionId); + + if (loadedConfig != null) mmsConfigMap.put(subscriptionId, loadedConfig); + + return loadedConfig; + } + + private static MmsConfig loadMmsConfig(Context context, int subscriptionId) { + if (subscriptionId != -1 && Build.VERSION.SDK_INT >= 24) { + Optional subscriptionInfo = new SubscriptionManagerCompat(context).getActiveSubscriptionInfo(subscriptionId); + + if (subscriptionInfo.isPresent()) { + Configuration configuration = context.getResources().getConfiguration(); + configuration.mcc = subscriptionInfo.get().getMcc(); + configuration.mnc = subscriptionInfo.get().getMnc(); + + Context subcontext = context.createConfigurationContext(configuration); + return new MmsConfig(subcontext, subscriptionId); + } + } + + return new MmsConfig(context, subscriptionId); + } + +} diff --git a/src/org/thoughtcrime/securesms/mms/MmsException.java b/src/org/thoughtcrime/securesms/mms/MmsException.java new file mode 100644 index 0000000000..6aaa40b14f --- /dev/null +++ b/src/org/thoughtcrime/securesms/mms/MmsException.java @@ -0,0 +1,60 @@ +/* + * 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.mms; + +/** + * A generic exception that is thrown by the Mms client. + */ +public class MmsException extends Exception { + private static final long serialVersionUID = -7323249827281485390L; + + /** + * Creates a new MmsException. + */ + public MmsException() { + super(); + } + + /** + * Creates a new MmsException with the specified detail message. + * + * @param message the detail message. + */ + public MmsException(String message) { + super(message); + } + + /** + * Creates a new MmsException with the specified cause. + * + * @param cause the cause. + */ + public MmsException(Throwable cause) { + super(cause); + } + + /** + * Creates a new MmsException with the specified detail message and cause. + * + * @param message the detail message. + * @param cause the cause. + */ + public MmsException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/org/thoughtcrime/securesms/mms/MmsMediaConstraints.java b/src/org/thoughtcrime/securesms/mms/MmsMediaConstraints.java index 55bda06fa3..4a90313909 100644 --- a/src/org/thoughtcrime/securesms/mms/MmsMediaConstraints.java +++ b/src/org/thoughtcrime/securesms/mms/MmsMediaConstraints.java @@ -1,46 +1,78 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; +import android.os.Bundle; -import org.thoughtcrime.securesms.util.Util; +import com.android.mms.service_alt.MmsConfig; -public class MmsMediaConstraints extends MediaConstraints { - private static final int MAX_IMAGE_DIMEN_LOWMEM = 768; - private static final int MAX_IMAGE_DIMEN = 1024; - public static final int MAX_MESSAGE_SIZE = 280 * 1024; +class MmsMediaConstraints extends MediaConstraints { + + private static final int DEFAULT_MAX_IMAGE_DIMEN = 1024; + private static final int DEFAULT_MAX_MESSAGE_SIZE = 280 * 1024; + + private final int subscriptionId; + + MmsMediaConstraints(int subscriptionId) { + this.subscriptionId = subscriptionId; + } @Override public int getImageMaxWidth(Context context) { - return Util.isLowMemory(context) ? MAX_IMAGE_DIMEN_LOWMEM : MAX_IMAGE_DIMEN; + MmsConfig mmsConfig = MmsConfigManager.getMmsConfig(context, subscriptionId); + + if (mmsConfig != null) { + MmsConfig.Overridden overridden = new MmsConfig.Overridden(mmsConfig, new Bundle()); + return overridden.getMaxImageWidth(); + } + + return DEFAULT_MAX_IMAGE_DIMEN; } @Override public int getImageMaxHeight(Context context) { - return getImageMaxWidth(context); + MmsConfig mmsConfig = MmsConfigManager.getMmsConfig(context, subscriptionId); + + if (mmsConfig != null) { + MmsConfig.Overridden overridden = new MmsConfig.Overridden(mmsConfig, new Bundle()); + return overridden.getMaxImageHeight(); + } + + return DEFAULT_MAX_IMAGE_DIMEN; } @Override - public int getImageMaxSize() { - return MAX_MESSAGE_SIZE; + public int getImageMaxSize(Context context) { + return getMaxMessageSize(context); } @Override - public int getGifMaxSize() { - return MAX_MESSAGE_SIZE; + public int getGifMaxSize(Context context) { + return getMaxMessageSize(context); } @Override - public int getVideoMaxSize() { - return MAX_MESSAGE_SIZE; + public int getVideoMaxSize(Context context) { + return getMaxMessageSize(context); } @Override - public int getAudioMaxSize() { - return MAX_MESSAGE_SIZE; + public int getAudioMaxSize(Context context) { + return getMaxMessageSize(context); } @Override - public int getDocumentMaxSize() { - return MAX_MESSAGE_SIZE; + public int getDocumentMaxSize(Context context) { + return getMaxMessageSize(context); + } + + private int getMaxMessageSize(Context context) { + MmsConfig mmsConfig = MmsConfigManager.getMmsConfig(context, subscriptionId); + + if (mmsConfig != null) { + MmsConfig.Overridden overridden = new MmsConfig.Overridden(mmsConfig, new Bundle()); + return overridden.getMaxMessageSize(); + } + + return DEFAULT_MAX_MESSAGE_SIZE; } } diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java b/src/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java index 2ac7c241ab..4d9f364585 100644 --- a/src/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/OutgoingLegacyMmsConnection.java @@ -24,6 +24,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; +import com.google.android.mms.pdu_alt.PduParser; +import com.google.android.mms.pdu_alt.SendConf; + import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -34,8 +37,6 @@ import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import java.io.IOException; -import ws.com.google.android.mms.pdu.PduParser; -import ws.com.google.android.mms.pdu.SendConf; @SuppressWarnings("deprecation") public class OutgoingLegacyMmsConnection extends LegacyMmsConnection implements OutgoingMmsConnection { diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java b/src/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java index d6c2e0740f..7876962d51 100644 --- a/src/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java @@ -21,11 +21,16 @@ import android.content.Context; import android.content.Intent; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.telephony.SmsManager; import android.util.Log; +import com.android.mms.service_alt.MmsConfig; +import com.google.android.mms.pdu_alt.PduParser; +import com.google.android.mms.pdu_alt.SendConf; + import org.thoughtcrime.securesms.providers.MmsBodyProvider; import org.thoughtcrime.securesms.transport.UndeliverableMessageException; import org.thoughtcrime.securesms.util.Util; @@ -34,9 +39,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.concurrent.TimeoutException; -import ws.com.google.android.mms.pdu.PduParser; -import ws.com.google.android.mms.pdu.SendConf; - public class OutgoingLollipopMmsConnection extends LollipopMmsConnection implements OutgoingMmsConnection { private static final String TAG = OutgoingLollipopMmsConnection.class.getSimpleName(); private static final String ACTION = OutgoingLollipopMmsConnection.class.getCanonicalName() + "MMS_SENT_ACTION"; @@ -75,10 +77,21 @@ public class OutgoingLollipopMmsConnection extends LollipopMmsConnection impleme smsManager = SmsManager.getDefault(); } + Bundle configOverrides = new Bundle(); + configOverrides.putBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED, true); + + MmsConfig mmsConfig = MmsConfigManager.getMmsConfig(getContext(), subscriptionId); + + if (mmsConfig != null) { + MmsConfig.Overridden overridden = new MmsConfig.Overridden(mmsConfig, new Bundle()); + configOverrides.putString(SmsManager.MMS_CONFIG_HTTP_PARAMS, overridden.getHttpParams()); + configOverrides.putInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE, overridden.getMaxMessageSize()); + } + smsManager.sendMultimediaMessage(getContext(), pointer.getUri(), null, - null, + configOverrides, getPendingIntent()); waitForResult(); diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java b/src/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java index 64a3c58a99..4e1fce4aca 100644 --- a/src/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java +++ b/src/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java @@ -3,10 +3,12 @@ package org.thoughtcrime.securesms.mms; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.google.android.mms.pdu_alt.SendConf; + import org.thoughtcrime.securesms.transport.UndeliverableMessageException; -import ws.com.google.android.mms.pdu.SendConf; public interface OutgoingMmsConnection { - @Nullable SendConf send(@NonNull byte[] pduBytes, int subscriptionId) throws UndeliverableMessageException; + @Nullable + SendConf send(@NonNull byte[] pduBytes, int subscriptionId) throws UndeliverableMessageException; } diff --git a/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java b/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java index e6567c6197..f93a124d11 100644 --- a/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java +++ b/src/org/thoughtcrime/securesms/mms/OutgoingSecureMediaMessage.java @@ -1,14 +1,10 @@ package org.thoughtcrime.securesms.mms; -import android.content.Context; - import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.recipients.Recipients; import java.util.List; -import ws.com.google.android.mms.pdu.PduBody; - public class OutgoingSecureMediaMessage extends OutgoingMediaMessage { public OutgoingSecureMediaMessage(Recipients recipients, String body, diff --git a/src/org/thoughtcrime/securesms/mms/PartParser.java b/src/org/thoughtcrime/securesms/mms/PartParser.java index 050b5559f2..e0fc12d36a 100644 --- a/src/org/thoughtcrime/securesms/mms/PartParser.java +++ b/src/org/thoughtcrime/securesms/mms/PartParser.java @@ -2,14 +2,15 @@ package org.thoughtcrime.securesms.mms; import android.util.Log; +import com.google.android.mms.ContentType; +import com.google.android.mms.pdu_alt.CharacterSets; +import com.google.android.mms.pdu_alt.PduBody; +import com.google.android.mms.pdu_alt.PduPart; + import org.thoughtcrime.securesms.util.Util; import java.io.UnsupportedEncodingException; -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 PartParser { public static String getMessageText(PduBody body) { diff --git a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java index b916e1b6b2..30a6b1ea18 100644 --- a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java +++ b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java @@ -5,6 +5,7 @@ import android.content.Context; import org.thoughtcrime.securesms.util.Util; public class PushMediaConstraints extends MediaConstraints { + private static final int MAX_IMAGE_DIMEN_LOWMEM = 768; private static final int MAX_IMAGE_DIMEN = 4096; private static final int KB = 1024; @@ -21,27 +22,27 @@ public class PushMediaConstraints extends MediaConstraints { } @Override - public int getImageMaxSize() { + public int getImageMaxSize(Context context) { return 6 * MB; } @Override - public int getGifMaxSize() { + public int getGifMaxSize(Context context) { return 25 * MB; } @Override - public int getVideoMaxSize() { + public int getVideoMaxSize(Context context) { return 100 * MB; } @Override - public int getAudioMaxSize() { + public int getAudioMaxSize(Context context) { return 100 * MB; } @Override - public int getDocumentMaxSize() { + public int getDocumentMaxSize(Context context) { return 100 * MB; } } diff --git a/src/org/thoughtcrime/securesms/mms/VideoSlide.java b/src/org/thoughtcrime/securesms/mms/VideoSlide.java index 2b24701d6d..cf51b5797c 100644 --- a/src/org/thoughtcrime/securesms/mms/VideoSlide.java +++ b/src/org/thoughtcrime/securesms/mms/VideoSlide.java @@ -27,12 +27,10 @@ import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.ResUtil; -import ws.com.google.android.mms.ContentType; - public class VideoSlide extends Slide { public VideoSlide(Context context, Uri uri, long dataSize) { - super(context, constructAttachmentFromUri(context, uri, ContentType.VIDEO_UNSPECIFIED, dataSize, MediaUtil.hasVideoThumbnail(uri), null)); + super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize, MediaUtil.hasVideoThumbnail(uri), null)); } public VideoSlide(Context context, Attachment attachment) { diff --git a/src/org/thoughtcrime/securesms/scribbles/ScribbleActivity.java b/src/org/thoughtcrime/securesms/scribbles/ScribbleActivity.java index ecc4ef5bf2..ff986c56aa 100644 --- a/src/org/thoughtcrime/securesms/scribbles/ScribbleActivity.java +++ b/src/org/thoughtcrime/securesms/scribbles/ScribbleActivity.java @@ -28,14 +28,13 @@ import org.thoughtcrime.securesms.scribbles.widget.VerticalSlideColorPicker; import org.thoughtcrime.securesms.scribbles.widget.entity.ImageEntity; import org.thoughtcrime.securesms.scribbles.widget.entity.MotionEntity; import org.thoughtcrime.securesms.scribbles.widget.entity.TextEntity; +import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.concurrent.ListenableFuture; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.concurrent.ExecutionException; -import ws.com.google.android.mms.ContentType; - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class ScribbleActivity extends PassphraseRequiredActionBarActivity implements ScribbleToolbar.ScribbleToolbarListener, VerticalSlideColorPicker.OnColorChangeListener { @@ -230,7 +229,7 @@ public class ScribbleActivity extends PassphraseRequiredActionBarActivity implem baos = null; result = null; - Uri uri = provider.create(masterSecret, data, ContentType.IMAGE_JPEG); + Uri uri = provider.create(masterSecret, data, MediaUtil.IMAGE_JPEG); Intent intent = new Intent(); intent.setData(uri); setResult(RESULT_OK, intent); diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 80674b7baa..be4f99c91c 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -52,7 +52,7 @@ import org.whispersystems.signalservice.api.util.InvalidNumberException; import java.io.IOException; -import ws.com.google.android.mms.MmsException; +import org.thoughtcrime.securesms.mms.MmsException; public class MessageSender { diff --git a/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/src/org/thoughtcrime/securesms/util/BitmapUtil.java index bf13ad851d..62f8a54913 100644 --- a/src/org/thoughtcrime/securesms/util/BitmapUtil.java +++ b/src/org/thoughtcrime/securesms/util/BitmapUtil.java @@ -72,14 +72,14 @@ public class BitmapUtil { Log.w(TAG, "iteration with quality " + quality + " size " + (bytes.length / 1024) + "kb"); if (quality == MIN_COMPRESSION_QUALITY) break; - int nextQuality = (int)Math.floor(quality * Math.sqrt((double)constraints.getImageMaxSize() / bytes.length)); + int nextQuality = (int)Math.floor(quality * Math.sqrt((double)constraints.getImageMaxSize(context) / bytes.length)); if (quality - nextQuality < MIN_COMPRESSION_QUALITY_DECREASE) { nextQuality = quality - MIN_COMPRESSION_QUALITY_DECREASE; } quality = Math.max(nextQuality, MIN_COMPRESSION_QUALITY); } - while (bytes.length > constraints.getImageMaxSize() && attempts++ < MAX_COMPRESSION_ATTEMPTS); - if (bytes.length > constraints.getImageMaxSize()) { + while (bytes.length > constraints.getImageMaxSize(context) && attempts++ < MAX_COMPRESSION_ATTEMPTS); + if (bytes.length > constraints.getImageMaxSize(context)) { throw new BitmapDecodingException("Unable to scale image below: " + bytes.length); } Log.w(TAG, "createScaledBytes(" + model.toString() + ") -> quality " + Math.min(quality, MAX_COMPRESSION_QUALITY) + ", " + attempts + " attempt(s)"); diff --git a/src/org/thoughtcrime/securesms/util/MediaUtil.java b/src/org/thoughtcrime/securesms/util/MediaUtil.java index 41cb601616..6a6da5de99 100644 --- a/src/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/src/org/thoughtcrime/securesms/util/MediaUtil.java @@ -31,19 +31,25 @@ import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutionException; -import ws.com.google.android.mms.ContentType; - public class MediaUtil { private static final String TAG = MediaUtil.class.getSimpleName(); + public static final String IMAGE_PNG = "image/png"; + public static final String IMAGE_JPEG = "image/jpeg"; + public static final String IMAGE_GIF = "image/gif"; + public static final String AUDIO_AAC = "audio/aac"; + public static final String AUDIO_UNSPECIFIED = "audio/*"; + public static final String VIDEO_UNSPECIFIED = "video/*"; + + public static @Nullable ThumbnailData generateThumbnail(Context context, MasterSecret masterSecret, String contentType, Uri uri) throws BitmapDecodingException { long startMillis = System.currentTimeMillis(); ThumbnailData data = null; - if (ContentType.isImageType(contentType)) { + if (isImageType(contentType)) { data = new ThumbnailData(generateImageThumbnail(context, masterSecret, uri)); } @@ -77,11 +83,11 @@ public class MediaUtil { Slide slide = null; if (isGif(attachment.getContentType())) { slide = new GifSlide(context, attachment); - } else if (ContentType.isImageType(attachment.getContentType())) { + } else if (isImageType(attachment.getContentType())) { slide = new ImageSlide(context, attachment); - } else if (ContentType.isVideoType(attachment.getContentType())) { + } else if (isVideoType(attachment.getContentType())) { slide = new VideoSlide(context, attachment); - } else if (ContentType.isAudioType(attachment.getContentType())) { + } else if (isAudioType(attachment.getContentType())) { slide = new AudioSlide(context, attachment); } else if (isMms(attachment.getContentType())) { slide = new MmsSlide(context, attachment); @@ -112,8 +118,8 @@ public class MediaUtil { switch(mimeType) { case "image/jpg": - return MimeTypeMap.getSingleton().hasMimeType(ContentType.IMAGE_JPEG) - ? ContentType.IMAGE_JPEG + return MimeTypeMap.getSingleton().hasMimeType(IMAGE_JPEG) + ? IMAGE_JPEG : mimeType; default: return mimeType; @@ -140,34 +146,50 @@ public class MediaUtil { return !TextUtils.isEmpty(contentType) && contentType.trim().equals("application/mms"); } - public static boolean isGif(String contentType) { - return !TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif"); - } - public static boolean isGif(Attachment attachment) { return isGif(attachment.getContentType()); } public static boolean isImage(Attachment attachment) { - return ContentType.isImageType(attachment.getContentType()); + return isImageType(attachment.getContentType()); } public static boolean isAudio(Attachment attachment) { - return ContentType.isAudioType(attachment.getContentType()); + return isAudioType(attachment.getContentType()); } public static boolean isVideo(Attachment attachment) { - return ContentType.isVideoType(attachment.getContentType()); + return isVideoType(attachment.getContentType()); } public static boolean isVideo(String contentType) { return !TextUtils.isEmpty(contentType) && contentType.trim().startsWith("video/"); } + public static boolean isGif(String contentType) { + return !TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif"); + } + public static boolean isFile(Attachment attachment) { return !isGif(attachment) && !isImage(attachment) && !isAudio(attachment) && !isVideo(attachment); } + public static boolean isTextType(String contentType) { + return (null != contentType) && contentType.startsWith("text/"); + } + + public static boolean isImageType(String contentType) { + return (null != contentType) && contentType.startsWith("image/"); + } + + public static boolean isAudioType(String contentType) { + return (null != contentType) && contentType.startsWith("audio/"); + } + + public static boolean isVideoType(String contentType) { + return (null != contentType) && contentType.startsWith("video/"); + } + public static boolean hasVideoThumbnail(Uri uri) { Log.w(TAG, "Checking: " + uri); diff --git a/src/org/thoughtcrime/securesms/util/SmilUtil.java b/src/org/thoughtcrime/securesms/util/SmilUtil.java deleted file mode 100644 index 59599bdd1a..0000000000 --- a/src/org/thoughtcrime/securesms/util/SmilUtil.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.thoughtcrime.securesms.util; - -import android.util.Log; - -import org.thoughtcrime.securesms.dom.smil.SmilDocumentImpl; -import org.thoughtcrime.securesms.dom.smil.parser.SmilXmlSerializer; -import org.thoughtcrime.securesms.mms.PartParser; -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; - -import java.io.ByteArrayOutputStream; - -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.pdu.PduBody; -import ws.com.google.android.mms.pdu.PduPart; - -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 PduBody getSmilBody(PduBody body) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - SmilXmlSerializer.serialize(SmilUtil.createSmilDocument(body), 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; - } - - private static SMILDocument createSmilDocument(PduBody body) { - Log.w(TAG, "Creating SMIL document from PduBody."); - - 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 (int i=0; i", ">") - .replaceAll("\"", """) - .replaceAll("'", "'"); - } -} diff --git a/src/org/thoughtcrime/securesms/util/Util.java b/src/org/thoughtcrime/securesms/util/Util.java index 7b8f959f95..0848bd9ea2 100644 --- a/src/org/thoughtcrime/securesms/util/Util.java +++ b/src/org/thoughtcrime/securesms/util/Util.java @@ -40,6 +40,8 @@ import android.text.style.StyleSpan; import android.util.Log; import android.widget.EditText; +import com.google.android.mms.pdu_alt.CharacterSets; +import com.google.android.mms.pdu_alt.EncodedStringValue; import com.google.i18n.phonenumbers.PhoneNumberUtil; import org.thoughtcrime.securesms.BuildConfig; @@ -65,9 +67,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import ws.com.google.android.mms.pdu.CharacterSets; -import ws.com.google.android.mms.pdu.EncodedStringValue; - public class Util { private static final String TAG = Util.class.getSimpleName(); diff --git a/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionInfoCompat.java b/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionInfoCompat.java index 59ba5e399a..f3ef15f413 100644 --- a/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionInfoCompat.java +++ b/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionInfoCompat.java @@ -6,11 +6,15 @@ import android.support.annotation.Nullable; public class SubscriptionInfoCompat { private final int subscriptionId; + private final int mcc; + private final int mnc; private final @Nullable CharSequence displayName; - public SubscriptionInfoCompat(int subscriptionId, @Nullable CharSequence displayName) { + public SubscriptionInfoCompat(int subscriptionId, @Nullable CharSequence displayName, int mcc, int mnc) { this.subscriptionId = subscriptionId; this.displayName = displayName; + this.mcc = mcc; + this.mnc = mnc; } public @NonNull CharSequence getDisplayName() { @@ -20,4 +24,12 @@ public class SubscriptionInfoCompat { public int getSubscriptionId() { return subscriptionId; } + + public int getMnc() { + return mnc; + } + + public int getMcc() { + return mcc; + } } diff --git a/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionManagerCompat.java b/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionManagerCompat.java index 586182e3b0..3d358afee0 100644 --- a/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionManagerCompat.java +++ b/src/org/thoughtcrime/securesms/util/dualsim/SubscriptionManagerCompat.java @@ -35,7 +35,8 @@ public class SubscriptionManagerCompat { SubscriptionInfo subscriptionInfo = SubscriptionManager.from(context).getActiveSubscriptionInfo(subscriptionId); if (subscriptionInfo != null) { - return Optional.of(new SubscriptionInfoCompat(subscriptionId, subscriptionInfo.getDisplayName())); + return Optional.of(new SubscriptionInfoCompat(subscriptionId, subscriptionInfo.getDisplayName(), + subscriptionInfo.getMcc(), subscriptionInfo.getMnc())); } else { return Optional.absent(); } @@ -56,7 +57,9 @@ public class SubscriptionManagerCompat { for (SubscriptionInfo subscriptionInfo : subscriptionInfos) { compatList.add(new SubscriptionInfoCompat(subscriptionInfo.getSubscriptionId(), - subscriptionInfo.getDisplayName())); + subscriptionInfo.getDisplayName(), + subscriptionInfo.getMcc(), + subscriptionInfo.getMnc())); } return compatList; diff --git a/src/ws/com/google/android/mms/ContentType.java b/src/ws/com/google/android/mms/ContentType.java deleted file mode 100644 index 862dd5aca6..0000000000 --- a/src/ws/com/google/android/mms/ContentType.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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 ws.com.google.android.mms; - -import java.util.ArrayList; - -public class ContentType { - public static final String MMS_MESSAGE = "application/vnd.wap.mms-message"; - // The phony content type for generic PDUs (e.g. ReadOrig.ind, - // Notification.ind, Delivery.ind). - public static final String MMS_GENERIC = "application/vnd.wap.mms-generic"; - public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed"; - public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related"; - public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative"; - - public static final String TEXT_PLAIN = "text/plain"; - public static final String TEXT_HTML = "text/html"; - public static final String TEXT_VCALENDAR = "text/x-vCalendar"; - public static final String TEXT_VCARD = "text/x-vCard"; - - public static final String IMAGE_UNSPECIFIED = "image/*"; - public static final String IMAGE_JPEG = "image/jpeg"; - public static final String IMAGE_JPG = "image/jpg"; - public static final String IMAGE_GIF = "image/gif"; - public static final String IMAGE_WBMP = "image/vnd.wap.wbmp"; - public static final String IMAGE_PNG = "image/png"; - public static final String IMAGE_X_MS_BMP = "image/x-ms-bmp"; - - public static final String AUDIO_UNSPECIFIED = "audio/*"; - public static final String AUDIO_AAC = "audio/aac"; - public static final String AUDIO_AMR = "audio/amr"; - public static final String AUDIO_IMELODY = "audio/imelody"; - public static final String AUDIO_MID = "audio/mid"; - public static final String AUDIO_MIDI = "audio/midi"; - public static final String AUDIO_MP3 = "audio/mp3"; - public static final String AUDIO_MPEG3 = "audio/mpeg3"; - public static final String AUDIO_MPEG = "audio/mpeg"; - public static final String AUDIO_MPG = "audio/mpg"; - public static final String AUDIO_MP4 = "audio/mp4"; - public static final String AUDIO_X_MID = "audio/x-mid"; - public static final String AUDIO_X_MIDI = "audio/x-midi"; - public static final String AUDIO_X_MP3 = "audio/x-mp3"; - public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3"; - public static final String AUDIO_X_MPEG = "audio/x-mpeg"; - public static final String AUDIO_X_MPG = "audio/x-mpg"; - public static final String AUDIO_3GPP = "audio/3gpp"; - public static final String AUDIO_X_WAV = "audio/x-wav"; - public static final String AUDIO_OGG = "application/ogg"; - - public static final String VIDEO_UNSPECIFIED = "video/*"; - public static final String VIDEO_3GPP = "video/3gpp"; - public static final String VIDEO_3G2 = "video/3gpp2"; - public static final String VIDEO_H263 = "video/h263"; - public static final String VIDEO_MP4 = "video/mp4"; - - public static final String APP_SMIL = "application/smil"; - public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml"; - public static final String APP_XHTML = "application/xhtml+xml"; - - public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content"; - public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message"; - - private static final ArrayList sSupportedContentTypes = new ArrayList(); - private static final ArrayList sSupportedImageTypes = new ArrayList(); - private static final ArrayList sSupportedAudioTypes = new ArrayList(); - private static final ArrayList sSupportedVideoTypes = new ArrayList(); - - static { - sSupportedContentTypes.add(TEXT_PLAIN); - sSupportedContentTypes.add(TEXT_HTML); - sSupportedContentTypes.add(TEXT_VCALENDAR); - sSupportedContentTypes.add(TEXT_VCARD); - - sSupportedContentTypes.add(IMAGE_JPEG); - sSupportedContentTypes.add(IMAGE_GIF); - sSupportedContentTypes.add(IMAGE_WBMP); - sSupportedContentTypes.add(IMAGE_PNG); - sSupportedContentTypes.add(IMAGE_JPG); - sSupportedContentTypes.add(IMAGE_X_MS_BMP); - //supportedContentTypes.add(IMAGE_SVG); not yet supported. - - sSupportedContentTypes.add(AUDIO_AAC); - sSupportedContentTypes.add(AUDIO_AMR); - sSupportedContentTypes.add(AUDIO_IMELODY); - sSupportedContentTypes.add(AUDIO_MID); - sSupportedContentTypes.add(AUDIO_MIDI); - sSupportedContentTypes.add(AUDIO_MP3); - sSupportedContentTypes.add(AUDIO_MPEG3); - sSupportedContentTypes.add(AUDIO_MPEG); - sSupportedContentTypes.add(AUDIO_MPG); - sSupportedContentTypes.add(AUDIO_X_MID); - sSupportedContentTypes.add(AUDIO_X_MIDI); - sSupportedContentTypes.add(AUDIO_X_MP3); - sSupportedContentTypes.add(AUDIO_X_MPEG3); - sSupportedContentTypes.add(AUDIO_X_MPEG); - sSupportedContentTypes.add(AUDIO_X_MPG); - sSupportedContentTypes.add(AUDIO_X_WAV); - sSupportedContentTypes.add(AUDIO_3GPP); - sSupportedContentTypes.add(AUDIO_OGG); - - sSupportedContentTypes.add(VIDEO_3GPP); - sSupportedContentTypes.add(VIDEO_3G2); - sSupportedContentTypes.add(VIDEO_H263); - sSupportedContentTypes.add(VIDEO_MP4); - - sSupportedContentTypes.add(APP_SMIL); - sSupportedContentTypes.add(APP_WAP_XHTML); - sSupportedContentTypes.add(APP_XHTML); - - sSupportedContentTypes.add(APP_DRM_CONTENT); - sSupportedContentTypes.add(APP_DRM_MESSAGE); - - // add supported image types - sSupportedImageTypes.add(IMAGE_JPEG); - sSupportedImageTypes.add(IMAGE_GIF); - sSupportedImageTypes.add(IMAGE_WBMP); - sSupportedImageTypes.add(IMAGE_PNG); - sSupportedImageTypes.add(IMAGE_JPG); - sSupportedImageTypes.add(IMAGE_X_MS_BMP); - - // add supported audio types - sSupportedAudioTypes.add(AUDIO_AAC); - sSupportedAudioTypes.add(AUDIO_AMR); - sSupportedAudioTypes.add(AUDIO_IMELODY); - sSupportedAudioTypes.add(AUDIO_MID); - sSupportedAudioTypes.add(AUDIO_MIDI); - sSupportedAudioTypes.add(AUDIO_MP3); - sSupportedAudioTypes.add(AUDIO_MPEG3); - sSupportedAudioTypes.add(AUDIO_MPEG); - sSupportedAudioTypes.add(AUDIO_MPG); - sSupportedAudioTypes.add(AUDIO_MP4); - sSupportedAudioTypes.add(AUDIO_X_MID); - sSupportedAudioTypes.add(AUDIO_X_MIDI); - sSupportedAudioTypes.add(AUDIO_X_MP3); - sSupportedAudioTypes.add(AUDIO_X_MPEG3); - sSupportedAudioTypes.add(AUDIO_X_MPEG); - sSupportedAudioTypes.add(AUDIO_X_MPG); - sSupportedAudioTypes.add(AUDIO_X_WAV); - sSupportedAudioTypes.add(AUDIO_3GPP); - sSupportedAudioTypes.add(AUDIO_OGG); - - // add supported video types - sSupportedVideoTypes.add(VIDEO_3GPP); - sSupportedVideoTypes.add(VIDEO_3G2); - sSupportedVideoTypes.add(VIDEO_H263); - sSupportedVideoTypes.add(VIDEO_MP4); - } - - // This class should never be instantiated. - private ContentType() { - } - - public static boolean isSupportedType(String contentType) { - return (null != contentType) && sSupportedContentTypes.contains(contentType); - } - - public static boolean isSupportedImageType(String contentType) { - return isImageType(contentType) && isSupportedType(contentType); - } - - public static boolean isSupportedAudioType(String contentType) { - return isAudioType(contentType) && isSupportedType(contentType); - } - - public static boolean isSupportedVideoType(String contentType) { - return isVideoType(contentType) && isSupportedType(contentType); - } - - public static boolean isTextType(String contentType) { - return (null != contentType) && contentType.startsWith("text/"); - } - - public static boolean isImageType(String contentType) { - return (null != contentType) && contentType.startsWith("image/"); - } - - public static boolean isAudioType(String contentType) { - return (null != contentType) && contentType.startsWith("audio/"); - } - - public static boolean isVideoType(String contentType) { - return (null != contentType) && contentType.startsWith("video/"); - } - - public static boolean isDrmType(String contentType) { - return (null != contentType) - && (contentType.equals(APP_DRM_CONTENT) - || contentType.equals(APP_DRM_MESSAGE)); - } - - public static boolean isUnspecified(String contentType) { - return (null != contentType) && contentType.endsWith("*"); - } - - @SuppressWarnings("unchecked") - public static ArrayList getImageTypes() { - return (ArrayList) sSupportedImageTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getAudioTypes() { - return (ArrayList) sSupportedAudioTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getVideoTypes() { - return (ArrayList) sSupportedVideoTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList getSupportedTypes() { - return (ArrayList) sSupportedContentTypes.clone(); - } -} diff --git a/src/ws/com/google/android/mms/InvalidHeaderValueException.java b/src/ws/com/google/android/mms/InvalidHeaderValueException.java deleted file mode 100644 index ec3e75fd2c..0000000000 --- a/src/ws/com/google/android/mms/InvalidHeaderValueException.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 ws.com.google.android.mms; - -/** - * Thrown when an invalid header value was set. - */ -public class InvalidHeaderValueException extends MmsException { - private static final long serialVersionUID = -2053384496042052262L; - - /** - * Constructs an InvalidHeaderValueException with no detailed message. - */ - public InvalidHeaderValueException() { - super(); - } - - /** - * Constructs an InvalidHeaderValueException with the specified detailed message. - * - * @param message the detailed message. - */ - public InvalidHeaderValueException(String message) { - super(message); - } -} diff --git a/src/ws/com/google/android/mms/MmsException.java b/src/ws/com/google/android/mms/MmsException.java deleted file mode 100644 index 39775c4dc9..0000000000 --- a/src/ws/com/google/android/mms/MmsException.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 ws.com.google.android.mms; - -/** - * A generic exception that is thrown by the Mms client. - */ -public class MmsException extends Exception { - private static final long serialVersionUID = -7323249827281485390L; - - /** - * Creates a new MmsException. - */ - public MmsException() { - super(); - } - - /** - * Creates a new MmsException with the specified detail message. - * - * @param message the detail message. - */ - public MmsException(String message) { - super(message); - } - - /** - * Creates a new MmsException with the specified cause. - * - * @param cause the cause. - */ - public MmsException(Throwable cause) { - super(cause); - } - - /** - * Creates a new MmsException with the specified detail message and cause. - * - * @param message the detail message. - * @param cause the cause. - */ - public MmsException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/ws/com/google/android/mms/package.html b/src/ws/com/google/android/mms/package.html deleted file mode 100755 index c9f96a66ab..0000000000 --- a/src/ws/com/google/android/mms/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - - diff --git a/src/ws/com/google/android/mms/pdu/AcknowledgeInd.java b/src/ws/com/google/android/mms/pdu/AcknowledgeInd.java deleted file mode 100644 index dcc747299f..0000000000 --- a/src/ws/com/google/android/mms/pdu/AcknowledgeInd.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Acknowledge.ind PDU. - */ -public class AcknowledgeInd extends GenericPdu { - /** - * Constructor, used when composing a M-Acknowledge.ind pdu. - * - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - */ - public AcknowledgeInd(int mmsVersion, byte[] transactionId) - throws InvalidHeaderValueException { - super(); - - setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - AcknowledgeInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/src/ws/com/google/android/mms/pdu/Base64.java b/src/ws/com/google/android/mms/pdu/Base64.java deleted file mode 100644 index c6f16025ca..0000000000 --- a/src/ws/com/google/android/mms/pdu/Base64.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -public class Base64 { - /** - * Used to get the number of Quadruples. - */ - static final int FOURBYTE = 4; - - /** - * Byte used to pad output. - */ - static final byte PAD = (byte) '='; - - /** - * The base length. - */ - static final int BASELENGTH = 255; - - // Create arrays to hold the base64 characters - private static byte[] base64Alphabet = new byte[BASELENGTH]; - - // Populating the character arrays - static { - for (int i = 0; i < BASELENGTH; i++) { - base64Alphabet[i] = (byte) -1; - } - for (int i = 'Z'; i >= 'A'; i--) { - base64Alphabet[i] = (byte) (i - 'A'); - } - for (int i = 'z'; i >= 'a'; i--) { - base64Alphabet[i] = (byte) (i - 'a' + 26); - } - for (int i = '9'; i >= '0'; i--) { - base64Alphabet[i] = (byte) (i - '0' + 52); - } - - base64Alphabet['+'] = 62; - base64Alphabet['/'] = 63; - } - - /** - * Decodes Base64 data into octects - * - * @param base64Data Byte array containing Base64 data - * @return Array containing decoded data. - */ - public static byte[] decodeBase64(byte[] base64Data) { - // RFC 2045 requires that we discard ALL non-Base64 characters - base64Data = discardNonBase64(base64Data); - - // handle the edge case, so we don't have to worry about it later - if (base64Data.length == 0) { - return new byte[0]; - } - - int numberQuadruple = base64Data.length / FOURBYTE; - byte decodedData[] = null; - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; - - // Throw away anything not in base64Data - - int encodedIndex = 0; - int dataIndex = 0; - { - // this sizes the output array properly - rlw - int lastData = base64Data.length; - // ignore the '=' padding - while (base64Data[lastData - 1] == PAD) { - if (--lastData == 0) { - return new byte[0]; - } - } - decodedData = new byte[lastData - numberQuadruple]; - } - - for (int i = 0; i < numberQuadruple; i++) { - dataIndex = i * 4; - marker0 = base64Data[dataIndex + 2]; - marker1 = base64Data[dataIndex + 3]; - - b1 = base64Alphabet[base64Data[dataIndex]]; - b2 = base64Alphabet[base64Data[dataIndex + 1]]; - - if (marker0 != PAD && marker1 != PAD) { - //No PAD e.g 3cQl - b3 = base64Alphabet[marker0]; - b4 = base64Alphabet[marker1]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); - } else if (marker0 == PAD) { - //Two PAD e.g. 3c[Pad][Pad] - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - } else if (marker1 == PAD) { - //One PAD e.g. 3cQ[Pad] - b3 = base64Alphabet[marker0]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - } - encodedIndex += 3; - } - return decodedData; - } - - /** - * Check octect wheter it is a base64 encoding. - * - * @param octect to be checked byte - * @return ture if it is base64 encoding, false otherwise. - */ - private static boolean isBase64(byte octect) { - if (octect == PAD) { - return true; - } else if (base64Alphabet[octect] == -1) { - return false; - } else { - return true; - } - } - - /** - * Discards any characters outside of the base64 alphabet, per - * the requirements on page 25 of RFC 2045 - "Any characters - * outside of the base64 alphabet are to be ignored in base64 - * encoded data." - * - * @param data The base-64 encoded data to groom - * @return The data, less non-base64 characters (see RFC 2045). - */ - static byte[] discardNonBase64(byte[] data) { - byte groomedData[] = new byte[data.length]; - int bytesCopied = 0; - - for (int i = 0; i < data.length; i++) { - if (isBase64(data[i])) { - groomedData[bytesCopied++] = data[i]; - } - } - - byte packedData[] = new byte[bytesCopied]; - - System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); - - return packedData; - } -} diff --git a/src/ws/com/google/android/mms/pdu/CharacterSets.java b/src/ws/com/google/android/mms/pdu/CharacterSets.java deleted file mode 100644 index 46f2767eef..0000000000 --- a/src/ws/com/google/android/mms/pdu/CharacterSets.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import java.io.UnsupportedEncodingException; -import java.util.HashMap; - -public class CharacterSets { - /** - * IANA assigned MIB enum numbers. - * - * From wap-230-wsp-20010705-a.pdf - * Any-charset = - * Equivalent to the special RFC2616 charset value "*" - */ - public static final int ANY_CHARSET = 0x00; - public static final int US_ASCII = 0x03; - public static final int ISO_8859_1 = 0x04; - public static final int ISO_8859_2 = 0x05; - public static final int ISO_8859_3 = 0x06; - public static final int ISO_8859_4 = 0x07; - public static final int ISO_8859_5 = 0x08; - public static final int ISO_8859_6 = 0x09; - public static final int ISO_8859_7 = 0x0A; - public static final int ISO_8859_8 = 0x0B; - public static final int ISO_8859_9 = 0x0C; - public static final int SHIFT_JIS = 0x11; - public static final int UTF_8 = 0x6A; - public static final int BIG5 = 0x07EA; - public static final int UCS2 = 0x03E8; - public static final int UTF_16 = 0x03F7; - - /** - * If the encoding of given data is unsupported, use UTF_8 to decode it. - */ - public static final int DEFAULT_CHARSET = UTF_8; - - /** - * Array of MIB enum numbers. - */ - private static final int[] MIBENUM_NUMBERS = { - ANY_CHARSET, - US_ASCII, - ISO_8859_1, - ISO_8859_2, - ISO_8859_3, - ISO_8859_4, - ISO_8859_5, - ISO_8859_6, - ISO_8859_7, - ISO_8859_8, - ISO_8859_9, - SHIFT_JIS, - UTF_8, - BIG5, - UCS2, - UTF_16, - }; - - /** - * The Well-known-charset Mime name. - */ - public static final String MIMENAME_ANY_CHARSET = "*"; - public static final String MIMENAME_US_ASCII = "us-ascii"; - public static final String MIMENAME_ISO_8859_1 = "iso-8859-1"; - public static final String MIMENAME_ISO_8859_2 = "iso-8859-2"; - public static final String MIMENAME_ISO_8859_3 = "iso-8859-3"; - public static final String MIMENAME_ISO_8859_4 = "iso-8859-4"; - public static final String MIMENAME_ISO_8859_5 = "iso-8859-5"; - public static final String MIMENAME_ISO_8859_6 = "iso-8859-6"; - public static final String MIMENAME_ISO_8859_7 = "iso-8859-7"; - public static final String MIMENAME_ISO_8859_8 = "iso-8859-8"; - public static final String MIMENAME_ISO_8859_9 = "iso-8859-9"; - public static final String MIMENAME_SHIFT_JIS = "shift_JIS"; - public static final String MIMENAME_UTF_8 = "utf-8"; - public static final String MIMENAME_BIG5 = "big5"; - public static final String MIMENAME_UCS2 = "iso-10646-ucs-2"; - public static final String MIMENAME_UTF_16 = "utf-16"; - - public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8; - - /** - * Array of the names of character sets. - */ - private static final String[] MIME_NAMES = { - MIMENAME_ANY_CHARSET, - MIMENAME_US_ASCII, - MIMENAME_ISO_8859_1, - MIMENAME_ISO_8859_2, - MIMENAME_ISO_8859_3, - MIMENAME_ISO_8859_4, - MIMENAME_ISO_8859_5, - MIMENAME_ISO_8859_6, - MIMENAME_ISO_8859_7, - MIMENAME_ISO_8859_8, - MIMENAME_ISO_8859_9, - MIMENAME_SHIFT_JIS, - MIMENAME_UTF_8, - MIMENAME_BIG5, - MIMENAME_UCS2, - MIMENAME_UTF_16, - }; - - private static final HashMap MIBENUM_TO_NAME_MAP; - private static final HashMap NAME_TO_MIBENUM_MAP; - - static { - // Create the HashMaps. - MIBENUM_TO_NAME_MAP = new HashMap(); - NAME_TO_MIBENUM_MAP = new HashMap(); - assert(MIBENUM_NUMBERS.length == MIME_NAMES.length); - int count = MIBENUM_NUMBERS.length - 1; - for(int i = 0; i <= count; i++) { - MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]); - NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]); - } - } - - private CharacterSets() {} // Non-instantiatable - - /** - * Map an MIBEnum number to the name of the charset which this number - * is assigned to by IANA. - * - * @param mibEnumValue An IANA assigned MIBEnum number. - * @return The name string of the charset. - * @throws UnsupportedEncodingException - */ - public static String getMimeName(int mibEnumValue) - throws UnsupportedEncodingException { - String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue); - if (name == null) { - throw new UnsupportedEncodingException(); - } - return name; - } - - /** - * Map a well-known charset name to its assigned MIBEnum number. - * - * @param mimeName The charset name. - * @return The MIBEnum number assigned by IANA for this charset. - * @throws UnsupportedEncodingException - */ - public static int getMibEnumValue(String mimeName) - throws UnsupportedEncodingException { - if(null == mimeName) { - return -1; - } - - Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName); - if (mibEnumValue == null) { - throw new UnsupportedEncodingException(); - } - return mibEnumValue; - } -} diff --git a/src/ws/com/google/android/mms/pdu/DeliveryInd.java b/src/ws/com/google/android/mms/pdu/DeliveryInd.java deleted file mode 100644 index 694e3c2535..0000000000 --- a/src/ws/com/google/android/mms/pdu/DeliveryInd.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Delivery.Ind Pdu. - */ -public class DeliveryInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public DeliveryInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - DeliveryInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value, should not be null - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get Status value. - * - * @return the value - */ - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Set Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public EncodedStringValue getStatusText() {return null;} - * public void setStatusText(EncodedStringValue value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/EncodedStringValue.java b/src/ws/com/google/android/mms/pdu/EncodedStringValue.java deleted file mode 100644 index eaacd99b56..0000000000 --- a/src/ws/com/google/android/mms/pdu/EncodedStringValue.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import android.util.Config; -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; - -/** - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ -public class EncodedStringValue implements Cloneable { - private static final String TAG = "EncodedStringValue"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; - - /** - * The Char-set value. - */ - private int mCharacterSet; - - /** - * The Text-string value. - */ - private byte[] mData; - - /** - * Constructor. - * - * @param charset the Char-set value - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public EncodedStringValue(int charset, byte[] data) { - // TODO: CharSet needs to be validated against MIBEnum. - if(null == data) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mCharacterSet = charset; - mData = new byte[data.length]; - System.arraycopy(data, 0, mData, 0, data.length); - } - - /** - * Constructor. - * - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public EncodedStringValue(byte[] data) { - this(CharacterSets.DEFAULT_CHARSET, data); - } - - public EncodedStringValue(String data) { - try { - mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); - mCharacterSet = CharacterSets.DEFAULT_CHARSET; - } catch (UnsupportedEncodingException e) { - Log.e(TAG, "Default encoding must be supported.", e); - } - } - - /** - * Get Char-set value. - * - * @return the value - */ - public int getCharacterSet() { - return mCharacterSet; - } - - /** - * Set Char-set value. - * - * @param charset the Char-set value - */ - public void setCharacterSet(int charset) { - // TODO: CharSet needs to be validated against MIBEnum. - mCharacterSet = charset; - } - - /** - * Get Text-string value. - * - * @return the value - */ - public byte[] getTextString() { - byte[] byteArray = new byte[mData.length]; - - System.arraycopy(mData, 0, byteArray, 0, mData.length); - return byteArray; - } - - /** - * Set Text-string value. - * - * @param textString the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - public void setTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } - - /** - * Convert this object to a {@link java.lang.String}. If the encoding of - * the EncodedStringValue is null or unsupported, it will be - * treated as iso-8859-1 encoding. - * - * @return The decoded String. - */ - public String getString() { - if (CharacterSets.ANY_CHARSET == mCharacterSet) { - return new String(mData); // system default encoding. - } else { - try { - String name = CharacterSets.getMimeName(mCharacterSet); - return new String(mData, name); - } catch (UnsupportedEncodingException e) { - if (LOCAL_LOGV) { - Log.v(TAG, e.getMessage(), e); - } - try { - return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException _) { - return new String(mData); // system default encoding. - } - } - } - } - - /** - * Append to Text-string. - * - * @param textString the textString to append - * @throws NullPointerException if the text String is null - * or an IOException occured. - */ - public void appendTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("Text-string is null."); - } - - if(null == mData) { - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } else { - ByteArrayOutputStream newTextString = new ByteArrayOutputStream(); - try { - newTextString.write(mData); - newTextString.write(textString); - } catch (IOException e) { - e.printStackTrace(); - throw new NullPointerException( - "appendTextString: failed when write a new Text-string"); - } - - mData = newTextString.toByteArray(); - } - } - - /* - * (non-Javadoc) - * @see java.lang.Object#clone() - */ - @Override - public Object clone() throws CloneNotSupportedException { - super.clone(); - int len = mData.length; - byte[] dstBytes = new byte[len]; - System.arraycopy(mData, 0, dstBytes, 0, len); - - try { - return new EncodedStringValue(mCharacterSet, dstBytes); - } catch (Exception e) { - Log.e(TAG, "failed to clone an EncodedStringValue: " + this); - e.printStackTrace(); - throw new CloneNotSupportedException(e.getMessage()); - } - } - - /** - * Split this encoded string around matches of the given pattern. - * - * @param pattern the delimiting pattern - * @return the array of encoded strings computed by splitting this encoded - * string around matches of the given pattern - */ - public EncodedStringValue[] split(String pattern) { - String[] temp = getString().split(pattern); - EncodedStringValue[] ret = new EncodedStringValue[temp.length]; - for (int i = 0; i < ret.length; ++i) { - try { - ret[i] = new EncodedStringValue(mCharacterSet, - temp[i].getBytes()); - } catch (NullPointerException _) { - // Can't arrive here - return null; - } - } - return ret; - } - - /** - * Extract an EncodedStringValue[] from a given String. - */ - public static EncodedStringValue[] extract(String src) { - String[] values = src.split(";"); - - ArrayList list = new ArrayList(); - for (int i = 0; i < values.length; i++) { - if (values[i].length() > 0) { - list.add(new EncodedStringValue(values[i])); - } - } - - int len = list.size(); - if (len > 0) { - return list.toArray(new EncodedStringValue[len]); - } else { - return null; - } - } - - /** - * Concatenate an EncodedStringValue[] into a single String. - */ - public static String concat(EncodedStringValue[] addr) { - StringBuilder sb = new StringBuilder(); - int maxIndex = addr.length - 1; - for (int i = 0; i <= maxIndex; i++) { - sb.append(addr[i].getString()); - if (i < maxIndex) { - sb.append(";"); - } - } - - return sb.toString(); - } - - public static EncodedStringValue copy(EncodedStringValue value) { - if (value == null) { - return null; - } - - return new EncodedStringValue(value.mCharacterSet, value.mData); - } - - public static EncodedStringValue[] encodeStrings(String[] array) { - int count = array.length; - if (count > 0) { - EncodedStringValue[] encodedArray = new EncodedStringValue[count]; - for (int i = 0; i < count; i++) { - encodedArray[i] = new EncodedStringValue(array[i]); - } - return encodedArray; - } - return null; - } -} diff --git a/src/ws/com/google/android/mms/pdu/GenericPdu.java b/src/ws/com/google/android/mms/pdu/GenericPdu.java deleted file mode 100644 index f397c5ba69..0000000000 --- a/src/ws/com/google/android/mms/pdu/GenericPdu.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -public class GenericPdu { - /** - * The headers of pdu. - */ - PduHeaders mPduHeaders = null; - - /** - * Constructor. - */ - public GenericPdu() { - mPduHeaders = new PduHeaders(); - } - - /** - * Constructor. - * - * @param headers Headers for this PDU. - */ - GenericPdu(PduHeaders headers) { - mPduHeaders = headers; - } - - /** - * Get the headers of this PDU. - * - * @return A PduHeaders of this PDU. - */ - public PduHeaders getPduHeaders() { - return mPduHeaders; - } - - /** - * Get X-Mms-Message-Type field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getMessageType() { - return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - } - - /** - * Set X-Mms-Message-Type field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - public void setMessageType(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE); - } - - /** - * Get X-Mms-MMS-Version field value. - * - * @return the X-Mms-MMS-Version value - */ - public int getMmsVersion() { - return mPduHeaders.getOctet(PduHeaders.MMS_VERSION); - } - - /** - * Set X-Mms-MMS-Version field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - public void setMmsVersion(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } -} diff --git a/src/ws/com/google/android/mms/pdu/MultimediaMessagePdu.java b/src/ws/com/google/android/mms/pdu/MultimediaMessagePdu.java deleted file mode 100644 index fdae64bcd7..0000000000 --- a/src/ws/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * Multimedia message PDU. - */ -public class MultimediaMessagePdu extends GenericPdu{ - /** - * The body. - */ - private PduBody mMessageBody; - - /** - * Constructor. - */ - public MultimediaMessagePdu() { - super(); - } - - /** - * Constructor. - * - * @param header the header of this PDU - * @param body the body of this PDU - */ - public MultimediaMessagePdu(PduHeaders header, PduBody body) { - super(header); - mMessageBody = body; - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - MultimediaMessagePdu(PduHeaders headers) { - super(headers); - } - - /** - * Get body of the PDU. - * - * @return the body - */ - public PduBody getBody() { - return mMessageBody; - } - - /** - * Set body of the PDU. - * - * @param body the body - */ - public void setBody(PduBody body) { - mMessageBody = body; - } - - /** - * Get subject. - * - * @return the value - */ - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Add a "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addTo(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Priority value. - * - * @return the value - */ - public int getPriority() { - return mPduHeaders.getOctet(PduHeaders.PRIORITY); - } - - /** - * Set X-Mms-Priority value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setPriority(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.PRIORITY); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value in seconds. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } -} diff --git a/src/ws/com/google/android/mms/pdu/NotificationInd.java b/src/ws/com/google/android/mms/pdu/NotificationInd.java deleted file mode 100644 index 6076eee9fe..0000000000 --- a/src/ws/com/google/android/mms/pdu/NotificationInd.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Notification.ind PDU. - */ -public class NotificationInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - * RuntimeException if an undeclared error occurs. - */ - public NotificationInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - public NotificationInd(PduHeaders headers) { - super(headers); - } - - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Get X-Mms-Content-Class Value. - * - * @return the value - */ - public int getContentClass() { - return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS); - } - - /** - * Set X-Mms-Content-Class Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setContentClass(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS); - } - - /** - * Get X-Mms-Content-Location value. - * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf: - * Content-location-value = Uri-value - * - * @return the value - */ - public byte[] getContentLocation() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION); - } - - /** - * Set X-Mms-Content-Location value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setContentLocation(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Message-Size value. - * Message-size-value = Long-integer - * - * @return the value - */ - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-Message-Size value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get subject. - * - * @return the value - */ - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /** - * Get X-Mms-Delivery-Report Value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public ElementDescriptorValue getElementDescriptor() {return null;} - * public void getElementDescriptor(ElementDescriptorValue value) {} - * - * public byte getPriority() {return 0x00;} - * public void setPriority(byte value) {} - * - * public byte getRecommendedRetrievalMode() {return 0x00;} - * public void setRecommendedRetrievalMode(byte value) {} - * - * public byte getRecommendedRetrievalModeText() {return 0x00;} - * public void setRecommendedRetrievalModeText(byte value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte getStored() {return 0x00;} - * public void setStored(byte value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/NotifyRespInd.java b/src/ws/com/google/android/mms/pdu/NotifyRespInd.java deleted file mode 100644 index 118fa5cb84..0000000000 --- a/src/ws/com/google/android/mms/pdu/NotifyRespInd.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * M-NofifyResp.ind PDU. - */ -public class NotifyRespInd extends GenericPdu { - /** - * Constructor, used when composing a M-NotifyResp.ind pdu. - * - * @param mmsVersion current version of mms - * @param transactionId the transaction-id value - * @param status the status value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - * RuntimeException if an undeclared error occurs. - */ - public NotifyRespInd(int mmsVersion, - byte[] transactionId, - int status) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - setStatus(status); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - NotifyRespInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Status field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * GetX-Mms-Status field value. - * - * @return the X-Mms-Status value - */ - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/src/ws/com/google/android/mms/pdu/PduBody.java b/src/ws/com/google/android/mms/pdu/PduBody.java deleted file mode 100644 index 1947dbe7d1..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduBody.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -public class PduBody { - private Vector mParts = null; - - private Map mPartMapByContentId = null; - private Map mPartMapByContentLocation = null; - private Map mPartMapByName = null; - private Map mPartMapByFileName = null; - - /** - * Constructor. - */ - public PduBody() { - mParts = new Vector(); - - mPartMapByContentId = new HashMap(); - mPartMapByContentLocation = new HashMap(); - mPartMapByName = new HashMap(); - mPartMapByFileName = new HashMap(); - } - - private void putPartToMaps(PduPart part) { - // Put part to mPartMapByContentId. - byte[] contentId = part.getContentId(); - if(null != contentId) { - mPartMapByContentId.put(new String(contentId), part); - } - - // Put part to mPartMapByContentLocation. - byte[] contentLocation = part.getContentLocation(); - if(null != contentLocation) { - String clc = new String(contentLocation); - mPartMapByContentLocation.put(clc, part); - } - - // Put part to mPartMapByName. - byte[] name = part.getName(); - if(null != name) { - String clc = new String(name); - mPartMapByName.put(clc, part); - } - - // Put part to mPartMapByFileName. - byte[] fileName = part.getFilename(); - if(null != fileName) { - String clc = new String(fileName); - mPartMapByFileName.put(clc, part); - } - } - - /** - * Appends the specified part to the end of this body. - * - * @param part part to be appended - * @return true when success, false when fail - * @throws NullPointerException when part is null - */ - public boolean addPart(PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - return mParts.add(part); - } - - /** - * Inserts the specified part at the specified position. - * - * @param index index at which the specified part is to be inserted - * @param part part to be inserted - * @throws NullPointerException when part is null - */ - public void addPart(int index, PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - mParts.add(index, part); - } - - /** - * Removes the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - public PduPart removePart(int index) { - return mParts.remove(index); - } - - /** - * Remove all of the parts. - */ - public void removeAll() { - mParts.clear(); - } - - /** - * Get the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - public PduPart getPart(int index) { - return mParts.get(index); - } - - /** - * Get the index of the specified part. - * - * @param part the part object - * @return index the index of the first occurrence of the part in this body - */ - public int getPartIndex(PduPart part) { - return mParts.indexOf(part); - } - - /** - * Get the number of parts. - * - * @return the number of parts - */ - public int getPartsNum() { - return mParts.size(); - } - - /** - * Get pdu part by content id. - * - * @param cid the value of content id. - * @return the pdu part. - */ - public PduPart getPartByContentId(String cid) { - return mPartMapByContentId.get(cid); - } - - /** - * Get pdu part by Content-Location. Content-Location of part is - * the same as filename and name(param of content-type). - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByContentLocation(String contentLocation) { - return mPartMapByContentLocation.get(contentLocation); - } - - /** - * Get pdu part by name. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByName(String name) { - return mPartMapByName.get(name); - } - - /** - * Get pdu part by filename. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - public PduPart getPartByFileName(String filename) { - return mPartMapByFileName.get(filename); - } -} diff --git a/src/ws/com/google/android/mms/pdu/PduComposer.java b/src/ws/com/google/android/mms/pdu/PduComposer.java deleted file mode 100644 index d2808cc7c5..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduComposer.java +++ /dev/null @@ -1,1184 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import android.content.ContentResolver; -import android.content.Context; -import android.text.TextUtils; -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; - -public class PduComposer { - /** - * Address type. - */ - static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1; - static private final int PDU_EMAIL_ADDRESS_TYPE = 2; - static private final int PDU_IPV4_ADDRESS_TYPE = 3; - static private final int PDU_IPV6_ADDRESS_TYPE = 4; - static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5; - - /** - * Address regular expression string. - */ - static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+"; - static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" + - "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}"; - static final String REGEXP_IPV6_ADDRESS_TYPE = - "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}"; - static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" + - "[0-9]{1,3}\\.{1}[0-9]{1,3}"; - - /** - * The postfix strings of address. - */ - static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN"; - static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4"; - static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6"; - - /** - * Error values. - */ - static private final int PDU_COMPOSE_SUCCESS = 0; - static private final int PDU_COMPOSE_CONTENT_ERROR = 1; - static private final int PDU_COMPOSE_FIELD_NOT_SET = 2; - static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3; - - /** - * WAP values defined in WSP spec. - */ - static private final int QUOTED_STRING_FLAG = 34; - static private final int END_STRING_FLAG = 0; - static private final int LENGTH_QUOTE = 31; - static private final int TEXT_MAX = 127; - static private final int SHORT_INTEGER_MAX = 127; - static private final int LONG_INTEGER_LENGTH_MAX = 8; - - /** - * Block size when read data from InputStream. - */ - static private final int PDU_COMPOSER_BLOCK_SIZE = 1024; - - /** - * The output message. - */ - protected ByteArrayOutputStream mMessage = null; - - /** - * The PDU. - */ - private GenericPdu mPdu = null; - - /** - * Current visiting position of the mMessage. - */ - protected int mPosition = 0; - - /** - * Message compose buffer stack. - */ - private BufferStack mStack = null; - - /** - * Content resolver. - */ - private final ContentResolver mResolver; - - /** - * Header of this pdu. - */ - private PduHeaders mPduHeader = null; - - /** - * Map of all content type - */ - private static HashMap mContentTypeMap = null; - - static { - mContentTypeMap = new HashMap(); - - int i; - for (i = 0; i < PduContentTypes.contentTypes.length; i++) { - mContentTypeMap.put(PduContentTypes.contentTypes[i], i); - } - } - - /** - * Constructor. - * - * @param context the context - * @param pdu the pdu to be composed - */ - public PduComposer(Context context, GenericPdu pdu) { - mPdu = pdu; - mResolver = context.getContentResolver(); - mPduHeader = pdu.getPduHeaders(); - mStack = new BufferStack(); - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Make the message. No need to check whether mandatory fields are set, - * because the constructors of outgoing pdus are taking care of this. - * - * @return OutputStream of maked message. Return null if - * the PDU is invalid. - */ - public byte[] make() { - // Get Message-type. - int type = mPdu.getMessageType(); - - /* make the message */ - switch (type) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - if (makeAckInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - default: - return null; - } - - Log.w("PduComposer", "Returning: " + mMessage.size() + " bytes..."); - - return mMessage.toByteArray(); - } - - /** - * Copy buf to mMessage. - */ - protected void arraycopy(byte[] buf, int pos, int length) { - mMessage.write(buf, pos, length); - mPosition = mPosition + length; - } - - /** - * Append a byte to mMessage. - */ - protected void append(int value) { - mMessage.write(value); - mPosition ++; - } - - /** - * Append short integer value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendShortInteger(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-integer = OCTET - * ; Integers in range 0-127 shall be encoded as a one octet value - * ; with the most significant bit set to one (1xxx xxxx) and with - * ; the value in the remaining least significant bits. - * In our implementation, only low 7 bits are stored and otherwise - * bits are ignored. - */ - append((value | 0x80) & 0xff); - } - - /** - * Append an octet number between 128 and 255 into mMessage. - * NOTE: - * A value between 0 and 127 should be appended by using appendShortInteger. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendOctet(int number) { - append(number); - } - - /** - * Append a short length into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendShortLength(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-length = - */ - append(value); - } - - /** - * Append long integer into mMessage. it's used for really long integers. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendLongInteger(long longInt) { - /* - * From WAP-230-WSP-20010705-a: - * Long-integer = Short-length Multi-octet-integer - * ; The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * ; The content octets shall be an unsigned integer value with the - * ; most significant octet encoded first (big-endian representation). - * ; The minimum number of octets must be used to encode the value. - */ - int size; - long temp = longInt; - - // Count the length of the long integer. - for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) { - temp = (temp >>> 8); - } - - // Set Length. - appendShortLength(size); - - // Count and set the long integer. - int i; - int shift = (size -1) * 8; - - for (i = 0; i < size; i++) { - append((int)((longInt >>> shift) & 0xff)); - shift = shift - 8; - } - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendTextString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255 - append(TEXT_MAX); - } - - arraycopy(text, 0, text.length); - append(0); - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendTextString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - appendTextString(str.getBytes()); - } - - /** - * Append encoded string value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendEncodedString(EncodedStringValue enStr) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(enStr != null); - - int charset = enStr.getCharacterSet(); - byte[] textString = enStr.getTextString(); - if (null == textString) { - return; - } - - /* - * In the implementation of EncodedStringValue, the charset field will - * never be 0. It will always be composed as - * Encoded-string-value = Value-length Char-set Text-string - */ - mStack.newbuf(); - PositionMarker start = mStack.mark(); - - appendShortInteger(charset); - appendTextString(textString); - - int len = start.getLength(); - mStack.pop(); - appendValueLength(len); - mStack.copy(); - } - - /** - * Append uintvar integer into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendUintvarInteger(long value) { - /* - * From WAP-230-WSP-20010705-a: - * To encode a large unsigned integer, split it into 7-bit fragments - * and place them in the payloads of multiple octets. The most significant - * bits are placed in the first octets with the least significant bits - * ending up in the last octet. All octets MUST set the Continue bit to 1 - * except the last octet, which MUST set the Continue bit to 0. - */ - int i; - long max = SHORT_INTEGER_MAX; - - for (i = 0; i < 5; i++) { - if (value < max) { - break; - } - - max = (max << 7) | 0x7fl; - } - - while(i > 0) { - long temp = value >>> (i * 7); - temp = temp & 0x7f; - - append((int)((temp | 0x80) & 0xff)); - - i--; - } - - append((int)(value & 0x7f)); - } - - /** - * Append date value into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendDateValue(long date) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Date-value = Long-integer - */ - appendLongInteger(date); - } - - /** - * Append value length to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendValueLength(long value) { - /* - * From WAP-230-WSP-20010705-a: - * Value-length = Short-length | (Length-quote Length) - * ; Value length is used to indicate the length of the value to follow - * Short-length = - * Length-quote = - * Length = Uintvar-integer - */ - if (value < LENGTH_QUOTE) { - appendShortLength((int) value); - return; - } - - append(LENGTH_QUOTE); - appendUintvarInteger(value); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendQuotedString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - append(QUOTED_STRING_FLAG); - arraycopy(text, 0, text.length); - append(END_STRING_FLAG); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendQuotedString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - appendQuotedString(str.getBytes()); - } - - private EncodedStringValue appendAddressType(EncodedStringValue address) { - EncodedStringValue temp = null; - - try { - int addressType = checkAddressType(address.getString()); - temp = EncodedStringValue.copy(address); - if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) { - // Phone number. - temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV4_ADDRESS_TYPE == addressType) { - // Ipv4 address. - temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV6_ADDRESS_TYPE == addressType) { - // Ipv6 address. - temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes()); - } - } catch (NullPointerException e) { - return null; - } - - return temp; - } - - /** - * Append header to mMessage. - */ - private int appendHeader(int field) { - switch (field) { - case PduHeaders.MMS_VERSION: - appendOctet(field); - - int version = mPduHeader.getOctet(field); - if (0 == version) { - appendShortInteger(PduHeaders.CURRENT_MMS_VERSION); - } else { - appendShortInteger(version); - } - - break; - - case PduHeaders.MESSAGE_ID: - case PduHeaders.TRANSACTION_ID: - byte[] textString = mPduHeader.getTextString(field); - if (null == textString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendTextString(textString); - break; - - case PduHeaders.TO: - case PduHeaders.BCC: - case PduHeaders.CC: - EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field); - - if (null == addr) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - EncodedStringValue temp; - for (int i = 0; i < addr.length; i++) { - temp = appendAddressType(addr[i]); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendOctet(field); - appendEncodedString(temp); - } - break; - - case PduHeaders.FROM: - // Value-length (Address-present-token Encoded-string-value | Insert-address-token) - appendOctet(field); - - EncodedStringValue from = mPduHeader.getEncodedStringValue(field); - if ((from == null) - || TextUtils.isEmpty(from.getString()) - || new String(from.getTextString()).equals( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { - // Length of from = 1 - append(1); - // Insert-address-token = - append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN); - } else { - mStack.newbuf(); - PositionMarker fstart = mStack.mark(); - - // Address-present-token = - append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN); - - temp = appendAddressType(from); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendEncodedString(temp); - - int flen = fstart.getLength(); - mStack.pop(); - appendValueLength(flen); - mStack.copy(); - } - break; - - case PduHeaders.READ_STATUS: - case PduHeaders.STATUS: - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.PRIORITY: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.READ_REPORT: - int octet = mPduHeader.getOctet(field); - if (0 == octet) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendOctet(octet); - break; - - case PduHeaders.DATE: - long date = mPduHeader.getLongInteger(field); - if (-1 == date) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendDateValue(date); - break; - - case PduHeaders.SUBJECT: - EncodedStringValue enString = - mPduHeader.getEncodedStringValue(field); - if (null == enString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendEncodedString(enString); - break; - - case PduHeaders.MESSAGE_CLASS: - byte[] messageClass = mPduHeader.getTextString(field); - if (null == messageClass) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_AUTO); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL); - } else { - appendTextString(messageClass); - } - break; - - case PduHeaders.EXPIRY: - long expiry = mPduHeader.getLongInteger(field); - if (-1 == expiry) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - - mStack.newbuf(); - PositionMarker expiryStart = mStack.mark(); - - append(PduHeaders.VALUE_RELATIVE_TOKEN); - appendLongInteger(expiry); - - int expiryLength = expiryStart.getLength(); - mStack.pop(); - appendValueLength(expiryLength); - mStack.copy(); - break; - - default: - return PDU_COMPOSE_FIELD_NOT_SUPPORTED; - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make ReadRec.Ind. - */ - private int makeReadRecInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Message-ID - if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Optional - appendHeader(PduHeaders.DATE); - - // X-Mms-Read-Status - if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Applic-ID Optional(not support) - // X-Mms-Reply-Applic-ID Optional(not support) - // X-Mms-Aux-Applic-Info Optional(not support) - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make NotifyResp.Ind. - */ - private int makeNotifyResp() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Status - if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional (not support) - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Acknowledge.Ind. - */ - private int makeAckInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional - appendHeader(PduHeaders.REPORT_ALLOWED); - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Send.req. - */ - private int makeSendReqPdu() { - Log.w("PduComposer", "Making send request..."); - - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ); - - // X-Mms-Transaction-ID - appendOctet(PduHeaders.TRANSACTION_ID); - - byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID); - if (trid == null) { - // Transaction-ID should be set(by Transaction) before make(). - throw new IllegalArgumentException("Transaction-ID is null."); - } - appendTextString(trid); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Date-value Optional. - appendHeader(PduHeaders.DATE); - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - boolean recipient = false; - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Cc - if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Bcc - if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Need at least one of "cc", "bcc" and "to". - if (false == recipient) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Subject Optional - appendHeader(PduHeaders.SUBJECT); - - // X-Mms-Message-Class Optional - // Message-class-value = Class-identifier | Token-text - appendHeader(PduHeaders.MESSAGE_CLASS); - - // X-Mms-Expiry Optional - appendHeader(PduHeaders.EXPIRY); - - // X-Mms-Priority Optional - appendHeader(PduHeaders.PRIORITY); - - // X-Mms-Delivery-Report Optional - appendHeader(PduHeaders.DELIVERY_REPORT); - - // X-Mms-Read-Report Optional - appendHeader(PduHeaders.READ_REPORT); - - // Content-Type - appendOctet(PduHeaders.CONTENT_TYPE); - - // Message body - return makeMessageBody(); - } - - /** - * Make message body. - */ - private int makeMessageBody() { - Log.w("PduComposer", "Making message body..."); - // 1. add body informations - mStack.newbuf(); // Switching buffer because we need to - - PositionMarker ctStart = mStack.mark(); - - // This contentTypeIdentifier should be used for type of attachment... - String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE)); - Integer contentTypeIdentifier = mContentTypeMap.get(contentType); - if (contentTypeIdentifier == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendShortInteger(contentTypeIdentifier.intValue()); - - // content-type parameter: start - PduBody body = ((SendReq) mPdu).getBody(); - if (null == body || body.getPartsNum() == 0) { - // empty message - appendUintvarInteger(0); - mStack.pop(); - mStack.copy(); - return PDU_COMPOSE_SUCCESS; - } - - PduPart part; - try { - part = body.getPart(0); - - byte[] start = part.getContentId(); - if (start != null) { - appendOctet(PduPart.P_DEP_START); - if (('<' == start[0]) && ('>' == start[start.length - 1])) { - appendTextString(start); - } else { - appendTextString("<" + new String(start) + ">"); - } - } - - // content-type parameter: type - appendOctet(PduPart.P_CT_MR_TYPE); - appendTextString(part.getContentType()); - } - catch (ArrayIndexOutOfBoundsException e){ - e.printStackTrace(); - } - - int ctLength = ctStart.getLength(); - mStack.pop(); - appendValueLength(ctLength); - mStack.copy(); - - // 3. add content - int partNum = body.getPartsNum(); - appendUintvarInteger(partNum); - for (int i = 0; i < partNum; i++) { - part = body.getPart(i); - mStack.newbuf(); // Leaving space for header lengh and data length - PositionMarker attachment = mStack.mark(); - - mStack.newbuf(); // Leaving space for Content-Type length - PositionMarker contentTypeBegin = mStack.mark(); - - byte[] partContentType = part.getContentType(); - - if (partContentType == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - // content-type value - Integer partContentTypeIdentifier = - mContentTypeMap.get(new String(partContentType)); - if (partContentTypeIdentifier == null) { - appendTextString(partContentType); - } else { - appendShortInteger(partContentTypeIdentifier.intValue()); - } - - /* Content-type parameter : name. - * The value of name, filename, content-location is the same. - * Just one of them is enough for this PDU. - */ - byte[] name = part.getName(); - - if (null == name) { - name = part.getFilename(); - - if (null == name) { - name = part.getContentLocation(); - - if (null == name) { - /* at lease one of name, filename, Content-location - * should be available. - */ - return PDU_COMPOSE_CONTENT_ERROR; - } - } - } - appendOctet(PduPart.P_DEP_NAME); - appendTextString(name); - - // content-type parameter : charset - int charset = part.getCharset(); - if (charset != 0) { - appendOctet(PduPart.P_CHARSET); - appendShortInteger(charset); - } - - int contentTypeLength = contentTypeBegin.getLength(); - mStack.pop(); - appendValueLength(contentTypeLength); - mStack.copy(); - - // content id - byte[] contentId = part.getContentId(); - - if (null != contentId) { - appendOctet(PduPart.P_CONTENT_ID); - if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) { - appendQuotedString(contentId); - } else { - appendQuotedString("<" + new String(contentId) + ">"); - } - } - - // content-location - byte[] contentLocation = part.getContentLocation(); - if (null != contentLocation) { - appendOctet(PduPart.P_CONTENT_LOCATION); - appendTextString(contentLocation); - } - - // content - int headerLength = attachment.getLength(); - - int dataLength = 0; // Just for safety... - byte[] partData = part.getData(); - - if (partData != null) { - arraycopy(partData, 0, partData.length); - dataLength = partData.length; - } else { - InputStream cr; - try { - byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE]; - cr = mResolver.openInputStream(part.getDataUri()); - int len = 0; - while ((len = cr.read(buffer)) != -1) { - mMessage.write(buffer, 0, len); - mPosition += len; - dataLength += len; - } - } catch (FileNotFoundException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (IOException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (RuntimeException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } - } - - if (dataLength != (attachment.getLength() - headerLength)) { - throw new RuntimeException("BUG: Length sanity check failed"); - } - - mStack.pop(); - appendUintvarInteger(headerLength); - appendUintvarInteger(dataLength); - mStack.copy(); - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Record current message informations. - */ - static private class LengthRecordNode { - ByteArrayOutputStream currentMessage = null; - public int currentPosition = 0; - - public LengthRecordNode next = null; - } - - /** - * Mark current message position and stact size. - */ - private class PositionMarker { - private int c_pos; // Current position - private int currentStackSize; // Current stack size - - int getLength() { - // If these assert fails, likely that you are finding the - // size of buffer that is deep in BufferStack you can only - // find the length of the buffer that is on top - if (currentStackSize != mStack.stackSize) { - throw new RuntimeException("BUG: Invalid call to getLength()"); - } - - return mPosition - c_pos; - } - } - - /** - * This implementation can be OPTIMIZED to use only - * 2 buffers. This optimization involves changing BufferStack - * only... Its usage (interface) will not change. - */ - private class BufferStack { - private LengthRecordNode stack = null; - private LengthRecordNode toCopy = null; - - int stackSize = 0; - - /** - * Create a new message buffer and push it into the stack. - */ - void newbuf() { - // You can't create a new buff when toCopy != null - // That is after calling pop() and before calling copy() - // If you do, it is a bug - if (toCopy != null) { - throw new RuntimeException("BUG: Invalid newbuf() before copy()"); - } - - LengthRecordNode temp = new LengthRecordNode(); - - temp.currentMessage = mMessage; - temp.currentPosition = mPosition; - - temp.next = stack; - stack = temp; - - stackSize = stackSize + 1; - - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Pop the message before and record current message in the stack. - */ - void pop() { - ByteArrayOutputStream currentMessage = mMessage; - int currentPosition = mPosition; - - mMessage = stack.currentMessage; - mPosition = stack.currentPosition; - - toCopy = stack; - // Re using the top element of the stack to avoid memory allocation - - stack = stack.next; - stackSize = stackSize - 1; - - toCopy.currentMessage = currentMessage; - toCopy.currentPosition = currentPosition; - } - - /** - * Append current message to the message before. - */ - void copy() { - arraycopy(toCopy.currentMessage.toByteArray(), 0, - toCopy.currentPosition); - - toCopy = null; - } - - /** - * Mark current message position - */ - PositionMarker mark() { - PositionMarker m = new PositionMarker(); - - m.c_pos = mPosition; - m.currentStackSize = stackSize; - - return m; - } - } - - /** - * Check address type. - * - * @param address address string without the postfix stinng type, - * such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4" - * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number, - * PDU_EMAIL_ADDRESS_TYPE if it is email address, - * PDU_IPV4_ADDRESS_TYPE if it is ipv4 address, - * PDU_IPV6_ADDRESS_TYPE if it is ipv6 address, - * PDU_UNKNOWN_ADDRESS_TYPE if it is unknown. - */ - protected static int checkAddressType(String address) { - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8. - * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode) - * e-mail = mailbox; to the definition of mailbox as described in - * section 3.4 of [RFC2822], but excluding the - * obsolete definitions as indicated by the "obs-" prefix. - * device-address = ( global-phone-number "/TYPE=PLMN" ) - * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" ) - * / ( escaped-value "/TYPE=" address-type ) - * - * global-phone-number = ["+"] 1*( DIGIT / written-sep ) - * written-sep =("-"/".") - * - * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value - * - * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373 - */ - - if (null == address) { - return PDU_UNKNOWN_ADDRESS_TYPE; - } - - if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) { - // Ipv4 address. - return PDU_IPV4_ADDRESS_TYPE; - }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) { - // Phone number. - return PDU_PHONE_NUMBER_ADDRESS_TYPE; - } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) { - // Email address. - return PDU_EMAIL_ADDRESS_TYPE; - } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) { - // Ipv6 address. - return PDU_IPV6_ADDRESS_TYPE; - } else { - // Unknown address. - return PDU_UNKNOWN_ADDRESS_TYPE; - } - } -} diff --git a/src/ws/com/google/android/mms/pdu/PduContentTypes.java b/src/ws/com/google/android/mms/pdu/PduContentTypes.java deleted file mode 100644 index 6fcab96575..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduContentTypes.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -public class PduContentTypes { - /** - * All content types. From: - * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm - */ - static final String[] contentTypes = { - "*/*", /* 0x00 */ - "text/*", /* 0x01 */ - "text/html", /* 0x02 */ - "text/plain", /* 0x03 */ - "text/x-hdml", /* 0x04 */ - "text/x-ttml", /* 0x05 */ - "text/x-vCalendar", /* 0x06 */ - "text/x-vCard", /* 0x07 */ - "text/vnd.wap.wml", /* 0x08 */ - "text/vnd.wap.wmlscript", /* 0x09 */ - "text/vnd.wap.wta-event", /* 0x0A */ - "multipart/*", /* 0x0B */ - "multipart/mixed", /* 0x0C */ - "multipart/form-data", /* 0x0D */ - "multipart/byterantes", /* 0x0E */ - "multipart/alternative", /* 0x0F */ - "application/*", /* 0x10 */ - "application/java-vm", /* 0x11 */ - "application/x-www-form-urlencoded", /* 0x12 */ - "application/x-hdmlc", /* 0x13 */ - "application/vnd.wap.wmlc", /* 0x14 */ - "application/vnd.wap.wmlscriptc", /* 0x15 */ - "application/vnd.wap.wta-eventc", /* 0x16 */ - "application/vnd.wap.uaprof", /* 0x17 */ - "application/vnd.wap.wtls-ca-certificate", /* 0x18 */ - "application/vnd.wap.wtls-user-certificate", /* 0x19 */ - "application/x-x509-ca-cert", /* 0x1A */ - "application/x-x509-user-cert", /* 0x1B */ - "image/*", /* 0x1C */ - "image/gif", /* 0x1D */ - "image/jpeg", /* 0x1E */ - "image/tiff", /* 0x1F */ - "image/png", /* 0x20 */ - "image/vnd.wap.wbmp", /* 0x21 */ - "application/vnd.wap.multipart.*", /* 0x22 */ - "application/vnd.wap.multipart.mixed", /* 0x23 */ - "application/vnd.wap.multipart.form-data", /* 0x24 */ - "application/vnd.wap.multipart.byteranges", /* 0x25 */ - "application/vnd.wap.multipart.alternative", /* 0x26 */ - "application/xml", /* 0x27 */ - "text/xml", /* 0x28 */ - "application/vnd.wap.wbxml", /* 0x29 */ - "application/x-x968-cross-cert", /* 0x2A */ - "application/x-x968-ca-cert", /* 0x2B */ - "application/x-x968-user-cert", /* 0x2C */ - "text/vnd.wap.si", /* 0x2D */ - "application/vnd.wap.sic", /* 0x2E */ - "text/vnd.wap.sl", /* 0x2F */ - "application/vnd.wap.slc", /* 0x30 */ - "text/vnd.wap.co", /* 0x31 */ - "application/vnd.wap.coc", /* 0x32 */ - "application/vnd.wap.multipart.related", /* 0x33 */ - "application/vnd.wap.sia", /* 0x34 */ - "text/vnd.wap.connectivity-xml", /* 0x35 */ - "application/vnd.wap.connectivity-wbxml", /* 0x36 */ - "application/pkcs7-mime", /* 0x37 */ - "application/vnd.wap.hashed-certificate", /* 0x38 */ - "application/vnd.wap.signed-certificate", /* 0x39 */ - "application/vnd.wap.cert-response", /* 0x3A */ - "application/xhtml+xml", /* 0x3B */ - "application/wml+xml", /* 0x3C */ - "text/css", /* 0x3D */ - "application/vnd.wap.mms-message", /* 0x3E */ - "application/vnd.wap.rollover-certificate", /* 0x3F */ - "application/vnd.wap.locc+wbxml", /* 0x40 */ - "application/vnd.wap.loc+xml", /* 0x41 */ - "application/vnd.syncml.dm+wbxml", /* 0x42 */ - "application/vnd.syncml.dm+xml", /* 0x43 */ - "application/vnd.syncml.notification", /* 0x44 */ - "application/vnd.wap.xhtml+xml", /* 0x45 */ - "application/vnd.wv.csp.cir", /* 0x46 */ - "application/vnd.oma.dd+xml", /* 0x47 */ - "application/vnd.oma.drm.message", /* 0x48 */ - "application/vnd.oma.drm.content", /* 0x49 */ - "application/vnd.oma.drm.rights+xml", /* 0x4A */ - "application/vnd.oma.drm.rights+wbxml", /* 0x4B */ - "application/vnd.wv.csp+xml", /* 0x4C */ - "application/vnd.wv.csp+wbxml", /* 0x4D */ - "application/vnd.syncml.ds.notification", /* 0x4E */ - "audio/*", /* 0x4F */ - "video/*", /* 0x50 */ - "application/vnd.oma.dd2+xml", /* 0x51 */ - "application/mikey" /* 0x52 */ - }; -} diff --git a/src/ws/com/google/android/mms/pdu/PduHeaders.java b/src/ws/com/google/android/mms/pdu/PduHeaders.java deleted file mode 100644 index d3b2690554..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduHeaders.java +++ /dev/null @@ -1,731 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -import java.util.ArrayList; -import java.util.HashMap; - -public class PduHeaders { - /** - * All pdu header fields. - */ - public static final int BCC = 0x81; - public static final int CC = 0x82; - public static final int CONTENT_LOCATION = 0x83; - public static final int CONTENT_TYPE = 0x84; - public static final int DATE = 0x85; - public static final int DELIVERY_REPORT = 0x86; - public static final int DELIVERY_TIME = 0x87; - public static final int EXPIRY = 0x88; - public static final int FROM = 0x89; - public static final int MESSAGE_CLASS = 0x8A; - public static final int MESSAGE_ID = 0x8B; - public static final int MESSAGE_TYPE = 0x8C; - public static final int MMS_VERSION = 0x8D; - public static final int MESSAGE_SIZE = 0x8E; - public static final int PRIORITY = 0x8F; - - public static final int READ_REPLY = 0x90; - public static final int READ_REPORT = 0x90; - public static final int REPORT_ALLOWED = 0x91; - public static final int RESPONSE_STATUS = 0x92; - public static final int RESPONSE_TEXT = 0x93; - public static final int SENDER_VISIBILITY = 0x94; - public static final int STATUS = 0x95; - public static final int SUBJECT = 0x96; - public static final int TO = 0x97; - public static final int TRANSACTION_ID = 0x98; - public static final int RETRIEVE_STATUS = 0x99; - public static final int RETRIEVE_TEXT = 0x9A; - public static final int READ_STATUS = 0x9B; - public static final int REPLY_CHARGING = 0x9C; - public static final int REPLY_CHARGING_DEADLINE = 0x9D; - public static final int REPLY_CHARGING_ID = 0x9E; - public static final int REPLY_CHARGING_SIZE = 0x9F; - - public static final int PREVIOUSLY_SENT_BY = 0xA0; - public static final int PREVIOUSLY_SENT_DATE = 0xA1; - public static final int STORE = 0xA2; - public static final int MM_STATE = 0xA3; - public static final int MM_FLAGS = 0xA4; - public static final int STORE_STATUS = 0xA5; - public static final int STORE_STATUS_TEXT = 0xA6; - public static final int STORED = 0xA7; - public static final int ATTRIBUTES = 0xA8; - public static final int TOTALS = 0xA9; - public static final int MBOX_TOTALS = 0xAA; - public static final int QUOTAS = 0xAB; - public static final int MBOX_QUOTAS = 0xAC; - public static final int MESSAGE_COUNT = 0xAD; - public static final int CONTENT = 0xAE; - public static final int START = 0xAF; - - public static final int ADDITIONAL_HEADERS = 0xB0; - public static final int DISTRIBUTION_INDICATOR = 0xB1; - public static final int ELEMENT_DESCRIPTOR = 0xB2; - public static final int LIMIT = 0xB3; - public static final int RECOMMENDED_RETRIEVAL_MODE = 0xB4; - public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5; - public static final int STATUS_TEXT = 0xB6; - public static final int APPLIC_ID = 0xB7; - public static final int REPLY_APPLIC_ID = 0xB8; - public static final int AUX_APPLIC_ID = 0xB9; - public static final int CONTENT_CLASS = 0xBA; - public static final int DRM_CONTENT = 0xBB; - public static final int ADAPTATION_ALLOWED = 0xBC; - public static final int REPLACE_ID = 0xBD; - public static final int CANCEL_ID = 0xBE; - public static final int CANCEL_STATUS = 0xBF; - - /** - * X-Mms-Message-Type field types. - */ - public static final int MESSAGE_TYPE_SEND_REQ = 0x80; - public static final int MESSAGE_TYPE_SEND_CONF = 0x81; - public static final int MESSAGE_TYPE_NOTIFICATION_IND = 0x82; - public static final int MESSAGE_TYPE_NOTIFYRESP_IND = 0x83; - public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; - public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND = 0x85; - public static final int MESSAGE_TYPE_DELIVERY_IND = 0x86; - public static final int MESSAGE_TYPE_READ_REC_IND = 0x87; - public static final int MESSAGE_TYPE_READ_ORIG_IND = 0x88; - public static final int MESSAGE_TYPE_FORWARD_REQ = 0x89; - public static final int MESSAGE_TYPE_FORWARD_CONF = 0x8A; - public static final int MESSAGE_TYPE_MBOX_STORE_REQ = 0x8B; - public static final int MESSAGE_TYPE_MBOX_STORE_CONF = 0x8C; - public static final int MESSAGE_TYPE_MBOX_VIEW_REQ = 0x8D; - public static final int MESSAGE_TYPE_MBOX_VIEW_CONF = 0x8E; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ = 0x8F; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF = 0x90; - public static final int MESSAGE_TYPE_MBOX_DELETE_REQ = 0x91; - public static final int MESSAGE_TYPE_MBOX_DELETE_CONF = 0x92; - public static final int MESSAGE_TYPE_MBOX_DESCR = 0x93; - public static final int MESSAGE_TYPE_DELETE_REQ = 0x94; - public static final int MESSAGE_TYPE_DELETE_CONF = 0x95; - public static final int MESSAGE_TYPE_CANCEL_REQ = 0x96; - public static final int MESSAGE_TYPE_CANCEL_CONF = 0x97; - - /** - * X-Mms-Delivery-Report | - * X-Mms-Read-Report | - * X-Mms-Report-Allowed | - * X-Mms-Sender-Visibility | - * X-Mms-Store | - * X-Mms-Stored | - * X-Mms-Totals | - * X-Mms-Quotas | - * X-Mms-Distribution-Indicator | - * X-Mms-DRM-Content | - * X-Mms-Adaptation-Allowed | - * field types. - */ - public static final int VALUE_YES = 0x80; - public static final int VALUE_NO = 0x81; - - /** - * Delivery-Time | - * Expiry and Reply-Charging-Deadline | - * field type components. - */ - public static final int VALUE_ABSOLUTE_TOKEN = 0x80; - public static final int VALUE_RELATIVE_TOKEN = 0x81; - - /** - * X-Mms-MMS-Version field types. - */ - public static final int MMS_VERSION_1_3 = ((1 << 4) | 3); - public static final int MMS_VERSION_1_2 = ((1 << 4) | 2); - public static final int MMS_VERSION_1_1 = ((1 << 4) | 1); - public static final int MMS_VERSION_1_0 = ((1 << 4) | 0); - - // Current version is 1.2. - public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2; - - /** - * From field type components. - */ - public static final int FROM_ADDRESS_PRESENT_TOKEN = 0x80; - public static final int FROM_INSERT_ADDRESS_TOKEN = 0x81; - - public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token"; - public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token"; - - /** - * X-Mms-Status Field. - */ - public static final int STATUS_EXPIRED = 0x80; - public static final int STATUS_RETRIEVED = 0x81; - public static final int STATUS_REJECTED = 0x82; - public static final int STATUS_DEFERRED = 0x83; - public static final int STATUS_UNRECOGNIZED = 0x84; - public static final int STATUS_INDETERMINATE = 0x85; - public static final int STATUS_FORWARDED = 0x86; - public static final int STATUS_UNREACHABLE = 0x87; - - /** - * MM-Flags field type components. - */ - public static final int MM_FLAGS_ADD_TOKEN = 0x80; - public static final int MM_FLAGS_REMOVE_TOKEN = 0x81; - public static final int MM_FLAGS_FILTER_TOKEN = 0x82; - - /** - * X-Mms-Message-Class field types. - */ - public static final int MESSAGE_CLASS_PERSONAL = 0x80; - public static final int MESSAGE_CLASS_ADVERTISEMENT = 0x81; - public static final int MESSAGE_CLASS_INFORMATIONAL = 0x82; - public static final int MESSAGE_CLASS_AUTO = 0x83; - - public static final String MESSAGE_CLASS_PERSONAL_STR = "personal"; - public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"; - public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational"; - public static final String MESSAGE_CLASS_AUTO_STR = "auto"; - - /** - * X-Mms-Priority field types. - */ - public static final int PRIORITY_LOW = 0x80; - public static final int PRIORITY_NORMAL = 0x81; - public static final int PRIORITY_HIGH = 0x82; - - /** - * X-Mms-Response-Status field types. - */ - public static final int RESPONSE_STATUS_OK = 0x80; - public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED = 0x81; - public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = 0x83; - public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = 0x85; - public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = 0x86; - public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87; - public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = 0x88; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC2; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC3; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS = 0xC4; - - public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED = 0xE3; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE4; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED = 0xE5; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED = 0xE8; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED = 0xE9; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED = 0xEA; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID = 0xEB; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_END = 0xFF; - - /** - * X-Mms-Retrieve-Status field types. - */ - public static final int RETRIEVE_STATUS_OK = 0x80; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC1; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3; - public static final int RETRIEVE_STATUS_ERROR_END = 0xFF; - - /** - * X-Mms-Sender-Visibility field types. - */ - public static final int SENDER_VISIBILITY_HIDE = 0x80; - public static final int SENDER_VISIBILITY_SHOW = 0x81; - - /** - * X-Mms-Read-Status field types. - */ - public static final int READ_STATUS_READ = 0x80; - public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81; - - /** - * X-Mms-Cancel-Status field types. - */ - public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80; - public static final int CANCEL_STATUS_REQUEST_CORRUPTED = 0x81; - - /** - * X-Mms-Reply-Charging field types. - */ - public static final int REPLY_CHARGING_REQUESTED = 0x80; - public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81; - public static final int REPLY_CHARGING_ACCEPTED = 0x82; - public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY = 0x83; - - /** - * X-Mms-MM-State field types. - */ - public static final int MM_STATE_DRAFT = 0x80; - public static final int MM_STATE_SENT = 0x81; - public static final int MM_STATE_NEW = 0x82; - public static final int MM_STATE_RETRIEVED = 0x83; - public static final int MM_STATE_FORWARDED = 0x84; - - /** - * X-Mms-Recommended-Retrieval-Mode field types. - */ - public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80; - - /** - * X-Mms-Content-Class field types. - */ - public static final int CONTENT_CLASS_TEXT = 0x80; - public static final int CONTENT_CLASS_IMAGE_BASIC = 0x81; - public static final int CONTENT_CLASS_IMAGE_RICH = 0x82; - public static final int CONTENT_CLASS_VIDEO_BASIC = 0x83; - public static final int CONTENT_CLASS_VIDEO_RICH = 0x84; - public static final int CONTENT_CLASS_MEGAPIXEL = 0x85; - public static final int CONTENT_CLASS_CONTENT_BASIC = 0x86; - public static final int CONTENT_CLASS_CONTENT_RICH = 0x87; - - /** - * X-Mms-Store-Status field types. - */ - public static final int STORE_STATUS_SUCCESS = 0x80; - public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC1; - public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE3; - public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL = 0xE4; - public static final int STORE_STATUS_ERROR_END = 0xFF; - - /** - * The map contains the value of all headers. - */ - private HashMap mHeaderMap = null; - - private long messageBox; - - /** - * Constructor of PduHeaders. - */ - public PduHeaders() { - mHeaderMap = new HashMap(); - } - - /** - * Get octet value by header field. - * - * @param field the field - * @return the octet value of the pdu header - * with specified header field. Return 0 if - * the value is not set. - */ - public int getOctet(int field) { - Integer octet = (Integer) mHeaderMap.get(field); - if (null == octet) { - return 0; - } - - return octet; - } - - public void setMessageBox(long messageBox) { - this.messageBox = messageBox; - } - - public long getMessageBox() { - return this.messageBox; - } - - /** - * Set octet value to pdu header by header field. - * - * @param value the value - * @param field the field - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setOctet(int value, int field) - throws InvalidHeaderValueException{ - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case REPORT_ALLOWED: - case ADAPTATION_ALLOWED: - case DELIVERY_REPORT: - case DRM_CONTENT: - case DISTRIBUTION_INDICATOR: - case QUOTAS: - case READ_REPORT: - case STORE: - case STORED: - case TOTALS: - case SENDER_VISIBILITY: - if ((VALUE_YES != value) && (VALUE_NO != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case READ_STATUS: - if ((READ_STATUS_READ != value) && - (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CANCEL_STATUS: - if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) && - (CANCEL_STATUS_REQUEST_CORRUPTED != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case PRIORITY: - if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case STATUS: -// if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) { -// // Invalid value. -// throw new InvalidHeaderValueException("Invalid Octet value!"); -// } - break; - case REPLY_CHARGING: - if ((value < REPLY_CHARGING_REQUESTED) - || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case MM_STATE: - if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RECOMMENDED_RETRIEVAL_MODE: - if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CONTENT_CLASS: - if ((value < CONTENT_CLASS_TEXT) - || (value > CONTENT_CLASS_CONTENT_RICH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RETRIEVE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value. - if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) && - (value <= RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < RETRIEVE_STATUS_OK) || - ((value > RETRIEVE_STATUS_OK) && - (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case STORE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value. - if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = STORE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) && - (value <= STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < STORE_STATUS_SUCCESS) || - ((value > STORE_STATUS_SUCCESS) && - (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case RESPONSE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value. - if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) && - (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) && - (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) || - (value < RESPONSE_STATUS_OK) || - ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) && - (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) { - value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case MMS_VERSION: - if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) { - value = CURRENT_MMS_VERSION; // Current version is the default value. - } - break; - case MESSAGE_TYPE: - if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - default: - // This header value should not be Octect. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get TextString value by header field. - * - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - */ - public byte[] getTextString(int field) { - return (byte[]) mHeaderMap.get(field); - } - - /** - * Set TextString value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - public void setTextString(byte[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case TRANSACTION_ID: - case REPLY_CHARGING_ID: - case AUX_APPLIC_ID: - case APPLIC_ID: - case REPLY_APPLIC_ID: - case MESSAGE_ID: - case REPLACE_ID: - case CANCEL_ID: - case CONTENT_LOCATION: - case MESSAGE_CLASS: - case CONTENT_TYPE: - break; - default: - // This header value should not be Text-String. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get EncodedStringValue value by header field. - * - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - */ - public EncodedStringValue getEncodedStringValue(int field) { - return (EncodedStringValue) mHeaderMap.get(field); - } - - /** - * Get TO, CC or BCC header value. - * - * @param field the field - * @return the EncodeStringValue array of the pdu header - * with specified header field - */ - public EncodedStringValue[] getEncodedStringValues(int field) { - ArrayList list = - (ArrayList) mHeaderMap.get(field); - if (null == list) { - return null; - } - EncodedStringValue[] values = new EncodedStringValue[list.size()]; - return list.toArray(values); - } - - /** - * Set EncodedStringValue value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - public void setEncodedStringValue(EncodedStringValue value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case SUBJECT: - case RECOMMENDED_RETRIEVAL_MODE_TEXT: - case RETRIEVE_TEXT: - case STATUS_TEXT: - case STORE_STATUS_TEXT: - case RESPONSE_TEXT: - case FROM: - case PREVIOUSLY_SENT_BY: - case MM_FLAGS: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - mHeaderMap.put(field, value); - } - - /** - * Set TO, CC or BCC header value. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value array of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setEncodedStringValues(EncodedStringValue[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - ArrayList list = new ArrayList(); - for (int i = 0; i < value.length; i++) { - list.add(value[i]); - } - mHeaderMap.put(field, list); - } - - /** - * Append one EncodedStringValue to another. - * - * @param value the EncodedStringValue to append - * @param field the field - * @throws NullPointerException if the value is null. - */ - public void appendEncodedStringValue(EncodedStringValue value, - int field) { - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - throw new RuntimeException("Invalid header field!"); - } - - ArrayList list = - (ArrayList) mHeaderMap.get(field); - if (null == list) { - list = new ArrayList(); - } - list.add(value); - mHeaderMap.put(field, list); - } - - /** - * Get LongInteger value by header field. - * - * @param field the field - * @return the LongInteger value of the pdu header - * with specified header field. if return -1, the - * field is not existed in pdu header. - */ - public long getLongInteger(int field) { - Long longInteger = (Long) mHeaderMap.get(field); - if (null == longInteger) { - return -1; - } - - return longInteger.longValue(); - } - - /** - * Set LongInteger value to pdu header by header field. - * - * @param value the value - * @param field the field - */ - public void setLongInteger(long value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case DATE: - case REPLY_CHARGING_SIZE: - case MESSAGE_SIZE: - case MESSAGE_COUNT: - case START: - case LIMIT: - case DELIVERY_TIME: - case EXPIRY: - case REPLY_CHARGING_DEADLINE: - case PREVIOUSLY_SENT_DATE: - break; - default: - // This header value should not be LongInteger. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } -} diff --git a/src/ws/com/google/android/mms/pdu/PduParser.java b/src/ws/com/google/android/mms/pdu/PduParser.java deleted file mode 100644 index f95e4a0ad1..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduParser.java +++ /dev/null @@ -1,1919 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import android.content.res.Resources; -import android.util.Log; - -import ws.com.google.android.mms.ContentType; -import ws.com.google.android.mms.InvalidHeaderValueException; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.HashMap; - -public class PduParser { - /** - * The next are WAP values defined in WSP specification. - */ - private static final int QUOTE = 127; - private static final int LENGTH_QUOTE = 31; - private static final int TEXT_MIN = 32; - private static final int TEXT_MAX = 127; - private static final int SHORT_INTEGER_MAX = 127; - private static final int SHORT_LENGTH_MAX = 30; - private static final int LONG_INTEGER_LENGTH_MAX = 8; - private static final int QUOTED_STRING_FLAG = 34; - private static final int END_STRING_FLAG = 0x00; - //The next two are used by the interface "parseWapString" to - //distinguish Text-String and Quoted-String. - private static final int TYPE_TEXT_STRING = 0; - private static final int TYPE_QUOTED_STRING = 1; - private static final int TYPE_TOKEN_STRING = 2; - - /** - * Specify the part position. - */ - private static final int THE_FIRST_PART = 0; - private static final int THE_LAST_PART = 1; - - /** - * The pdu data. - */ - private ByteArrayInputStream mPduDataStream = null; - - /** - * Store pdu headers - */ - private PduHeaders mHeaders = null; - - /** - * Store pdu parts. - */ - private PduBody mBody = null; - - /** - * Store the "type" parameter in "Content-Type" header field. - */ - private static byte[] mTypeParam = null; - - /** - * Store the "start" parameter in "Content-Type" header field. - */ - private static byte[] mStartParam = null; - - /** - * The log tag. - */ - private static final String LOG_TAG = "PduParser"; - private static final boolean LOCAL_LOGV = true; - - /** - * Constructor. - * - * @param pduDataStream pdu data to be parsed - */ - public PduParser(byte[] pduDataStream) { - mPduDataStream = new ByteArrayInputStream(pduDataStream); - } - - /** - * Parse the pdu. - * - * @return the pdu structure if parsing successfully. - * null if parsing error happened or mandatory fields are not set. - */ - public GenericPdu parse(){ - Log.w("PduParser", "parse() called..."); - if (mPduDataStream == null) { - return null; - } - - /* parse headers */ - mHeaders = parseHeaders(mPduDataStream); - if (null == mHeaders) { - // Parse headers failed. - return null; - } - - /* get the message type */ - int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check mandatory header fields */ - if (false == checkMandatoryHeader(mHeaders)) { - log("check mandatory headers failed!"); - return null; - } - - Log.w("PduParser", "Message Type: " + messageType); - if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) || - (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) { - /* need to parse the parts */ - Log.w("PduParser", "Parsing parts..."); - mBody = parseParts(mPduDataStream); - if (null == mBody) { - // Parse parts failed. - return null; - } - } - - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - SendReq sendReq = new SendReq(mHeaders, mBody); - return sendReq; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - SendConf sendConf = new SendConf(mHeaders); - return sendConf; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - NotificationInd notificationInd = - new NotificationInd(mHeaders); - return notificationInd; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - NotifyRespInd notifyRespInd = - new NotifyRespInd(mHeaders); - return notifyRespInd; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - RetrieveConf retrieveConf = - new RetrieveConf(mHeaders, mBody); - - byte[] contentType = retrieveConf.getContentType(); - if (null == contentType) { - return null; - } - String ctTypeStr = new String(contentType); - if (ctTypeStr.equals(ContentType.MULTIPART_MIXED) - || ctTypeStr.equals(ContentType.MULTIPART_RELATED) - || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // The MMS content type must be "application/vnd.wap.multipart.mixed" - // or "application/vnd.wap.multipart.related" - // or "application/vnd.wap.multipart.alternative" - return retrieveConf; - } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // "application/vnd.wap.multipart.alternative" - // should take only the first part. - PduPart firstPart = mBody.getPart(0); - mBody.removeAll(); - mBody.addPart(0, firstPart); - return retrieveConf; - } - return null; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - DeliveryInd deliveryInd = - new DeliveryInd(mHeaders); - return deliveryInd; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - AcknowledgeInd acknowledgeInd = - new AcknowledgeInd(mHeaders); - return acknowledgeInd; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - ReadOrigInd readOrigInd = - new ReadOrigInd(mHeaders); - return readOrigInd; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - ReadRecInd readRecInd = - new ReadRecInd(mHeaders); - return readRecInd; - default: - log("Parser doesn't support this message type in this version!"); - return null; - } - } - - /** - * Parse pdu headers. - * - * @param pduDataStream pdu data input stream - * @return headers in PduHeaders structure, null when parse fail - */ - protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){ - if (pduDataStream == null) { - return null; - } - - boolean keepParsing = true; - PduHeaders headers = new PduHeaders(); - - while (keepParsing && (pduDataStream.available() > 0)) { - pduDataStream.mark(1); - int headerField = extractByteValue(pduDataStream); - /* parse custom text header */ - if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { - pduDataStream.reset(); - byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); - } - /* we should ignore it at the moment */ - continue; - } - switch (headerField) { - case PduHeaders.MESSAGE_TYPE: - { - int messageType = extractByteValue(pduDataStream); - switch (messageType) { - // We don't support these kind of messages now. - case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: - case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: - case PduHeaders.MESSAGE_TYPE_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: - case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: - return null; - } - try { - headers.setOctet(messageType, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + messageType + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - /* Octect value */ - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.ADAPTATION_ALLOWED: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.DRM_CONTENT: - case PduHeaders.DISTRIBUTION_INDICATOR: - case PduHeaders.QUOTAS: - case PduHeaders.READ_REPORT: - case PduHeaders.STORE: - case PduHeaders.STORED: - case PduHeaders.TOTALS: - case PduHeaders.SENDER_VISIBILITY: - case PduHeaders.READ_STATUS: - case PduHeaders.CANCEL_STATUS: - case PduHeaders.PRIORITY: - case PduHeaders.STATUS: - case PduHeaders.REPLY_CHARGING: - case PduHeaders.MM_STATE: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE: - case PduHeaders.CONTENT_CLASS: - case PduHeaders.RETRIEVE_STATUS: - case PduHeaders.STORE_STATUS: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.RESPONSE_STATUS: - { - int value = extractByteValue(pduDataStream); - - try { - headers.setOctet(value, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + value + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - /* Long-Integer */ - case PduHeaders.DATE: - case PduHeaders.REPLY_CHARGING_SIZE: - case PduHeaders.MESSAGE_SIZE: - { - try { - long value = parseLongInteger(pduDataStream); - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Integer-Value */ - case PduHeaders.MESSAGE_COUNT: - case PduHeaders.START: - case PduHeaders.LIMIT: - { - try { - long value = parseIntegerValue(pduDataStream); - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Text-String */ - case PduHeaders.TRANSACTION_ID: - case PduHeaders.REPLY_CHARGING_ID: - case PduHeaders.AUX_APPLIC_ID: - case PduHeaders.APPLIC_ID: - case PduHeaders.REPLY_APPLIC_ID: - /** - * The next three header fields are email addresses - * as defined in RFC2822, - * not including the characters "<" and ">" - */ - case PduHeaders.MESSAGE_ID: - case PduHeaders.REPLACE_ID: - case PduHeaders.CANCEL_ID: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.CONTENT_LOCATION: - { - byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != value) { - try { - headers.setTextString(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - break; - } - - /* Encoded-string-value */ - case PduHeaders.SUBJECT: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT: - case PduHeaders.RETRIEVE_TEXT: - case PduHeaders.STATUS_TEXT: - case PduHeaders.STORE_STATUS_TEXT: - /* the next one is not support - * M-Mbox-Delete.conf and M-Delete.conf now */ - case PduHeaders.RESPONSE_TEXT: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - try { - headers.setEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch (RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Addressing model */ - case PduHeaders.BCC: - case PduHeaders.CC: - case PduHeaders.TO: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - byte[] address = value.getTextString(); - if (null != address) { - String str = new String(address); - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - value.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - - try { - headers.appendEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) */ - case PduHeaders.DELIVERY_TIME: - case PduHeaders.EXPIRY: - case PduHeaders.REPLY_CHARGING_DEADLINE: - { - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Absolute-token or Relative-token */ - int token = extractByteValue(pduDataStream); - - /* Date-value or Delta-seconds-value */ - long timeValue; - try { - timeValue = parseLongInteger(pduDataStream); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - if (PduHeaders.VALUE_RELATIVE_TOKEN == token) { - /* need to convert the Delta-seconds-value - * into Date-value */ - timeValue = System.currentTimeMillis()/1000 + timeValue; - } - - try { - headers.setLongInteger(timeValue, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.FROM: { - /* From-value = - * Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - */ - EncodedStringValue from = null; - parseValueLength(pduDataStream); /* parse value-length */ - - /* Address-present-token or Insert-address-token */ - int fromToken = extractByteValue(pduDataStream); - - /* Address-present-token or Insert-address-token */ - if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) { - /* Encoded-string-value */ - from = parseEncodedStringValue(pduDataStream); - if (null != from) { - byte[] address = from.getTextString(); - if (null != address) { - String str = new String(address); - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - from.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - } - } else { - try { - from = new EncodedStringValue( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()); - } catch(NullPointerException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - - try { - headers.setEncodedStringValue(from, PduHeaders.FROM); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - break; - } - - case PduHeaders.MESSAGE_CLASS: { - /* Message-class-value = Class-identifier | Token-text */ - pduDataStream.mark(1); - int messageClass = extractByteValue(pduDataStream); - - if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { - /* Class-identifier */ - try { - if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } else { - /* Token-text */ - pduDataStream.reset(); - byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != messageClassString) { - try { - headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - } - break; - } - - case PduHeaders.MMS_VERSION: { - int version = parseShortInteger(pduDataStream); - - try { - headers.setOctet(version, PduHeaders.MMS_VERSION); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + version + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_BY: { - /* Previously-sent-by-value = - * Value-length Forwarded-count-value Encoded-string-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* parse Encoded-string-value */ - EncodedStringValue previouslySentBy = - parseEncodedStringValue(pduDataStream); - if (null != previouslySentBy) { - try { - headers.setEncodedStringValue(previouslySentBy, - PduHeaders.PREVIOUSLY_SENT_BY); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_DATE: { - /* Previously-sent-date-value = - * Value-length Forwarded-count-value Date-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* Date-value */ - try { - long perviouslySentDate = parseLongInteger(pduDataStream); - headers.setLongInteger(perviouslySentDate, - PduHeaders.PREVIOUSLY_SENT_DATE); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.MM_FLAGS: { - /* MM-flags-value = - * Value-length - * ( Add-token | Remove-token | Filter-token ) - * Encoded-string-value - */ - - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Add-token | Remove-token | Filter-token */ - extractByteValue(pduDataStream); - - /* Encoded-string-value */ - parseEncodedStringValue(pduDataStream); - - /* not store this header filed in "headers", - * because now PduHeaders doesn't support it */ - break; - } - - /* Value-length - * (Message-total-token | Size-total-token) Integer-Value */ - case PduHeaders.MBOX_TOTALS: - case PduHeaders.MBOX_QUOTAS: - { - /* Value-length */ - parseValueLength(pduDataStream); - - /* Message-total-token | Size-total-token */ - extractByteValue(pduDataStream); - - /*Integer-Value*/ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* not store these headers filed in "headers", - because now PduHeaders doesn't support them */ - break; - } - - case PduHeaders.ELEMENT_DESCRIPTOR: { - parseContentType(pduDataStream, null); - - /* not store this header filed in "headers", - because now PduHeaders doesn't support it */ - break; - } - - case PduHeaders.CONTENT_TYPE: { - HashMap map = - new HashMap(); - byte[] contentType = - parseContentType(pduDataStream, map); - - if (null != contentType) { - try { - headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - - /* get start parameter */ - mStartParam = (byte[]) map.get(PduPart.P_START); - - /* get charset parameter */ - mTypeParam= (byte[]) map.get(PduPart.P_TYPE); - - keepParsing = false; - break; - } - - case PduHeaders.CONTENT: - case PduHeaders.ADDITIONAL_HEADERS: - case PduHeaders.ATTRIBUTES: - default: { - log("Unknown header"); - } - } - } - - return headers; - } - - /** - * Parse pdu parts. - * - * @param pduDataStream pdu data input stream - * @return parts in PduBody structure - */ - protected static PduBody parseParts(ByteArrayInputStream pduDataStream) { - if (pduDataStream == null) { - return null; - } - - int count = parseUnsignedInt(pduDataStream); // get the number of parts - PduBody body = new PduBody(); - - for (int i = 0 ; i < count ; i++) { - int headerLength = parseUnsignedInt(pduDataStream); - int dataLength = parseUnsignedInt(pduDataStream); - PduPart part = new PduPart(); - int startPos = pduDataStream.available(); - if (startPos <= 0) { - // Invalid part. - return null; - } - - /* parse part's content-type */ - HashMap map = new HashMap(); - byte[] contentType = parseContentType(pduDataStream, map); - if (null != contentType) { - part.setContentType(contentType); - } else { - part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*" - } - - /* get name parameter */ - byte[] name = (byte[]) map.get(PduPart.P_NAME); - if (null != name) { - part.setName(name); - } - - /* get charset parameter */ - Integer charset = (Integer) map.get(PduPart.P_CHARSET); - if (null != charset) { - part.setCharset(charset); - } - - /* parse part's headers */ - int endPos = pduDataStream.available(); - int partHeaderLen = headerLength - (startPos - endPos); - if (partHeaderLen > 0) { - if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) { - // Parse part header faild. - return null; - } - } else if (partHeaderLen < 0) { - // Invalid length of content-type. - return null; - } - - /* FIXME: check content-id, name, filename and content location, - * if not set anyone of them, generate a default content-location - */ - if ((null == part.getContentLocation()) - && (null == part.getName()) - && (null == part.getFilename()) - && (null == part.getContentId())) { - part.setContentLocation(Long.toOctalString( - System.currentTimeMillis()).getBytes()); - } - - /* get part's data */ - if (dataLength > 0) { - byte[] partData = new byte[dataLength]; - String partContentType = new String(part.getContentType()); - pduDataStream.read(partData, 0, dataLength); - if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { - // parse "multipart/vnd.wap.multipart.alternative". - PduBody childBody = parseParts(new ByteArrayInputStream(partData)); - // take the first part of children. - part = childBody.getPart(0); - } else { - // Check Content-Transfer-Encoding. - byte[] partDataEncoding = part.getContentTransferEncoding(); - if (null != partDataEncoding) { - String encoding = new String(partDataEncoding); - if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { - // Decode "base64" into "binary". - partData = Base64.decodeBase64(partData); - } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { - // Decode "quoted-printable" into "binary". - partData = QuotedPrintable.decodeQuotedPrintable(partData); - } else { - // "binary" is the default encoding. - } - } - if (null == partData) { - log("Decode part data error!"); - return null; - } - part.setData(partData); - } - } - - /* add this part to body */ - if (THE_FIRST_PART == checkPartPosition(part)) { - /* this is the first part */ - body.addPart(0, part); - } else { - /* add the part to the end */ - body.addPart(part); - } - } - - return body; - } - - /** - * Log status. - * - * @param text log information - */ - private static void log(String text) { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, text); - } - } - - /** - * Parse unsigned integer. - * - * @param pduDataStream pdu data input stream - * @return the integer, -1 when failed - */ - protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - assert(null != pduDataStream); - int result = 0; - int temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - - while((temp & 0x80) != 0) { - result = result << 7; - result |= temp & 0x7F; - temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - } - - result = result << 7; - result |= temp & 0x7F; - - return result; - } - - /** - * Parse value length. - * - * @param pduDataStream pdu data input stream - * @return the integer - */ - protected static int parseValueLength(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Value-length = Short-length | (Length-quote Length) - * Short-length = - * Length-quote = - * Length = Uintvar-integer - * Uintvar-integer = 1*5 OCTET - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - - if (first <= SHORT_LENGTH_MAX) { - return first; - } else if (first == LENGTH_QUOTE) { - return parseUnsignedInt(pduDataStream); - } - - throw new RuntimeException ("Value length > LENGTH_QUOTE!"); - } - - /** - * Parse encoded string value. - * - * @param pduDataStream pdu data input stream - * @return the EncodedStringValue - */ - protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){ - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - EncodedStringValue returnValue = null; - int charset = 0; - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - if (first == 0) { - return null; // Blank subject, bail. - } - - pduDataStream.reset(); - if (first < TEXT_MIN) { - parseValueLength(pduDataStream); - - charset = parseShortInteger(pduDataStream); //get the "Charset" - } - - byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - try { - if (0 != charset) { - returnValue = new EncodedStringValue(charset, textString); - } else { - returnValue = new EncodedStringValue(textString); - } - } catch(Exception e) { - return null; - } - - return returnValue; - } - - /** - * Parse Text-String or Quoted-String. - * - * @param pduDataStream pdu data input stream - * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING - * @return the string without End-of-string in byte array - */ - protected static byte[] parseWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - /** - * From wap-230-wsp-20010705-a.pdf - * Text-string = [Quote] *TEXT End-of-string - * If the first character in the TEXT is in the range of 128-255, - * a Quote character must precede it. - * Otherwise the Quote character must be omitted. - * The Quote is not part of the contents. - * Quote = - * End-of-string = - * - * Quoted-string = *TEXT End-of-string - * - * Token-text = Token End-of-string - */ - - // Mark supposed beginning of Text-string - // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG - pduDataStream.mark(1); - - // Check first char - int temp = pduDataStream.read(); - assert(-1 != temp); - if ((TYPE_QUOTED_STRING == stringType) && - (QUOTED_STRING_FLAG == temp)) { - // Mark again if QUOTED_STRING_FLAG and ignore it - pduDataStream.mark(1); - } else if ((TYPE_TEXT_STRING == stringType) && - (QUOTE == temp)) { - // Mark again if QUOTE and ignore it - pduDataStream.mark(1); - } else { - // Otherwise go back to origin - pduDataStream.reset(); - } - - // We are now definitely at the beginning of string - /** - * Return *TOKEN or *TEXT (Text-String without QUOTE, - * Quoted-String without QUOTED_STRING_FLAG and without End-of-string) - */ - return getWapString(pduDataStream, stringType); - } - - /** - * Check TOKEN data defined in RFC2616. - * @param ch checking data - * @return true when ch is TOKEN, false when ch is not TOKEN - */ - protected static boolean isTokenCharacter(int ch) { - /** - * Token = 1* - * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64) - * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34) - * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61) - * | "{"(123) | "}"(125) | SP(32) | HT(9) - * CHAR = - * CTL = - * SP = - * HT = - */ - if((ch < 33) || (ch > 126)) { - return false; - } - - switch(ch) { - case '"': /* '"' */ - case '(': /* '(' */ - case ')': /* ')' */ - case ',': /* ',' */ - case '/': /* '/' */ - case ':': /* ':' */ - case ';': /* ';' */ - case '<': /* '<' */ - case '=': /* '=' */ - case '>': /* '>' */ - case '?': /* '?' */ - case '@': /* '@' */ - case '[': /* '[' */ - case '\\': /* '\' */ - case ']': /* ']' */ - case '{': /* '{' */ - case '}': /* '}' */ - return false; - } - - return true; - } - - /** - * Check TEXT data defined in RFC2616. - * @param ch checking data - * @return true when ch is TEXT, false when ch is not TEXT - */ - protected static boolean isText(int ch) { - /** - * TEXT = - * CTL = - * LWS = [CRLF] 1*( SP | HT ) - * CRLF = CR LF - * CR = - * LF = - */ - if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) { - return true; - } - - switch(ch) { - case '\t': /* '\t' */ - case '\n': /* '\n' */ - case '\r': /* '\r' */ - return true; - } - - return false; - } - - protected static byte[] getWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int temp = pduDataStream.read(); - assert(-1 != temp); - while((-1 != temp) && ('\0' != temp)) { - // check each of the character - if (stringType == TYPE_TOKEN_STRING) { - if (isTokenCharacter(temp)) { - out.write(temp); - } - } else { - if (isText(temp)) { - out.write(temp); - } - } - - temp = pduDataStream.read(); - assert(-1 != temp); - } - - if (out.size() > 0) { - return out.toByteArray(); - } - - return null; - } - - /** - * Extract a byte value from the input stream. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - protected static int extractByteValue(ByteArrayInputStream pduDataStream) { - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0xFF; - } - - /** - * Parse Short-Integer. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - protected static int parseShortInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Short-integer = OCTET - * Integers in range 0-127 shall be encoded as a one - * octet value with the most significant bit set to one (1xxx xxxx) - * and with the value in the remaining least significant bits. - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0x7F; - } - - /** - * Parse Long-Integer. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseLongInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Long-integer = Short-length Multi-octet-integer - * The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * The content octets shall be an unsigned integer value - * with the most significant octet encoded first (big-endian representation). - * The minimum number of octets must be used to encode the value. - * Short-length = - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int count = temp & 0xFF; - - if (count > LONG_INTEGER_LENGTH_MAX) { - throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); - } - - long result = 0; - - for (int i = 0 ; i < count ; i++) { - temp = pduDataStream.read(); - assert(-1 != temp); - result <<= 8; - result += (temp & 0xFF); - } - - return result; - } - - /** - * Parse Integer-Value. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Integer-Value = Short-integer | Long-integer - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - if (temp > SHORT_INTEGER_MAX) { - return parseShortInteger(pduDataStream); - } else { - return parseLongInteger(pduDataStream); - } - } - - /** - * To skip length of the wap value. - * - * @param pduDataStream pdu data input stream - * @param length area size - * @return the values in this area - */ - protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) { - assert(null != pduDataStream); - byte[] area = new byte[length]; - int readLen = pduDataStream.read(area, 0, length); - if (readLen < length) { //The actually read length is lower than the length - return -1; - } else { - return readLen; - } - } - - /** - * Parse content type parameters. For now we just support - * four parameters used in mms: "type", "start", "name", "charset". - * - * @param pduDataStream pdu data input stream - * @param map to store parameters of Content-Type field - * @param length length of all the parameters - */ - protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream, - HashMap map, Integer length) { - /** - * From wap-230-wsp-20010705-a.pdf - * Parameter = Typed-parameter | Untyped-parameter - * Typed-parameter = Well-known-parameter-token Typed-value - * the actual expected type of the value is implied by the well-known parameter - * Well-known-parameter-token = Integer-value - * the code values used for parameters are specified in the Assigned Numbers appendix - * Typed-value = Compact-value | Text-value - * In addition to the expected type, there may be no value. - * If the value cannot be encoded using the expected type, it shall be encoded as text. - * Compact-value = Integer-value | - * Date-value | Delta-seconds-value | Q-value | Version-value | - * Uri-value - * Untyped-parameter = Token-text Untyped-value - * the type of the value is unknown, but it shall be encoded as an integer, - * if that is possible. - * Untyped-value = Integer-value | Text-value - */ - assert(null != pduDataStream); - assert(length > 0); - - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int param = pduDataStream.read(); - assert(-1 != param); - lastLen--; - - switch (param) { - /** - * From rfc2387, chapter 3.1 - * The type parameter must be specified and its value is the MIME media - * type of the "root" body part. It permits a MIME user agent to - * determine the content-type without reference to the enclosed body - * part. If the value of the type parameter and the root body part's - * content-type differ then the User Agent's behavior is undefined. - * - * From wap-230-wsp-20010705-a.pdf - * type = Constrained-encoding - * Constrained-encoding = Extension-Media | Short-integer - * Extension-media = *TEXT End-of-string - */ - case PduPart.P_TYPE: - case PduPart.P_CT_MR_TYPE: - pduDataStream.mark(1); - int first = extractByteValue(pduDataStream); - pduDataStream.reset(); - if (first > TEXT_MAX) { - // Short-integer (well-known type) - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { - byte[] type = (PduContentTypes.contentTypes[index]).getBytes(); - map.put(PduPart.P_TYPE, type); - } else { - //not support this type, ignore it. - } - } else { - // Text-String (extension-media) - byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != type) && (null != map)) { - map.put(PduPart.P_TYPE, type); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3. - * Start Parameter Referring to Presentation - * - * From rfc2387, chapter 3.2 - * The start parameter, if given, is the content-ID of the compound - * object's "root". If not present the "root" is the first body part in - * the Multipart/Related entity. The "root" is the element the - * applications processes first. - * - * From wap-230-wsp-20010705-a.pdf - * start = Text-String - */ - case PduPart.P_START: - case PduPart.P_DEP_START: - byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != start) && (null != map)) { - map.put(PduPart.P_START, start); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * In creation, the character set SHALL be either us-ascii - * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode]. - * In retrieval, both us-ascii and utf-8 SHALL be supported. - * - * From wap-230-wsp-20010705-a.pdf - * charset = Well-known-charset|Text-String - * Well-known-charset = Any-charset | Integer-value - * Both are encoded using values from Character Set - * Assignments table in Assigned Numbers - * Any-charset = - * Equivalent to the special RFC2616 charset value "*" - */ - case PduPart.P_CHARSET: - pduDataStream.mark(1); - int firstValue = extractByteValue(pduDataStream); - pduDataStream.reset(); - //Check first char - if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) || - (END_STRING_FLAG == firstValue)) { - //Text-String (extension-charset) - byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING); - try { - int charsetInt = CharacterSets.getMibEnumValue( - new String(charsetStr)); - map.put(PduPart.P_CHARSET, charsetInt); - } catch (UnsupportedEncodingException e) { - // Not a well-known charset, use "*". - Log.e(LOG_TAG, Arrays.toString(charsetStr), e); - map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); - } - } else { - //Well-known-charset - int charset = (int) parseIntegerValue(pduDataStream); - if (map != null) { - map.put(PduPart.P_CHARSET, charset); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * - * From wap-230-wsp-20010705-a.pdf - * name = Text-String - */ - case PduPart.P_DEP_NAME: - case PduPart.P_NAME: - byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != name) && (null != map)) { - map.put(PduPart.P_NAME, name); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Content-Type parameter"); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } else { - lastLen = 0; - } - break; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } - } - - /** - * Parse content type. - * - * @param pduDataStream pdu data input stream - * @param map to store parameters in Content-Type header field - * @return Content-Type value - */ - protected static byte[] parseContentType(ByteArrayInputStream pduDataStream, - HashMap map) { - /** - * From wap-230-wsp-20010705-a.pdf - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - */ - assert(null != pduDataStream); - - byte[] contentType = null; - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - - int cur = (temp & 0xFF); - - if (cur < TEXT_MIN) { - int length = parseValueLength(pduDataStream); - int startPos = pduDataStream.available(); - pduDataStream.mark(1); - temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - int first = (temp & 0xFF); - - if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else if (first > TEXT_MAX) { - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { //well-known type - contentType = (PduContentTypes.contentTypes[index]).getBytes(); - } else { - pduDataStream.reset(); - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } - } else { - Log.e(LOG_TAG, "Corrupt content-type"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - - int endPos = pduDataStream.available(); - int parameterLen = length - (startPos - endPos); - if (parameterLen > 0) {//have parameters - parseContentTypeParams(pduDataStream, map, parameterLen); - } - - if (parameterLen < 0) { - Log.e(LOG_TAG, "Corrupt MMS message"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - } else if (cur <= TEXT_MAX) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else { - contentType = - (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes(); - } - - return contentType; - } - - /** - * Parse part's headers. - * - * @param pduDataStream pdu data input stream - * @param part to store the header informations of the part - * @param length length of the headers - * @return true if parse successfully, false otherwise - */ - protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream, - PduPart part, int length) { - assert(null != pduDataStream); - assert(null != part); - assert(length > 0); - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2. - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * In decoding, name-parameter of Content-Type SHALL be used if available. - * If name-parameter of Content-Type is not available, - * filename parameter of Content-Disposition header SHALL be used if available. - * If neither name-parameter of Content-Type header nor filename parameter - * of Content-Disposition header is available, - * Content-Location header SHALL be used if available. - * - * Within SMIL part the reference to the media object parts SHALL use - * either Content-ID or Content-Location mechanism [RFC2557] - * and the corresponding WSP part headers in media object parts - * contain the corresponding definitions. - */ - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int header = pduDataStream.read(); - assert(-1 != header); - lastLen--; - - if (header > TEXT_MAX) { - // Number assigned headers. - switch (header) { - case PduPart.P_CONTENT_LOCATION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-location-value = Uri-value - */ - byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != contentLocation) { - part.setContentLocation(contentLocation); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_CONTENT_ID: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-ID-value = Quoted-string - */ - byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING); - if (null != contentId) { - part.setContentId(contentId); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_DEP_CONTENT_DISPOSITION: - case PduPart.P_CONTENT_DISPOSITION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-disposition-value = Value-length Disposition *(Parameter) - * Disposition = Form-data | Attachment | Inline | Token-text - * Form-data = - * Attachment = - * Inline = - */ - - /* - * some carrier mmsc servers do not support content_disposition - * field correctly - */ - Resources resources = Resources.getSystem(); - int id = resources.getIdentifier("config_mms_content_disposition_support", - "boolean", "android"); - - Log.w("PduParser", "config_mms_content_disposition_support ID: " + id); - boolean contentDisposition = (id != 0) && (resources.getBoolean(id)); - - Log.w("PduParser", "Content Disposition supported: " + contentDisposition); - - if (contentDisposition) { - int len = parseValueLength(pduDataStream); - pduDataStream.mark(1); - int thisStartPos = pduDataStream.available(); - int thisEndPos = 0; - int value = pduDataStream.read(); - - if (value == PduPart.P_DISPOSITION_FROM_DATA ) { - part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA); - } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) { - part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT); - } else if (value == PduPart.P_DISPOSITION_INLINE) { - part.setContentDisposition(PduPart.DISPOSITION_INLINE); - } else { - pduDataStream.reset(); - /* Token-text */ - part.setContentDisposition(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* get filename parameter and skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - value = pduDataStream.read(); - if (value == PduPart.P_FILENAME) { //filename is text-string - part.setFilename(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - int last = len - (thisStartPos - thisEndPos); - byte[] temp = new byte[last]; - pduDataStream.read(temp, 0, last); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - break; - } - } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) { - // Not assigned header. - byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING); - byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - // Check the header whether it is "Content-Transfer-Encoding". - if (true == - PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) { - part.setContentTransferEncoding(tempValue); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } else { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - // Skip all headers of this part. - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - - return true; - } - - /** - * Check the position of a specified part. - * - * @param part the part to be checked - * @return part position, THE_FIRST_PART when it's the - * first one, THE_LAST_PART when it's the last one. - */ - private static int checkPartPosition(PduPart part) { - assert(null != part); - if ((null == mTypeParam) && - (null == mStartParam)) { - return THE_LAST_PART; - } - - /* check part's content-id */ - if (null != mStartParam) { - byte[] contentId = part.getContentId(); - if (null != contentId) { - if (true == Arrays.equals(mStartParam, contentId)) { - return THE_FIRST_PART; - } - } - } - - /* check part's content-type */ - if (null != mTypeParam) { - byte[] contentType = part.getContentType(); - if (null != contentType) { - if (true == Arrays.equals(mTypeParam, contentType)) { - return THE_FIRST_PART; - } - } - } - - return THE_LAST_PART; - } - - /** - * Check mandatory headers of a pdu. - * - * @param headers pdu headers - * @return true if the pdu has all of the mandatory headers, false otherwise. - */ - protected static boolean checkMandatoryHeader(PduHeaders headers) { - if (null == headers) { - return false; - } - - /* get message type */ - int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check Mms-Version field */ - int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION); - if (0 == mmsVersion) { - // Every message should have Mms-Version field. - return false; - } - - /* check mandatory header fields */ - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - // Content-Type field. - byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == srContentType) { - return false; - } - - // From field. - EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == srFrom) { - return false; - } - - // Transaction-Id field. - byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == srTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - // Response-Status field. - int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS); - if (0 == scResponseStatus) { - return false; - } - - // Transaction-Id field. - byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == scTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - // Content-Location field. - byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION); - if (null == niContentLocation) { - return false; - } - - // Expiry field. - long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY); - if (-1 == niExpiry) { - return false; - } - - // Message-Class field. - byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS); - if (null == niMessageClass) { - return false; - } - - // Message-Size field. - long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE); - if (-1 == niMessageSize) { - return false; - } - - // Transaction-Id field. - byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == niTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - // Status field. - int nriStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == nriStatus) { - return false; - } - - // Transaction-Id field. - byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == nriTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - // Content-Type field. - byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == rcContentType) { - return false; - } - - // Date field. - long rcDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == rcDate) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - // Date field. - long diDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == diDate) { - return false; - } - - // Message-Id field. - byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == diMessageId) { - return false; - } - - // Status field. - int diStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == diStatus) { - return false; - } - - // To field. - EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == diTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - // Transaction-Id field. - byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == aiTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - // Date field. - long roDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == roDate) { - return false; - } - - // From field. - EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == roFrom) { - return false; - } - - // Message-Id field. - byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == roMessageId) { - return false; - } - - // Read-Status field. - int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == roReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == roTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - // From field. - EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == rrFrom) { - return false; - } - - // Message-Id field. - byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == rrMessageId) { - return false; - } - - // Read-Status field. - int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == rrReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == rrTo) { - return false; - } - - break; - default: - // Parser doesn't support this message type in this version. - return false; - } - - return true; - } -} diff --git a/src/ws/com/google/android/mms/pdu/PduPart.java b/src/ws/com/google/android/mms/pdu/PduPart.java deleted file mode 100644 index ffdb3b6305..0000000000 --- a/src/ws/com/google/android/mms/pdu/PduPart.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import android.net.Uri; - -import java.util.HashMap; -import java.util.Map; - -/** - * The pdu part. - */ -public class PduPart { - /** - * Well-Known Parameters. - */ - public static final int P_Q = 0x80; - public static final int P_CHARSET = 0x81; - public static final int P_LEVEL = 0x82; - public static final int P_TYPE = 0x83; - public static final int P_DEP_NAME = 0x85; - public static final int P_DEP_FILENAME = 0x86; - public static final int P_DIFFERENCES = 0x87; - public static final int P_PADDING = 0x88; - // This value of "TYPE" s used with Content-Type: multipart/related - public static final int P_CT_MR_TYPE = 0x89; - public static final int P_DEP_START = 0x8A; - public static final int P_DEP_START_INFO = 0x8B; - public static final int P_DEP_COMMENT = 0x8C; - public static final int P_DEP_DOMAIN = 0x8D; - public static final int P_MAX_AGE = 0x8E; - public static final int P_DEP_PATH = 0x8F; - public static final int P_SECURE = 0x90; - public static final int P_SEC = 0x91; - public static final int P_MAC = 0x92; - public static final int P_CREATION_DATE = 0x93; - public static final int P_MODIFICATION_DATE = 0x94; - public static final int P_READ_DATE = 0x95; - public static final int P_SIZE = 0x96; - public static final int P_NAME = 0x97; - public static final int P_FILENAME = 0x98; - public static final int P_START = 0x99; - public static final int P_START_INFO = 0x9A; - public static final int P_COMMENT = 0x9B; - public static final int P_DOMAIN = 0x9C; - public static final int P_PATH = 0x9D; - - /** - * Header field names. - */ - public static final int P_CONTENT_TYPE = 0x91; - public static final int P_CONTENT_LOCATION = 0x8E; - public static final int P_CONTENT_ID = 0xC0; - public static final int P_DEP_CONTENT_DISPOSITION = 0xAE; - public static final int P_CONTENT_DISPOSITION = 0xC5; - // The next header is unassigned header, use reserved header(0x48) value. - public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8; - - /** - * Content=Transfer-Encoding string. - */ - public static final String CONTENT_TRANSFER_ENCODING = - "Content-Transfer-Encoding"; - - /** - * Value of Content-Transfer-Encoding. - */ - public static final String P_BINARY = "binary"; - public static final String P_7BIT = "7bit"; - public static final String P_8BIT = "8bit"; - public static final String P_BASE64 = "base64"; - public static final String P_QUOTED_PRINTABLE = "quoted-printable"; - - /** - * Value of disposition can be set to PduPart when the value is octet in - * the PDU. - * "from-data" instead of Form-data. - * "attachment" instead of Attachment. - * "inline" instead of Inline. - */ - static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes(); - static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes(); - static final byte[] DISPOSITION_INLINE = "inline".getBytes(); - - /** - * Content-Disposition value. - */ - public static final int P_DISPOSITION_FROM_DATA = 0x80; - public static final int P_DISPOSITION_ATTACHMENT = 0x81; - public static final int P_DISPOSITION_INLINE = 0x82; - - /** - * Header of part. - */ - private Map mPartHeader = null; - - /** - * Data uri. - */ - private Uri mUri = null; - - /** - * Part data. - */ - private byte[] mPartData = null; - - private static final String TAG = "PduPart"; - - /** - * Empty Constructor. - */ - public PduPart() { - mPartHeader = new HashMap(); - } - - /** - * Set part data. The data are stored as byte array. - * - * @param data the data - */ - public void setData(byte[] data) { - if(data == null) { - return; - } - - mPartData = new byte[data.length]; - System.arraycopy(data, 0, mPartData, 0, data.length); - } - - /** - * @return A copy of the part data or null if the data wasn't set or - * the data is stored as Uri. - * @see #getDataUri - */ - public byte[] getData() { - if(mPartData == null) { - return null; - } - - byte[] byteArray = new byte[mPartData.length]; - System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length); - return byteArray; - } - - /** - * Set data uri. The data are stored as Uri. - * - * @param uri the uri - */ - public void setDataUri(Uri uri) { - mUri = uri; - } - - /** - * @return The Uri of the part data or null if the data wasn't set or - * the data is stored as byte array. - * @see #getData - */ - public Uri getDataUri() { - return mUri; - } - - /** - * Set Content-id value - * - * @param contentId the content-id value - * @throws NullPointerException if the value is null. - */ - public void setContentId(byte[] contentId) { - if((contentId == null) || (contentId.length == 0)) { - throw new IllegalArgumentException( - "Content-Id may not be null or empty."); - } - - if ((contentId.length > 1) - && ((char) contentId[0] == '<') - && ((char) contentId[contentId.length - 1] == '>')) { - mPartHeader.put(P_CONTENT_ID, contentId); - return; - } - - // Insert beginning '<' and trailing '>' for Content-Id. - byte[] buffer = new byte[contentId.length + 2]; - buffer[0] = (byte) (0xff & '<'); - buffer[buffer.length - 1] = (byte) (0xff & '>'); - System.arraycopy(contentId, 0, buffer, 1, contentId.length); - mPartHeader.put(P_CONTENT_ID, buffer); - } - - /** - * Get Content-id value. - * - * @return the value - */ - public byte[] getContentId() { - return (byte[]) mPartHeader.get(P_CONTENT_ID); - } - - /** - * Set Char-set value. - * - * @param charset the value - */ - public void setCharset(int charset) { - mPartHeader.put(P_CHARSET, charset); - } - - /** - * Get Char-set value - * - * @return the charset value. Return 0 if charset was not set. - */ - public int getCharset() { - Integer charset = (Integer) mPartHeader.get(P_CHARSET); - if(charset == null) { - return 0; - } else { - return charset.intValue(); - } - } - - /** - * Set Content-Location value. - * - * @param contentLocation the value - * @throws NullPointerException if the value is null. - */ - public void setContentLocation(byte[] contentLocation) { - if(contentLocation == null) { - throw new NullPointerException("null content-location"); - } - - mPartHeader.put(P_CONTENT_LOCATION, contentLocation); - } - - /** - * Get Content-Location value. - * - * @return the value - * return PduPart.disposition[0] instead of (Form-data). - * return PduPart.disposition[1] instead of (Attachment). - * return PduPart.disposition[2] instead of (Inline). - */ - public byte[] getContentLocation() { - return (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - - /** - * Set Content-Disposition value. - * Use PduPart.disposition[0] instead of (Form-data). - * Use PduPart.disposition[1] instead of (Attachment). - * Use PduPart.disposition[2] instead of (Inline). - * - * @param contentDisposition the value - * @throws NullPointerException if the value is null. - */ - public void setContentDisposition(byte[] contentDisposition) { - if(contentDisposition == null) { - throw new NullPointerException("null content-disposition"); - } - - mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition); - } - - /** - * Get Content-Disposition value. - * - * @return the value - */ - public byte[] getContentDisposition() { - return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION); - } - - /** - * Set Content-Type value. - * - * @param contentType the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] contentType) { - if(contentType == null) { - throw new NullPointerException("null content-type"); - } - - mPartHeader.put(P_CONTENT_TYPE, contentType); - } - - /** - * Get Content-Type value of part. - * - * @return the value - */ - public byte[] getContentType() { - return (byte[]) mPartHeader.get(P_CONTENT_TYPE); - } - - /** - * Set Content-Transfer-Encoding value - * - * @param contentTransferEncoding the value - * @throws NullPointerException if the value is null. - */ - public void setContentTransferEncoding(byte[] contentTransferEncoding) { - if(contentTransferEncoding == null) { - throw new NullPointerException("null content-transfer-encoding"); - } - - mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding); - } - - /** - * Get Content-Transfer-Encoding value. - * - * @return the value - */ - public byte[] getContentTransferEncoding() { - return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING); - } - - /** - * Set Content-type parameter: name. - * - * @param name the name value - * @throws NullPointerException if the value is null. - */ - public void setName(byte[] name) { - if(null == name) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_NAME, name); - } - - /** - * Get content-type parameter: name. - * - * @return the name - */ - public byte[] getName() { - return (byte[]) mPartHeader.get(P_NAME); - } - - /** - * Get Content-disposition parameter: filename - * - * @param fileName the filename value - * @throws NullPointerException if the value is null. - */ - public void setFilename(byte[] fileName) { - if(null == fileName) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_FILENAME, fileName); - } - - /** - * Set Content-disposition parameter: filename - * - * @return the filename - */ - public byte[] getFilename() { - return (byte[]) mPartHeader.get(P_FILENAME); - } - - public String generateLocation() { - // Assumption: At least one of the content-location / name / filename - // or content-id should be set. This is guaranteed by the PduParser - // for incoming messages and by MM composer for outgoing messages. - byte[] location = (byte[]) mPartHeader.get(P_NAME); - if(null == location) { - location = (byte[]) mPartHeader.get(P_FILENAME); - - if (null == location) { - location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - } - - if (null == location) { - byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID); - return "cid:" + new String(contentId); - } else { - return new String(location); - } - } -} - diff --git a/src/ws/com/google/android/mms/pdu/QuotedPrintable.java b/src/ws/com/google/android/mms/pdu/QuotedPrintable.java deleted file mode 100644 index 982a674289..0000000000 --- a/src/ws/com/google/android/mms/pdu/QuotedPrintable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import java.io.ByteArrayOutputStream; - -public class QuotedPrintable { - private static byte ESCAPE_CHAR = '='; - - /** - * Decodes an array quoted-printable characters into an array of original bytes. - * Escaped characters are converted back to their original representation. - * - * - * This function implements a subset of - * quoted-printable encoding specification (rule #1 and rule #2) - * as defined in RFC 1521. - * - * - * @param bytes array of quoted-printable characters - * @return array of original bytes, - * null if quoted-printable decoding is unsuccessful. - */ - public static final byte[] decodeQuotedPrintable(byte[] bytes) { - if (bytes == null) { - return null; - } - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - for (int i = 0; i < bytes.length; i++) { - int b = bytes[i]; - if (b == ESCAPE_CHAR) { - try { - if('\r' == (char)bytes[i + 1] && - '\n' == (char)bytes[i + 2]) { - i += 2; - continue; - } - int u = Character.digit((char) bytes[++i], 16); - int l = Character.digit((char) bytes[++i], 16); - if (u == -1 || l == -1) { - return null; - } - buffer.write((char) ((u << 4) + l)); - } catch (ArrayIndexOutOfBoundsException e) { - return null; - } - } else { - buffer.write(b); - } - } - return buffer.toByteArray(); - } -} diff --git a/src/ws/com/google/android/mms/pdu/ReadOrigInd.java b/src/ws/com/google/android/mms/pdu/ReadOrigInd.java deleted file mode 100644 index 4b16babe45..0000000000 --- a/src/ws/com/google/android/mms/pdu/ReadOrigInd.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -public class ReadOrigInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public ReadOrigInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - ReadOrigInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/ReadRecInd.java b/src/ws/com/google/android/mms/pdu/ReadRecInd.java deleted file mode 100644 index 6bb04c8296..0000000000 --- a/src/ws/com/google/android/mms/pdu/ReadRecInd.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -public class ReadRecInd extends GenericPdu { - /** - * Constructor, used when composing a M-ReadRec.ind pdu. - * - * @param from the from value - * @param messageId the message ID value - * @param mmsVersion current viersion of mms - * @param readStatus the read status value - * @param to the to value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if messageId or to is null. - */ - public ReadRecInd(EncodedStringValue from, - byte[] messageId, - int mmsVersion, - int readStatus, - EncodedStringValue[] to) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - setFrom(from); - setMessageId(messageId); - setMmsVersion(mmsVersion); - setTo(to); - setReadStatus(readStatus); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - ReadRecInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/RetrieveConf.java b/src/ws/com/google/android/mms/pdu/RetrieveConf.java deleted file mode 100644 index e5809ca54b..0000000000 --- a/src/ws/com/google/android/mms/pdu/RetrieveConf.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Retrive.conf Pdu. - */ -public class RetrieveConf extends MultimediaMessagePdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public RetrieveConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - RetrieveConf(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - public RetrieveConf(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get CC value. - * - * @return the value - */ - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Get X-Mms-Retrieve-Status value. - * - * @return the value - */ - public int getRetrieveStatus() { - return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS); - } - - /** - * Set X-Mms-Retrieve-Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setRetrieveStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS); - } - - /** - * Get X-Mms-Retrieve-Text value. - * - * @return the value - */ - public EncodedStringValue getRetrieveText() { - return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT); - } - - /** - * Set X-Mms-Retrieve-Text value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setRetrieveText(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public PreviouslySentByValue getPreviouslySentBy() {return null;} - * public void setPreviouslySentBy(PreviouslySentByValue value) {} - * - * public PreviouslySentDateValue getPreviouslySentDate() {} - * public void setPreviouslySentDate(PreviouslySentDateValue value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/SendConf.java b/src/ws/com/google/android/mms/pdu/SendConf.java deleted file mode 100644 index 4ed3ea71f2..0000000000 --- a/src/ws/com/google/android/mms/pdu/SendConf.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -public class SendConf extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public SendConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - SendConf(PduHeaders headers) { - super(headers); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Response-Status. - * - * @return the value - */ - public int getResponseStatus() { - return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS); - } - - /** - * Set X-Mms-Response-Status. - * - * @param value the values - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setResponseStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getContentLocation() {return null;} - * public void setContentLocation(byte[] value) {} - * - * public EncodedStringValue getResponseText() {return null;} - * public void setResponseText(EncodedStringValue value) {} - * - * public byte getStoreStatus() {return 0x00;} - * public void setStoreStatus(byte value) {} - * - * public byte[] getStoreStatusText() {return null;} - * public void setStoreStatusText(byte[] value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/SendReq.java b/src/ws/com/google/android/mms/pdu/SendReq.java deleted file mode 100644 index ab0a70bf21..0000000000 --- a/src/ws/com/google/android/mms/pdu/SendReq.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * 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 ws.com.google.android.mms.pdu; - -import android.util.Log; - -import ws.com.google.android.mms.InvalidHeaderValueException; - -public class SendReq extends MultimediaMessagePdu { - private static final String TAG = "SendReq"; - - public SendReq() { - super(); - - try { - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setMmsVersion(PduHeaders.CURRENT_MMS_VERSION); - // FIXME: Content-type must be decided according to whether - // SMIL part present. - setContentType("application/vnd.wap.multipart.related".getBytes()); - setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes())); - setTransactionId(generateTransactionId()); - } catch (InvalidHeaderValueException e) { - // Impossible to reach here since all headers we set above are valid. - Log.e(TAG, "Unexpected InvalidHeaderValueException.", e); - throw new RuntimeException(e); - } - } - - private byte[] generateTransactionId() { - String transactionId = "T" + Long.toHexString(System.currentTimeMillis()); - return transactionId.getBytes(); - } - - /** - * Constructor, used when composing a M-Send.req pdu. - * - * @param contentType the content type value - * @param from the from value - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if contentType, form or transactionId is null. - */ - public SendReq(byte[] contentType, - EncodedStringValue from, - int mmsVersion, - byte[] transactionId) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setContentType(contentType); - setFrom(from); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - SendReq(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - public SendReq(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get Bcc value. - * - * @return the value - */ - public EncodedStringValue[] getBcc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.BCC); - } - - /** - * Add a "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addBcc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC); - } - - /** - * Set "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setBcc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC); - } - - /** - * Get CC value. - * - * @return the value - */ - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Set "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setCc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - */ - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get X-Mms-MessageSize value. - * - * Expiry-value = size of message - * - * @return the value - */ - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-MessageSize value. - * - * @param value the value - */ - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Set "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte getAdaptationAllowed() {return 0}; - * public void setAdaptationAllowed(btye value) {}; - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public long getDeliveryTime() {return 0}; - * public void setDeliveryTime(long value) {}; - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getStore() {return 0x00;} - * public void setStore(byte value) {} - */ -} diff --git a/src/ws/com/google/android/mms/pdu/package.html b/src/ws/com/google/android/mms/pdu/package.html deleted file mode 100755 index c9f96a66ab..0000000000 --- a/src/ws/com/google/android/mms/pdu/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -{@hide} - -
Text>
Node
null
HEAD
- *
- * 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 ")" - *
- * Clock values have the following syntax: - *
- * 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] - *
- * Value ::= Number ("." Decimal)? (Text)? - * Number ::= DIGIT+; any positive number - * Decimal ::= DIGIT+; any positive number - * Text ::= CHAR*; any sequence of chars - * DIGIT ::= [0-9] - *
- * This function implements a subset of - * quoted-printable encoding specification (rule #1 and rule #2) - * as defined in RFC 1521. - *