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*/
15package com.android.bluetooth.map;
16
17import com.android.bluetooth.DeviceWorkArounds;
18import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
19
20import org.xmlpull.v1.XmlSerializer;
21
22import java.io.IOException;
23import java.text.SimpleDateFormat;
24import java.util.Date;
25
26public 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
60    public int getCursorIndex() {
61        return mCursorIndex;
62    }
63
64    public void setCursorIndex(int cursorIndex) {
65        this.mCursorIndex = cursorIndex;
66    }
67
68    public long getHandle() {
69        return mCpHandle;
70    }
71
72    public void setHandle(long handle) {
73        this.mCpHandle = handle;
74    }
75
76    public long getDateTime() {
77        return mDateTime;
78    }
79
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
88    public void setDateTime(long dateTime) {
89        this.mDateTime = dateTime;
90    }
91
92    public String getSubject() {
93        return mSubject;
94    }
95
96    public void setSubject(String subject) {
97        this.mSubject = subject;
98    }
99
100    public String getSenderName() {
101        return mSenderName;
102    }
103
104    public void setSenderName(String senderName) {
105        this.mSenderName = senderName;
106    }
107
108    public String getSenderAddressing() {
109        return mSenderAddressing;
110    }
111
112    public void setSenderAddressing(String senderAddressing) {
113        this.mSenderAddressing = senderAddressing;
114    }
115
116    public String getReplyToAddressing() {
117        return mReplytoAddressing;
118    }
119
120    public void setReplytoAddressing(String replytoAddressing) {
121        this.mReplytoAddressing = replytoAddressing;
122    }
123
124    public String getRecipientName() {
125        return mRecipientName;
126    }
127
128    public void setRecipientName(String recipientName) {
129        this.mRecipientName = recipientName;
130    }
131
132    public String getRecipientAddressing() {
133        return mRecipientAddressing;
134    }
135
136    public void setRecipientAddressing(String recipientAddressing) {
137        this.mRecipientAddressing = recipientAddressing;
138    }
139
140    public TYPE getType() {
141        return mType;
142    }
143
144    public void setType(TYPE type, boolean appParamSet) {
145        this.mMsgTypeAppParamSet = appParamSet;
146        this.mType = type;
147    }
148
149    public int getSize() {
150        return mSize;
151    }
152
153    public void setSize(int size) {
154        this.mSize = size;
155    }
156
157    public String getText() {
158        return mText;
159    }
160
161    public void setText(String text) {
162        this.mText = text;
163    }
164
165    public String getReceptionStatus() {
166        return mReceptionStatus;
167    }
168
169    public void setReceptionStatus(String receptionStatus) {
170        this.mReceptionStatus = receptionStatus;
171    }
172
173    public String getDeliveryStatus() {
174        return mDeliveryStatus;
175    }
176
177    public void setDeliveryStatus(String deliveryStatus) {
178        this.mDeliveryStatus = deliveryStatus;
179    }
180
181    public int getAttachmentSize() {
182        return mAttachmentSize;
183    }
184
185    public void setAttachmentSize(int attachmentSize) {
186        this.mAttachmentSize = attachmentSize;
187    }
188
189    public String getAttachmentMimeTypes() {
190        return mAttachmentMimeTypes;
191    }
192
193    public void setAttachmentMimeTypes(String attachmentMimeTypes) {
194        this.mAttachmentMimeTypes = attachmentMimeTypes;
195    }
196
197    public String getPriority() {
198        return mPriority;
199    }
200
201    public void setPriority(String priority) {
202        this.mPriority = priority;
203    }
204
205    public String getRead() {
206        return (mRead ? "yes" : "no");
207    }
208
209    public boolean getReadBool() {
210        return mRead;
211    }
212
213    public void setRead(boolean read, boolean reportRead) {
214        this.mRead = read;
215        this.mReportRead = reportRead;
216    }
217
218    public String getSent() {
219        return mSent;
220    }
221
222    public void setSent(String sent) {
223        this.mSent = sent;
224    }
225
226    public String getProtect() {
227        return mProtect;
228    }
229
230    public void setProtect(String protect) {
231        this.mProtect = protect;
232    }
233
234    public void setThreadId(long threadId, TYPE type) {
235        if (threadId != -1) {
236            this.mThreadId = BluetoothMapUtils.getMapConvoHandle(threadId, type);
237        }
238    }
239
240    public String getThreadName() {
241        return mThreadName;
242    }
243
244    public void setThreadName(String name) {
245        this.mThreadName = name;
246    }
247
248    public String getFolderType() {
249        return mFolderType;
250    }
251
252    public void setFolderType(String folderType) {
253        this.mFolderType = folderType;
254    }
255
256    @Override
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     * */
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", this.getDateTimeString());
292        }
293        if (mSenderName != null) {
294            xmlMsgElement.attribute(null, "sender_name",
295                    BluetoothMapUtils.stripInvalidChars(mSenderName));
296        }
297        if (mSenderAddressing != null) {
298            xmlMsgElement.attribute(null, "sender_addressing", mSenderAddressing);
299        }
300        if (mReplytoAddressing != null) {
301            xmlMsgElement.attribute(null, "replyto_addressing", mReplytoAddressing);
302        }
303        if (mRecipientName != null) {
304            xmlMsgElement.attribute(null, "recipient_name",
305                    BluetoothMapUtils.stripInvalidChars(mRecipientName));
306        }
307        if (mRecipientAddressing != null) {
308            xmlMsgElement.attribute(null, "recipient_addressing", mRecipientAddressing);
309        }
310            /* Avoid NPE for possible "null" value of mType */
311        if (mMsgTypeAppParamSet && mType != null) {
312            xmlMsgElement.attribute(null, "type", mType.name());
313        }
314        if (mSize != -1) {
315            xmlMsgElement.attribute(null, "size", Integer.toString(mSize));
316        }
317        if (mText != null) {
318            xmlMsgElement.attribute(null, "text", mText);
319        }
320        if (mReceptionStatus != null) {
321            xmlMsgElement.attribute(null, "reception_status", mReceptionStatus);
322        }
323        if (mDeliveryStatus != null) {
324            xmlMsgElement.attribute(null, "delivery_status", mDeliveryStatus);
325        }
326        if (mAttachmentSize != -1) {
327            xmlMsgElement.attribute(null, "attachment_size", Integer.toString(mAttachmentSize));
328        }
329        if (mAttachmentMimeTypes != null) {
330            xmlMsgElement.attribute(null, "attachment_mime_types", mAttachmentMimeTypes);
331        }
332        if (mPriority != null) {
333            xmlMsgElement.attribute(null, "priority", mPriority);
334        }
335        if (mReportRead) {
336            xmlMsgElement.attribute(null, "read", getRead());
337        }
338        if (mSent != null) {
339            xmlMsgElement.attribute(null, "sent", mSent);
340        }
341        if (mProtect != null) {
342            xmlMsgElement.attribute(null, "protected", mProtect);
343        }
344        if (mThreadId != null && includeThreadId) {
345            xmlMsgElement.attribute(null, "conversation_id", mThreadId);
346        }
347        if (mThreadName != null && includeThreadId) {
348            xmlMsgElement.attribute(null, "conversation_name", mThreadName);
349        }
350        if (mFolderType != null) {
351            xmlMsgElement.attribute(null, "folder_type", mFolderType);
352        }
353        xmlMsgElement.endTag(null, "msg");
354
355    }
356}
357
358
359