From a554bab57603fb53583ada32d09303f3582072b3 Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Tue, 9 Apr 2013 10:22:03 +0800 Subject: [PATCH] Bug 849739 4/5: RIL. r=gwagner --- .../src/ril/MobileMessageDatabaseService.js | 112 +++++++++++++++--- 1 file changed, 97 insertions(+), 15 deletions(-) diff --git a/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js b/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js index 8041c7ed8f1..65bcb39fa74 100644 --- a/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js +++ b/dom/mobilemessage/src/ril/MobileMessageDatabaseService.js @@ -16,6 +16,8 @@ const RIL_MOBILEMESSAGEDATABASESERVICE_CID = Components.ID("{29785f90-6b5b-11e2-9201-3b280170b2ec}"); const RIL_GETMESSAGESCURSOR_CID = Components.ID("{484d1ad8-840e-4782-9dc4-9ebc4d914937}"); +const RIL_GETTHREADSCURSOR_CID = + Components.ID("{95ee7c3e-d6f2-4ec4-ade5-0c453c036d35}"); const DEBUG = false; const DB_NAME = "sms"; @@ -1360,34 +1362,35 @@ MobileMessageDatabaseService.prototype = { }, [MESSAGE_STORE_NAME, THREAD_STORE_NAME]); }, - getThreadList: function getThreadList(aRequest) { + createThreadCursor: function createThreadCursor(callback) { if (DEBUG) debug("Getting thread list"); + + let cursor = new GetThreadsCursor(this, callback); this.newTxn(READ_ONLY, function (error, txn, threadStore) { + let collector = cursor.collector; if (error) { if (DEBUG) debug(error); - aRequest.notifyThreadListFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + collector.collect(null, COLLECT_ID_ERROR, COLLECT_TIMESTAMP_UNUSED); return; } txn.onerror = function onerror(event) { if (DEBUG) debug("Caught error on transaction ", event.target.errorCode); - aRequest.notifyThreadListFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + collector.collect(null, COLLECT_ID_ERROR, COLLECT_TIMESTAMP_UNUSED); }; - let request = threadStore.index("lastTimestamp").mozGetAll(); + let request = threadStore.index("lastTimestamp").openKeyCursor(); request.onsuccess = function(event) { - // TODO: keep backward compatibility of original API interface only. - let results = []; - for each (let item in event.target.result) { - results.push({ - id: item.id, - senderOrReceiver: item.participantAddresses[0], - timestamp: item.lastTimestamp, - body: item.subject, - unreadCount: item.unreadCount - }); + let cursor = event.target.result; + if (cursor) { + if (collector.collect(txn, cursor.primaryKey, cursor.key)) { + cursor.continue(); + } + } else { + collector.collect(txn, COLLECT_ID_END, COLLECT_TIMESTAMP_UNUSED); } - aRequest.notifyThreadList(results); }; }, [THREAD_STORE_NAME]); + + return cursor; } }; @@ -1951,6 +1954,85 @@ GetMessagesCursor.prototype = { } }; +function GetThreadsCursor(service, callback) { + this.service = service; + this.callback = callback; + this.collector = new ResultsCollector(); + + this.handleContinue(); // Trigger first run. +} +GetThreadsCursor.prototype = { + classID: RIL_GETTHREADSCURSOR_CID, + QueryInterface: XPCOMUtils.generateQI([Ci.nsICursorContinueCallback]), + + service: null, + callback: null, + collector: null, + + getThreadTxn: function getThreadTxn(threadStore, threadId) { + if (DEBUG) debug ("Fetching message " + threadId); + + let getRequest = threadStore.get(threadId); + let self = this; + getRequest.onsuccess = function onsuccess(event) { + if (DEBUG) { + debug("notifyCursorResult - threadId: " + threadId); + } + let threadRecord = event.target.result; + let thread = + gMobileMessageService.createThread(threadRecord.id, + threadRecord.participantAddresses, + threadRecord.lastTimestamp, + threadRecord.subject, + threadRecord.unreadCount); + self.callback.notifyCursorResult(thread); + }; + getRequest.onerror = function onerror(event) { + if (DEBUG) { + debug("notifyCursorError - threadId: " + threadId); + } + self.callback.notifyCursorError(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + }; + }, + + notify: function notify(txn, threadId) { + if (!threadId) { + this.callback.notifyCursorDone(); + return; + } + + if (threadId < 0) { + this.callback.notifyCursorError(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + return; + } + + // When filter transaction is not yet completed, we're called with current + // ongoing transaction object. + if (txn) { + let threadStore = txn.objectStore(THREAD_STORE_NAME); + this.getThreadTxn(threadStore, threadId); + return; + } + + // Or, we have to open another transaction ourselves. + let self = this; + this.service.newTxn(READ_ONLY, function (error, txn, threadStore) { + if (error) { + self.callback.notifyCursorError(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + return; + } + self.getThreadTxn(threadStore, threadId); + }, [THREAD_STORE_NAME]); + }, + + // nsICursorContinueCallback + + handleContinue: function handleContinue() { + if (DEBUG) debug("Getting next thread in list"); + this.collector.squeeze(this.notify.bind(this)); + } +} + XPCOMUtils.defineLazyServiceGetter(MobileMessageDatabaseService.prototype, "mRIL", "@mozilla.org/ril;1", "nsIRadioInterfaceLayer");