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