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