1 package com.android.bluetooth.tests; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.UnsupportedEncodingException; 9 import java.text.SimpleDateFormat; 10 import java.util.ArrayList; 11 import java.util.Date; 12 import java.util.LinkedHashMap; 13 14 import android.annotation.TargetApi; 15 import android.content.ContentResolver; 16 import android.content.ContentValues; 17 import android.content.Context; 18 import android.database.Cursor; 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.os.Debug; 22 import android.os.ParcelFileDescriptor; 23 import android.provider.BaseColumns; 24 import android.provider.Telephony.Mms; 25 import android.provider.Telephony.MmsSms; 26 import android.provider.Telephony.Threads; 27 import android.test.AndroidTestCase; 28 import android.util.Log; 29 30 import com.android.bluetooth.map.BluetoothMapMasInstance; 31 import com.android.bluetooth.map.BluetoothMapAccountItem; 32 import com.android.bluetooth.map.BluetoothMapAccountLoader; 33 import com.android.bluetooth.map.BluetoothMapAppParams; 34 import com.android.bluetooth.map.BluetoothMapContent; 35 import com.android.bluetooth.map.BluetoothMapFolderElement; 36 import com.android.bluetooth.map.BluetoothMapMessageListing; 37 import com.android.bluetooth.map.BluetoothMapUtils; 38 import com.android.bluetooth.map.BluetoothMapUtils.TYPE; 39 import com.android.bluetooth.map.MapContact; 40 import com.android.bluetooth.map.SmsMmsContacts; 41 import com.android.bluetooth.mapapi.BluetoothMapContract; 42 43 public class BluetoothMapContentTest extends AndroidTestCase { 44 45 private static final String TAG = "BluetoothMapContentTest"; 46 47 private static final boolean D = true; 48 49 private Context mContext; 50 private ContentResolver mResolver; 51 private SmsMmsContacts mContacts = new SmsMmsContacts(); 52 53 private BluetoothMapFolderElement mCurrentFolder; 54 private BluetoothMapAccountItem mAccount = null; 55 56 private static final int MAS_ID = 0; 57 private static final int REMOTE_FEATURE_MASK = 0x07FFFFFF; 58 private static final BluetoothMapMasInstance mMasInstance = 59 new MockMasInstance(MAS_ID, REMOTE_FEATURE_MASK); 60 61 62 private Uri mEmailUri = null; 63 private Uri mEmailMessagesUri = null; 64 private Uri mEmailFolderUri = null; 65 private Uri mEmailAccountUri = null; 66 67 static final String[] EMAIL_ACCOUNT_PROJECTION = new String[] { 68 BluetoothMapContract.MessageColumns.FOLDER_ID, 69 BluetoothMapContract.MessageColumns.ACCOUNT_ID, 70 }; 71 printAccountInfo(Cursor c)72 private void printAccountInfo(Cursor c) { 73 if (D) Log.d(TAG, BluetoothMapContract.MessageColumns.ACCOUNT_ID + " : " + 74 c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.ACCOUNT_ID)) ); 75 } 76 77 static final String[] BT_MESSAGE_ID_PROJECTION = new String[] { 78 BluetoothMapContract.MessageColumns._ID, 79 BluetoothMapContract.MessageColumns.DATE, 80 }; 81 82 static final String[] BT_MESSAGE_PROJECTION = BluetoothMapContract.BT_MESSAGE_PROJECTION; 83 84 static final String[] BT_ACCOUNT_PROJECTION = BluetoothMapContract.BT_ACCOUNT_PROJECTION; 85 86 static final String[] BT_FOLDER_PROJECTION = BluetoothMapContract.BT_FOLDER_PROJECTION; 87 88 BluetoothMapAccountLoader loader; 89 LinkedHashMap<BluetoothMapAccountItem, ArrayList<BluetoothMapAccountItem>> mFullList; 90 BluetoothMapContentTest()91 public BluetoothMapContentTest() { 92 super(); 93 } 94 initTestSetup()95 private void initTestSetup(){ 96 mContext = this.getContext(); 97 mResolver = mContext.getContentResolver(); 98 99 // find enabled account 100 loader = new BluetoothMapAccountLoader(mContext); 101 mFullList = loader.parsePackages(false); 102 String accountId = getEnabledAccount(); 103 Uri tmpEmailUri = Uri.parse("content://com.android.email.bluetoothprovider/"); 104 105 mEmailUri = Uri.withAppendedPath(tmpEmailUri, accountId + "/"); 106 mEmailMessagesUri = Uri.parse(mEmailUri + BluetoothMapContract.TABLE_MESSAGE); 107 mEmailFolderUri = Uri.parse(mEmailUri + BluetoothMapContract.TABLE_FOLDER); 108 mEmailAccountUri = Uri.parse(tmpEmailUri + BluetoothMapContract.TABLE_ACCOUNT); 109 110 buildFolderStructure(); 111 112 } 113 getEnabledAccount()114 public String getEnabledAccount(){ 115 if(D)Log.d(TAG,"getEnabledAccountItems()\n"); 116 String account = null; 117 for(BluetoothMapAccountItem app:mFullList.keySet()){ 118 ArrayList<BluetoothMapAccountItem> accountList = mFullList.get(app); 119 for(BluetoothMapAccountItem acc: accountList){ 120 mAccount = acc; 121 account = acc.getId(); 122 break; 123 } 124 } 125 return account; 126 } 127 buildFolderStructure()128 private void buildFolderStructure(){ 129 mCurrentFolder = new BluetoothMapFolderElement("root", null); // This will be the root element 130 BluetoothMapFolderElement tmpFolder; 131 tmpFolder = mCurrentFolder.addFolder("telecom"); // root/telecom 132 tmpFolder = tmpFolder.addFolder("msg"); // root/telecom/msg 133 if(mEmailFolderUri != null) { 134 addEmailFolders(tmpFolder); 135 } 136 } 137 addEmailFolders(BluetoothMapFolderElement parentFolder)138 private void addEmailFolders(BluetoothMapFolderElement parentFolder) { 139 BluetoothMapFolderElement newFolder; 140 String where = BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + 141 " = " + parentFolder.getFolderId(); 142 Cursor c = mContext.getContentResolver().query(mEmailFolderUri, 143 BluetoothMapContract.BT_FOLDER_PROJECTION, where, null, null); 144 if (c != null) { 145 c.moveToPosition(-1); 146 while (c.moveToNext()) { 147 String name = c.getString(c.getColumnIndex(BluetoothMapContract.FolderColumns.NAME)); 148 long id = c.getLong(c.getColumnIndex(BluetoothMapContract.FolderColumns._ID)); 149 newFolder = parentFolder.addEmailFolder(name, id); 150 addEmailFolders(newFolder); // Use recursion to add any sub folders 151 } 152 c.close(); 153 } else { 154 if (D) Log.d(TAG, "addEmailFolders(): no elements found"); 155 } 156 } 157 getInbox()158 private BluetoothMapFolderElement getInbox() { 159 BluetoothMapFolderElement tmpFolderElement = null; 160 161 tmpFolderElement = mCurrentFolder.getSubFolder("telecom"); 162 tmpFolderElement = tmpFolderElement.getSubFolder("msg"); 163 tmpFolderElement = tmpFolderElement.getSubFolder("inbox"); 164 return tmpFolderElement; 165 } 166 getOutbox()167 private BluetoothMapFolderElement getOutbox() { 168 BluetoothMapFolderElement tmpFolderElement = null; 169 170 tmpFolderElement = mCurrentFolder.getSubFolder("telecom"); 171 tmpFolderElement = tmpFolderElement.getSubFolder("msg"); 172 tmpFolderElement = tmpFolderElement.getSubFolder("outbox"); 173 return tmpFolderElement; 174 } 175 176 getDateTimeString(long timestamp)177 private String getDateTimeString(long timestamp) { 178 SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); 179 Date date = new Date(timestamp); 180 return format.format(date); // Format to YYYYMMDDTHHMMSS local time 181 } 182 printCursor(Cursor c)183 private void printCursor(Cursor c) { 184 StringBuilder sb = new StringBuilder(); 185 sb.append("\nprintCursor:\n"); 186 for(int i = 0; i < c.getColumnCount(); i++) { 187 if(c.getColumnName(i).equals(BluetoothMapContract.MessageColumns.DATE)){ 188 sb.append(" ").append(c.getColumnName(i)) 189 .append(" : ").append(getDateTimeString(c.getLong(i))).append("\n"); 190 } else { 191 sb.append(" ").append(c.getColumnName(i)) 192 .append(" : ").append(c.getString(i)).append("\n"); 193 } 194 } 195 Log.d(TAG, sb.toString()); 196 } 197 dumpMessageContent(Cursor c)198 private void dumpMessageContent(Cursor c) { 199 long id = c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID)); 200 Uri uri = Uri.parse(mEmailMessagesUri + "/" + id 201 + "/" + BluetoothMapContract.FILE_MSG_NO_ATTACHMENTS); 202 FileInputStream is = null; 203 ParcelFileDescriptor fd = null; 204 int count; 205 try { 206 fd = mResolver.openFileDescriptor(uri, "r"); 207 is = new FileInputStream(fd.getFileDescriptor()); 208 byte[] buffer = new byte[1024]; 209 210 while((count = is.read(buffer)) != -1) { 211 Log.d(TAG, new String(buffer,0, count)); 212 } 213 214 215 } catch (FileNotFoundException e) { 216 Log.w(TAG, e); 217 } catch (IOException e) { 218 Log.w(TAG, e); 219 } 220 finally { 221 try { 222 if(is != null) 223 is.close(); 224 } catch (IOException e) {} 225 try { 226 if(fd != null) 227 fd.close(); 228 } catch (IOException e) {} 229 } 230 } 231 232 /** 233 * Create a new message in the database outbox, based on the content of c. 234 * @param c 235 */ writeMessageContent(Cursor c)236 private void writeMessageContent(Cursor c) { 237 long id = c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID)); 238 Uri uri = Uri.parse(mEmailMessagesUri + "/" + id + "/" 239 + BluetoothMapContract.FILE_MSG_NO_ATTACHMENTS); 240 FileInputStream is = null; 241 ParcelFileDescriptor fd = null; 242 FileOutputStream os = null; 243 ParcelFileDescriptor fdOut = null; 244 245 ContentValues newMessage = new ContentValues(); 246 BluetoothMapFolderElement outFolder = getOutbox(); 247 newMessage.put(BluetoothMapContract.MessageColumns.FOLDER_ID, outFolder.getFolderId()); 248 // Now insert the empty message into outbox (Maybe it should be draft first, and then a move?) 249 // TODO: Examine if we need to set some additional flags, e.g. visable? 250 Uri uriOut = mResolver.insert(mEmailMessagesUri, newMessage); 251 int count; 252 try { 253 fd = mResolver.openFileDescriptor(uri, "r"); 254 is = new FileInputStream(fd.getFileDescriptor()); 255 fdOut = mResolver.openFileDescriptor(uri, "w"); 256 os = new FileOutputStream(fdOut.getFileDescriptor()); 257 byte[] buffer = new byte[1024]; 258 259 while((count = is.read(buffer)) != -1) { 260 Log.d(TAG, new String(buffer,0, count)); 261 os.write(buffer, 0, count); 262 } 263 } catch (FileNotFoundException e) { 264 Log.w(TAG, e); 265 } catch (IOException e) { 266 Log.w(TAG, e); 267 } 268 finally { 269 try { 270 if(is != null) 271 is.close(); 272 } catch (IOException e) {} 273 try { 274 if(fd != null) 275 fd.close(); 276 } catch (IOException e) {} 277 try { 278 if(os != null) 279 os.close(); 280 } catch (IOException e) {} 281 try { 282 if(fdOut != null) 283 fdOut.close(); 284 } catch (IOException e) {} 285 } 286 } 287 writeMessage(Cursor c)288 private void writeMessage(Cursor c) { 289 Log.d(TAG, "c.getCount() = " + c.getCount()); 290 c.moveToPosition(-1); 291 if (c.moveToNext()) { 292 writeMessageContent(c); 293 } 294 c.close(); 295 } 296 297 dumpCursor(Cursor c)298 private void dumpCursor(Cursor c) { 299 Log.d(TAG, "c.getCount() = " + c.getCount()); 300 c.moveToPosition(-1); 301 while (c.moveToNext()) { 302 printCursor(c); 303 } 304 c.close(); 305 } 306 callBluetoothProvider()307 private void callBluetoothProvider() { 308 Log.d(TAG, "**** Test call into email provider ****"); 309 int accountId = 0; 310 int mailboxId = 0; 311 312 Log.d(TAG, "contentUri = " + mEmailMessagesUri); 313 314 Cursor c = mResolver.query(mEmailMessagesUri, EMAIL_ACCOUNT_PROJECTION, 315 null, null, "_id DESC"); 316 if (c != null) { 317 Log.d(TAG, "c.getCount() = " + c.getCount()); 318 c.moveToPosition(-1); 319 while (c.moveToNext()) { 320 printAccountInfo(c); 321 mailboxId = c.getInt(c.getColumnIndex( 322 BluetoothMapContract.MessageColumns.FOLDER_ID)); 323 accountId = c.getInt(c.getColumnIndex( 324 BluetoothMapContract.MessageColumns.ACCOUNT_ID)); 325 } 326 c.close(); 327 } else { 328 Log.d(TAG, "query failed"); 329 } 330 331 final Bundle extras = new Bundle(2); 332 /* TODO: find mailbox from DB */ 333 extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, mailboxId); 334 extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, accountId); 335 Bundle myBundle = mResolver.call(mEmailUri, BluetoothMapContract.METHOD_UPDATE_FOLDER, 336 null, extras); 337 } 338 339 testMsgListing()340 public void testMsgListing() { 341 initTestSetup(); 342 BluetoothMapContent mBtMapContent = new BluetoothMapContent(mContext, mAccount, 343 mMasInstance); 344 BluetoothMapAppParams appParams = new BluetoothMapAppParams(); 345 Log.d(TAG, "**** testMsgListing **** "); 346 BluetoothMapFolderElement fe = getInbox(); 347 348 if (fe != null) { 349 if (D) Log.d(TAG, "folder name=" + fe.getName()); 350 351 appParams.setFilterMessageType(0x0B); 352 appParams.setMaxListCount(1024); 353 appParams.setStartOffset(0); 354 355 BluetoothMapMessageListing msgListing = mBtMapContent.msgListing(fe, appParams); 356 int listCount = msgListing.getCount(); 357 int msgListingSize = mBtMapContent.msgListingSize(fe, appParams); 358 359 if (listCount == msgListingSize) { 360 Log.d(TAG, "testMsgListing - " + listCount ); 361 } 362 else { 363 Log.d(TAG, "testMsgListing - None"); 364 } 365 } 366 else { 367 Log.d(TAG, "testMsgListing - failed "); 368 } 369 370 } 371 testMsgListingUnread()372 public void testMsgListingUnread() { 373 initTestSetup(); 374 BluetoothMapContent mBtMapContent = new BluetoothMapContent(mContext, mAccount, 375 mMasInstance); 376 BluetoothMapAppParams appParams = new BluetoothMapAppParams(); 377 Log.d(TAG, "**** testMsgListingUnread **** "); 378 BluetoothMapFolderElement fe = getInbox(); 379 380 if (fe != null) { 381 382 appParams.setFilterReadStatus(0x01); 383 appParams.setFilterMessageType(0x0B); 384 appParams.setMaxListCount(1024); 385 appParams.setStartOffset(0); 386 387 BluetoothMapMessageListing msgListing = mBtMapContent.msgListing(fe, appParams); 388 389 int listCount = msgListing.getCount(); 390 if (msgListing.getCount() > 0) { 391 Log.d(TAG, "testMsgListingUnread - " + listCount ); 392 } 393 else { 394 Log.d(TAG, "testMsgListingUnread - None"); 395 } 396 } 397 else { 398 Log.d(TAG, "testMsgListingUnread - getInbox failed "); 399 } 400 } 401 testMsgListingWithOriginator()402 public void testMsgListingWithOriginator() { 403 initTestSetup(); 404 BluetoothMapContent mBtMapContent = new BluetoothMapContent(mContext, mAccount, 405 mMasInstance); 406 BluetoothMapAppParams appParams = new BluetoothMapAppParams(); 407 Log.d(TAG, "**** testMsgListingUnread **** "); 408 BluetoothMapFolderElement fe = getInbox(); 409 410 if (fe != null) { 411 412 appParams.setFilterOriginator("*scsc.*"); 413 appParams.setFilterMessageType(0x0B); 414 appParams.setMaxListCount(1024); 415 appParams.setStartOffset(0); 416 417 BluetoothMapMessageListing msgListing = mBtMapContent.msgListing(fe, appParams); 418 419 int listCount = msgListing.getCount(); 420 if (msgListing.getCount() > 0) { 421 Log.d(TAG, "testMsgListingWithOriginator - " + listCount ); 422 } 423 else { 424 Log.d(TAG, "testMsgListingWithOriginator - None"); 425 } 426 } else { 427 Log.d(TAG, "testMsgListingWithOriginator - getInbox failed "); 428 } 429 } 430 testGetMessages()431 public void testGetMessages() { 432 initTestSetup(); 433 BluetoothMapContent mBtMapContent = new BluetoothMapContent(mContext, mAccount, 434 mMasInstance); 435 BluetoothMapAppParams appParams = new BluetoothMapAppParams(); 436 Log.d(TAG, "**** testGetMessages **** "); 437 BluetoothMapFolderElement fe = getInbox(); 438 439 if (fe != null) { 440 appParams.setAttachment(0); 441 appParams.setCharset(BluetoothMapContent.MAP_MESSAGE_CHARSET_UTF8); 442 443 //get message handles 444 Cursor c = mResolver.query(mEmailMessagesUri, BT_MESSAGE_ID_PROJECTION, 445 null, null, "_id DESC"); 446 if (c != null) { 447 c.moveToPosition(-1); 448 while (c.moveToNext()) { 449 Long id = c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID)); 450 String handle = BluetoothMapUtils.getMapHandle(id, TYPE.EMAIL); 451 try { 452 // getMessage 453 byte[] bytes = mBtMapContent.getMessage(handle, appParams, fe, "1.1"); 454 Log.d(TAG, "testGetMessages id=" + id + ", handle=" + handle + 455 ", length=" + bytes.length ); 456 String testPrint = new String(bytes); 457 Log.d(TAG, "testGetMessage (only dump first part):\n" + testPrint ); 458 } catch (UnsupportedEncodingException e) { 459 Log.w(TAG, e); 460 } finally { 461 462 } 463 } 464 } else { 465 Log.d(TAG, "testGetMessages - no cursor "); 466 } 467 } else { 468 Log.d(TAG, "testGetMessages - getInbox failed "); 469 } 470 471 } 472 testDumpAccounts()473 public void testDumpAccounts() { 474 initTestSetup(); 475 Log.d(TAG, "**** testDumpAccounts **** \n from: " + mEmailAccountUri.toString()); 476 Cursor c = mResolver.query(mEmailAccountUri, BT_ACCOUNT_PROJECTION, null, null, "_id DESC"); 477 if (c != null) { 478 dumpCursor(c); 479 } else { 480 Log.d(TAG, "query failed"); 481 } 482 Log.w(TAG, "testDumpAccounts(): ThreadId: " + Thread.currentThread().getId()); 483 484 } 485 testAccountUpdate()486 public void testAccountUpdate() { 487 initTestSetup(); 488 Log.d(TAG, "**** testAccountUpdate **** \n of: " + mEmailAccountUri.toString()); 489 Cursor c = mResolver.query(mEmailAccountUri, BT_ACCOUNT_PROJECTION, null, null, "_id DESC"); 490 491 if (c != null) { 492 c.moveToPosition(-1); 493 while (c.moveToNext()) { 494 printCursor(c); 495 Long id = c.getLong(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)); 496 int exposeFlag = c.getInt( 497 c.getColumnIndex(BluetoothMapContract.AccountColumns.FLAG_EXPOSE)); 498 String where = BluetoothMapContract.AccountColumns._ID + " = " + id; 499 ContentValues values = new ContentValues(); 500 if(exposeFlag == 1) { 501 values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, (int) 0); 502 } else { 503 values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, (int) 1); 504 } 505 Log.i(TAG, "Calling update() with selection: " + where + 506 "values(exposeFlag): " + 507 values.getAsInteger(BluetoothMapContract.AccountColumns.FLAG_EXPOSE)); 508 mResolver.update(mEmailAccountUri, values, where, null); 509 } 510 c.close(); 511 } 512 513 } 514 testDumpMessages()515 public void testDumpMessages() { 516 initTestSetup(); 517 518 if (D) Log.d(TAG, "**** testDumpMessages **** \n uri=" + mEmailMessagesUri.toString()); 519 BluetoothMapFolderElement fe = getInbox(); 520 if (fe != null) 521 { 522 String where =""; 523 //where = BluetoothMapContract.MessageColumns.FOLDER_ID + " = " + fe.getEmailFolderId(); 524 Cursor c = mResolver.query(mEmailMessagesUri, BT_MESSAGE_PROJECTION, 525 where, null, "_id DESC"); 526 if (c != null) { 527 dumpCursor(c); 528 } else { 529 if (D) Log.d(TAG, "query failed"); 530 } 531 if (D) Log.w(TAG, "dumpMessage(): ThreadId: " + Thread.currentThread().getId()); 532 } else { 533 if (D) Log.w(TAG, "dumpMessage(): ThreadId: " + Thread.currentThread().getId()); 534 } 535 } 536 testDumpMessageContent()537 public void testDumpMessageContent() { 538 initTestSetup(); 539 540 Log.d(TAG, "**** testDumpMessageContent **** from: " + mEmailMessagesUri.toString()); 541 // BluetoothMapFolderElement fe = getInbox(); 542 // String where = BluetoothMapContract.MessageColumns.FOLDER_ID + " = " + fe.getEmailFolderId(); 543 // where += " AND " + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY + " = 0"; 544 545 Cursor c = mResolver.query(mEmailMessagesUri, BT_MESSAGE_PROJECTION, null, null, "_id DESC"); 546 if (c != null && c.moveToNext()) { 547 dumpMessageContent(c); 548 } else { 549 Log.d(TAG, "query failed"); 550 } 551 Log.w(TAG, "dumpMessage(): ThreadId: " + Thread.currentThread().getId()); 552 } 553 testWriteMessageContent()554 public void testWriteMessageContent() { 555 initTestSetup(); 556 Log.d(TAG, "**** testWriteMessageContent **** from: " + mEmailMessagesUri.toString()); 557 BluetoothMapFolderElement fe = getInbox(); 558 String where = BluetoothMapContract.MessageColumns.FOLDER_ID + " = " + fe.getFolderId(); 559 // where += " AND " + BluetoothMapContract.MessageColumns.HIGH_PRIORITY + " = 0"; 560 Cursor c = mResolver.query(mEmailMessagesUri, BT_MESSAGE_PROJECTION, where, null, "_id DESC"); 561 if (c != null) { 562 writeMessage(c); 563 } else { 564 Log.d(TAG, "query failed"); 565 } 566 Log.w(TAG, "writeMessage(): ThreadId: " + Thread.currentThread().getId()); 567 } 568 569 /* 570 * Handle test cases 571 */ 572 private static final long HANDLE_TYPE_SMS_CDMA_MASK = (((long)0x1)<<60); 573 testHandle()574 public void testHandle() { 575 String handleStr = null; 576 Debug.startMethodTracing("str_format"); 577 for(long i = 0; i < 10000; i++) { 578 handleStr = String.format("%016X",(i | HANDLE_TYPE_SMS_CDMA_MASK)); 579 } 580 Debug.stopMethodTracing(); 581 Debug.startMethodTracing("getHandleString"); 582 for(long i = 0; i < 10000; i++) { 583 handleStr = BluetoothMapUtils.getLongAsString(i | HANDLE_TYPE_SMS_CDMA_MASK); 584 } 585 Debug.stopMethodTracing(); 586 } 587 588 /* 589 * Folder test cases 590 */ 591 testDumpEmailFolders()592 public void testDumpEmailFolders() { 593 initTestSetup(); 594 Debug.startMethodTracing(); 595 String where = null; 596 Cursor c = mResolver.query(mEmailFolderUri, BT_FOLDER_PROJECTION, where, null, "_id DESC"); 597 if (c != null) { 598 dumpCursor(c); 599 c.close(); 600 } else { 601 Log.d(TAG, "query failed"); 602 } 603 Debug.stopMethodTracing(); 604 } 605 testFolderPath()606 public void testFolderPath() { 607 initTestSetup(); 608 Log.d(TAG, "**** testFolderPath **** "); 609 BluetoothMapFolderElement fe = getInbox(); 610 BluetoothMapFolderElement folder = fe.getFolderById(fe.getFolderId()); 611 if(folder == null) { 612 Log.d(TAG, "**** testFolderPath unable to find the folder with id: " + 613 fe.getFolderId()); 614 } 615 else { 616 Log.d(TAG, "**** testFolderPath found the folder with id: " + 617 fe.getFolderId() + "\nFull path: " + 618 folder.getFullPath()); 619 } 620 } 621 testFolderElement()622 public void testFolderElement() { 623 Log.d(TAG, "**** testFolderElement **** "); 624 BluetoothMapFolderElement fe = new BluetoothMapFolderElement("root", null); 625 fe = fe.addEmailFolder("MsG", 1); 626 fe.addEmailFolder("Outbox", 100); 627 fe.addEmailFolder("Sent", 200); 628 BluetoothMapFolderElement inbox = fe.addEmailFolder("Inbox", 300); 629 fe.addEmailFolder("Draft", 400); 630 fe.addEmailFolder("Deleted", 500); 631 inbox.addEmailFolder("keep", 301); 632 inbox.addEmailFolder("private", 302); 633 inbox.addEmailFolder("junk", 303); 634 635 BluetoothMapFolderElement folder = fe.getFolderById(400); 636 assertEquals("draft", folder.getName()); 637 assertEquals("private", fe.getFolderById(302).getName()); 638 assertEquals("junk", fe.getRoot().getFolderById(303).getName()); 639 assertEquals("msg/inbox/keep", fe.getFolderById(301).getFullPath()); 640 } 641 642 /* 643 * SMS test cases 644 */ testAddSmsEntries()645 public void testAddSmsEntries() { 646 int count = 1000; 647 mContext = this.getContext(); 648 mResolver = mContext.getContentResolver(); 649 ContentValues values[] = new ContentValues[count]; 650 long date = System.currentTimeMillis(); 651 Log.i(TAG, "Preparing messages..."); 652 for (int x=0;x<count;x++){ 653 //if (D) Log.d(TAG, "*** Adding dummy sms #"+x); 654 655 ContentValues item = new ContentValues(4); 656 item.put("address", "1234"); 657 item.put("body", "test message "+x); 658 item.put("date", date); 659 item.put("read", "0"); 660 661 values[x] = item; 662 // Uri mUri = mResolver.insert(Uri.parse("content://sms"), item); 663 } 664 Log.i(TAG, "Starting bulk insert..."); 665 mResolver.bulkInsert(Uri.parse("content://sms"), values); 666 Log.i(TAG, "Bulk insert done."); 667 } 668 testAddSms()669 public void testAddSms() { 670 mContext = this.getContext(); 671 mResolver = mContext.getContentResolver(); 672 if (D) Log.d(TAG, "*** Adding dummy sms #"); 673 674 ContentValues item = new ContentValues(); 675 item.put("address", "1234"); 676 item.put("body", "test message"); 677 item.put("date", System.currentTimeMillis()); 678 item.put("read", "0"); 679 680 Uri mUri = mResolver.insert(Uri.parse("content://sms"), item); 681 } 682 testServiceSms()683 public void testServiceSms() { 684 mContext = this.getContext(); 685 mResolver = mContext.getContentResolver(); 686 if (D) Log.d(TAG, "*** Adding dummy sms #"); 687 688 ContentValues item = new ContentValues(); 689 item.put("address", "C-Bonde"); 690 item.put("body", "test message"); 691 item.put("date", System.currentTimeMillis()); 692 item.put("read", "0"); 693 694 Uri mUri = mResolver.insert(Uri.parse("content://sms"), item); 695 } 696 697 /* 698 * MMS content test cases 699 */ 700 public static final int MMS_FROM = 0x89; 701 public static final int MMS_TO = 0x97; 702 public static final int MMS_BCC = 0x81; 703 public static final int MMS_CC = 0x82; 704 printMmsAddr(long id)705 private void printMmsAddr(long id) { 706 final String[] projection = null; 707 String selection = new String("msg_id=" + id); 708 String uriStr = String.format("content://mms/%d/addr", id); 709 Uri uriAddress = Uri.parse(uriStr); 710 Cursor c = mResolver.query(uriAddress, projection, selection, null, null); 711 712 if (c.moveToFirst()) { 713 do { 714 String add = c.getString(c.getColumnIndex("address")); 715 Integer type = c.getInt(c.getColumnIndex("type")); 716 if (type == MMS_TO) { 717 if (D) Log.d(TAG, " recipient: " + add + " (type: " + type + ")"); 718 } else if (type == MMS_FROM) { 719 if (D) Log.d(TAG, " originator: " + add + " (type: " + type + ")"); 720 } else { 721 if (D) Log.d(TAG, " address other: " + add + " (type: " + type + ")"); 722 } 723 printCursor(c); 724 725 } while(c.moveToNext()); 726 } 727 } 728 printMmsPartImage(long partid)729 private void printMmsPartImage(long partid) { 730 String uriStr = String.format("content://mms/part/%d", partid); 731 Uri uriAddress = Uri.parse(uriStr); 732 int ch; 733 StringBuffer sb = new StringBuffer(""); 734 InputStream is = null; 735 736 try { 737 is = mResolver.openInputStream(uriAddress); 738 739 while ((ch = is.read()) != -1) { 740 sb.append((char)ch); 741 } 742 if (D) Log.d(TAG, sb.toString()); 743 744 } catch (IOException e) { 745 // do nothing for now 746 e.printStackTrace(); 747 } 748 } 749 printMmsParts(long id)750 private void printMmsParts(long id) { 751 final String[] projection = null; 752 String selection = new String("mid=" + id); 753 String uriStr = String.format("content://mms/%d/part", id); 754 Uri uriAddress = Uri.parse(uriStr); 755 Cursor c = mResolver.query(uriAddress, projection, selection, null, null); 756 757 if (c.moveToFirst()) { 758 int i = 0; 759 do { 760 if (D) Log.d(TAG, " part " + i++); 761 printCursor(c); 762 763 /* if (ct.equals("image/jpeg")) { */ 764 /* printMmsPartImage(partid); */ 765 /* } */ 766 } while(c.moveToNext()); 767 } 768 } 769 dumpMmsTable()770 public void dumpMmsTable() { 771 mContext = this.getContext(); 772 mResolver = mContext.getContentResolver(); 773 774 if (D) Log.d(TAG, "**** Dump of mms table ****"); 775 Cursor c = mResolver.query(Mms.CONTENT_URI, 776 null, null, null, "_id DESC"); 777 if (c != null) { 778 if (D) Log.d(TAG, "c.getCount() = " + c.getCount()); 779 c.moveToPosition(-1); 780 while (c.moveToNext()) { 781 Log.d(TAG,"Message:"); 782 printCursor(c); 783 long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); 784 Log.d(TAG,"Address:"); 785 printMmsAddr(id); 786 Log.d(TAG,"Parts:"); 787 printMmsParts(id); 788 } 789 c.close(); 790 } else { 791 Log.d(TAG, "query failed"); 792 } 793 } 794 795 /** 796 * This dumps the thread database. 797 * Interesting how useful this is. 798 * - DATE is described to be the creation date of the thread. But it actually 799 * contains the time-date of the last activity of the thread. 800 * - RECIPIENTS is a list of the contacts related to the thread. The number can 801 * be found for both MMS and SMS in the "canonical-addresses" table. 802 * - The READ column tells if the thread have been read. (read = 1: no unread messages) 803 * - The snippet is a small piece of text from the last message, and could be used as thread 804 * name. Please however note that if we do this, the version-counter should change each 805 * time a message is added to the thread. But since it changes the read attribute and 806 * last activity, it changes anyway. 807 * - 808 */ 809 810 dumpThreadsTable()811 public void dumpThreadsTable() { 812 mContext = this.getContext(); 813 mResolver = mContext.getContentResolver(); 814 mContacts.clearCache(); 815 Uri uri = Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build(); 816 817 if (D) Log.d(TAG, "**** Dump of Threads table ****\nUri: " + uri); 818 Cursor c = mResolver.query(uri, 819 null, null, null, "_id DESC"); 820 if (c != null) { 821 if (D) Log.d(TAG, "c.getCount() = " + c.getCount()); 822 c.moveToPosition(-1); 823 while (c.moveToNext()) { 824 Log.d(TAG,"Threads:"); 825 printCursor(c); 826 String ids = c.getString(c.getColumnIndex(Threads.RECIPIENT_IDS)); 827 Log.d(TAG,"Address:"); 828 printAddresses(ids); 829 /* Log.d(TAG,"Parts:"); 830 printMmsParts(id);*/ 831 } 832 c.close(); 833 } else { 834 Log.d(TAG, "query failed"); 835 } 836 } 837 838 /** 839 * This test shows the content of the canonicalAddresses table. 840 * Conclusion: 841 * The _id column matches the id's from the RECIPIENT_IDS column 842 * in the Threads table, hence are to be used to map from an id to 843 * a phone number, which then can be matched to a contact. 844 */ dumpCanAddrTable()845 public void dumpCanAddrTable() { 846 mContext = this.getContext(); 847 mResolver = mContext.getContentResolver(); 848 Uri uri = Uri.parse("content://mms-sms/canonical-addresses"); 849 uri = MmsSms.CONTENT_URI.buildUpon().appendPath("canonical-addresses").build(); 850 dumpUri(uri); 851 } 852 dumpUri(Uri uri)853 public void dumpUri(Uri uri) { 854 if (D) Log.d(TAG, "**** Dump of table ****\nUri: " + uri); 855 Cursor c = mResolver.query(uri, null, null, null, null); 856 if (c != null) { 857 if (D) Log.d(TAG, "c.getCount() = " + c.getCount()); 858 c.moveToPosition(-1); 859 while (c.moveToNext()) { 860 Log.d(TAG,"Entry: " + c.getPosition()); 861 printCursor(c); 862 } 863 c.close(); 864 } else { 865 Log.d(TAG, "query failed"); 866 } 867 } 868 printAddresses(String idsStr)869 private void printAddresses(String idsStr) { 870 String[] ids = idsStr.split(" "); 871 for (String id : ids) { 872 long longId; 873 try { 874 longId = Long.parseLong(id); 875 String addr = mContacts.getPhoneNumber(mResolver, longId); 876 MapContact contact = mContacts.getContactNameFromPhone(addr, mResolver); 877 Log.d(TAG, " id " + id + ": " + addr + " - " + contact.getName() 878 + " X-BT-UID: " + contact.getXBtUidString()); 879 } catch (NumberFormatException ex) { 880 // skip this id 881 continue; 882 } 883 } 884 } 885 886 } 887