1 /*
2 * Copyright (C) 2013 Samsung System LSI
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package com.android.bluetooth.map;
16 
17 import com.android.bluetooth.DeviceWorkArounds;
18 import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
19 
20 import org.xmlpull.v1.XmlSerializer;
21 
22 import java.io.IOException;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 
26 public class BluetoothMapMessageListingElement
27         implements Comparable<BluetoothMapMessageListingElement> {
28 
29     private static final String TAG = "BluetoothMapMessageListingElement";
30     private static final boolean D = false;
31     private static final boolean V = false;
32 
33     private long mCpHandle = 0; /* The content provider handle - without type information */
34     private String mSubject = null;
35     private long mDateTime = 0;
36     private String mSenderName = null;
37     private String mSenderAddressing = null;
38     private String mReplytoAddressing = null;
39     private String mRecipientName = null;
40     private String mRecipientAddressing = null;
41     private TYPE mType = null;
42     private boolean mMsgTypeAppParamSet = false;
43     private int mSize = -1;
44     private String mText = null;
45     private String mReceptionStatus = null;
46     private String mDeliveryStatus = null;
47     private int mAttachmentSize = -1;
48     private String mPriority = null;
49     private boolean mRead = false;
50     private String mSent = null;
51     private String mProtect = null;
52     private String mFolderType = null;
53     private String mThreadId = null;
54     private String mThreadName = null;
55     private String mAttachmentMimeTypes = null;
56 
57     private boolean mReportRead = false;
58     private int mCursorIndex = 0;
59 
getCursorIndex()60     public int getCursorIndex() {
61         return mCursorIndex;
62     }
63 
setCursorIndex(int cursorIndex)64     public void setCursorIndex(int cursorIndex) {
65         this.mCursorIndex = cursorIndex;
66     }
67 
getHandle()68     public long getHandle() {
69         return mCpHandle;
70     }
71 
setHandle(long handle)72     public void setHandle(long handle) {
73         this.mCpHandle = handle;
74     }
75 
getDateTime()76     public long getDateTime() {
77         return mDateTime;
78     }
79 
getDateTimeString()80     public String getDateTimeString() {
81         /* TODO: if the feature bit mask of the client supports it, add the time-zone
82          *       (as for MSETime) */
83         SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
84         Date date = new Date(mDateTime);
85         return format.format(date); // Format to YYYYMMDDTHHMMSS local time
86     }
87 
setDateTime(long dateTime)88     public void setDateTime(long dateTime) {
89         this.mDateTime = dateTime;
90     }
91 
getSubject()92     public String getSubject() {
93         return mSubject;
94     }
95 
setSubject(String subject)96     public void setSubject(String subject) {
97         this.mSubject = subject;
98     }
99 
getSenderName()100     public String getSenderName() {
101         return mSenderName;
102     }
103 
setSenderName(String senderName)104     public void setSenderName(String senderName) {
105         this.mSenderName = senderName;
106     }
107 
getSenderAddressing()108     public String getSenderAddressing() {
109         return mSenderAddressing;
110     }
111 
setSenderAddressing(String senderAddressing)112     public void setSenderAddressing(String senderAddressing) {
113         this.mSenderAddressing = senderAddressing;
114     }
115 
getReplyToAddressing()116     public String getReplyToAddressing() {
117         return mReplytoAddressing;
118     }
119 
setReplytoAddressing(String replytoAddressing)120     public void setReplytoAddressing(String replytoAddressing) {
121         this.mReplytoAddressing = replytoAddressing;
122     }
123 
getRecipientName()124     public String getRecipientName() {
125         return mRecipientName;
126     }
127 
setRecipientName(String recipientName)128     public void setRecipientName(String recipientName) {
129         this.mRecipientName = recipientName;
130     }
131 
getRecipientAddressing()132     public String getRecipientAddressing() {
133         return mRecipientAddressing;
134     }
135 
setRecipientAddressing(String recipientAddressing)136     public void setRecipientAddressing(String recipientAddressing) {
137         this.mRecipientAddressing = recipientAddressing;
138     }
139 
getType()140     public TYPE getType() {
141         return mType;
142     }
143 
setType(TYPE type, boolean appParamSet)144     public void setType(TYPE type, boolean appParamSet) {
145         this.mMsgTypeAppParamSet = appParamSet;
146         this.mType = type;
147     }
148 
getSize()149     public int getSize() {
150         return mSize;
151     }
152 
setSize(int size)153     public void setSize(int size) {
154         this.mSize = size;
155     }
156 
getText()157     public String getText() {
158         return mText;
159     }
160 
setText(String text)161     public void setText(String text) {
162         this.mText = text;
163     }
164 
getReceptionStatus()165     public String getReceptionStatus() {
166         return mReceptionStatus;
167     }
168 
setReceptionStatus(String receptionStatus)169     public void setReceptionStatus(String receptionStatus) {
170         this.mReceptionStatus = receptionStatus;
171     }
172 
getDeliveryStatus()173     public String getDeliveryStatus() {
174         return mDeliveryStatus;
175     }
176 
setDeliveryStatus(String deliveryStatus)177     public void setDeliveryStatus(String deliveryStatus) {
178         this.mDeliveryStatus = deliveryStatus;
179     }
180 
getAttachmentSize()181     public int getAttachmentSize() {
182         return mAttachmentSize;
183     }
184 
setAttachmentSize(int attachmentSize)185     public void setAttachmentSize(int attachmentSize) {
186         this.mAttachmentSize = attachmentSize;
187     }
188 
getAttachmentMimeTypes()189     public String getAttachmentMimeTypes() {
190         return mAttachmentMimeTypes;
191     }
192 
setAttachmentMimeTypes(String attachmentMimeTypes)193     public void setAttachmentMimeTypes(String attachmentMimeTypes) {
194         this.mAttachmentMimeTypes = attachmentMimeTypes;
195     }
196 
getPriority()197     public String getPriority() {
198         return mPriority;
199     }
200 
setPriority(String priority)201     public void setPriority(String priority) {
202         this.mPriority = priority;
203     }
204 
getRead()205     public String getRead() {
206         return (mRead ? "yes" : "no");
207     }
208 
getReadBool()209     public boolean getReadBool() {
210         return mRead;
211     }
212 
setRead(boolean read, boolean reportRead)213     public void setRead(boolean read, boolean reportRead) {
214         this.mRead = read;
215         this.mReportRead = reportRead;
216     }
217 
getSent()218     public String getSent() {
219         return mSent;
220     }
221 
setSent(String sent)222     public void setSent(String sent) {
223         this.mSent = sent;
224     }
225 
getProtect()226     public String getProtect() {
227         return mProtect;
228     }
229 
setProtect(String protect)230     public void setProtect(String protect) {
231         this.mProtect = protect;
232     }
233 
setThreadId(long threadId, TYPE type)234     public void setThreadId(long threadId, TYPE type) {
235         if (threadId != -1) {
236             this.mThreadId = BluetoothMapUtils.getMapConvoHandle(threadId, type);
237         }
238     }
239 
getThreadName()240     public String getThreadName() {
241         return mThreadName;
242     }
243 
setThreadName(String name)244     public void setThreadName(String name) {
245         this.mThreadName = name;
246     }
247 
getFolderType()248     public String getFolderType() {
249         return mFolderType;
250     }
251 
setFolderType(String folderType)252     public void setFolderType(String folderType) {
253         this.mFolderType = folderType;
254     }
255 
256     @Override
compareTo(BluetoothMapMessageListingElement e)257     public int compareTo(BluetoothMapMessageListingElement e) {
258         if (this.mDateTime < e.mDateTime) {
259             return 1;
260         } else if (this.mDateTime > e.mDateTime) {
261             return -1;
262         } else {
263             return 0;
264         }
265     }
266 
267     /* Encode the MapMessageListingElement into the StringBuilder reference.
268      * */
encode(XmlSerializer xmlMsgElement, boolean includeThreadId)269     public void encode(XmlSerializer xmlMsgElement, boolean includeThreadId)
270             throws IllegalArgumentException, IllegalStateException, IOException {
271         // contruct the XML tag for a single msg in the msglisting
272         xmlMsgElement.startTag(null, "msg");
273         xmlMsgElement.attribute(null, "handle", BluetoothMapUtils.getMapHandle(mCpHandle, mType));
274         if (mSubject != null) {
275             String stripped = BluetoothMapUtils.stripInvalidChars(mSubject);
276 
277             if (DeviceWorkArounds.addressStartsWith(BluetoothMapService
278                     .getRemoteDevice().getAddress(), DeviceWorkArounds
279                     .MERCEDES_BENZ_CARKIT)) {
280                 stripped = stripped.replaceAll("[\\P{ASCII}&\"><]", "");
281                 if (stripped.isEmpty()) {
282                     stripped = "---";
283                 }
284             }
285 
286             xmlMsgElement.attribute(null, "subject",
287                     stripped.substring(0, stripped.length() < 256 ? stripped.length() : 256));
288         }
289 
290         if (mDateTime != 0) {
291             xmlMsgElement.attribute(null, "datetime",
292                     BluetoothMapUtils.getDateTimeString(this.getDateTime()));
293         }
294         if (mSenderName != null) {
295             xmlMsgElement.attribute(null, "sender_name",
296                     BluetoothMapUtils.stripInvalidChars(mSenderName));
297         }
298         if (mSenderAddressing != null) {
299             xmlMsgElement.attribute(null, "sender_addressing", mSenderAddressing);
300         }
301         if (mReplytoAddressing != null) {
302             xmlMsgElement.attribute(null, "replyto_addressing", mReplytoAddressing);
303         }
304         if (mRecipientName != null) {
305             xmlMsgElement.attribute(null, "recipient_name",
306                     BluetoothMapUtils.stripInvalidChars(mRecipientName));
307         }
308         if (mRecipientAddressing != null) {
309             xmlMsgElement.attribute(null, "recipient_addressing", mRecipientAddressing);
310         }
311             /* Avoid NPE for possible "null" value of mType */
312         if (mMsgTypeAppParamSet && mType != null) {
313             xmlMsgElement.attribute(null, "type", mType.name());
314         }
315         if (mSize != -1) {
316             xmlMsgElement.attribute(null, "size", Integer.toString(mSize));
317         }
318         if (mText != null) {
319             xmlMsgElement.attribute(null, "text", mText);
320         }
321         if (mReceptionStatus != null) {
322             xmlMsgElement.attribute(null, "reception_status", mReceptionStatus);
323         }
324         if (mDeliveryStatus != null) {
325             xmlMsgElement.attribute(null, "delivery_status", mDeliveryStatus);
326         }
327         if (mAttachmentSize != -1) {
328             xmlMsgElement.attribute(null, "attachment_size", Integer.toString(mAttachmentSize));
329         }
330         if (mAttachmentMimeTypes != null) {
331             xmlMsgElement.attribute(null, "attachment_mime_types", mAttachmentMimeTypes);
332         }
333         if (mPriority != null) {
334             xmlMsgElement.attribute(null, "priority", mPriority);
335         }
336         if (mReportRead) {
337             xmlMsgElement.attribute(null, "read", getRead());
338         }
339         if (mSent != null) {
340             xmlMsgElement.attribute(null, "sent", mSent);
341         }
342         if (mProtect != null) {
343             xmlMsgElement.attribute(null, "protected", mProtect);
344         }
345         if (mThreadId != null && includeThreadId) {
346             xmlMsgElement.attribute(null, "conversation_id", mThreadId);
347         }
348         if (mThreadName != null && includeThreadId) {
349             xmlMsgElement.attribute(null, "conversation_name", mThreadName);
350         }
351         if (mFolderType != null) {
352             xmlMsgElement.attribute(null, "folder_type", mFolderType);
353         }
354         xmlMsgElement.endTag(null, "msg");
355 
356     }
357 }
358 
359 
360