Merge b2g-inbound to m-c a=merge

This commit is contained in:
Wes Kocher 2014-08-07 18:06:14 -07:00
commit ca5d8751fe
20 changed files with 363 additions and 191 deletions

View File

@ -554,7 +554,7 @@ let memoryWatcher = {
});
}
let timer = setTimeout(() => this.measure(target), 300);
let timer = setTimeout(() => this.measure(target), 500);
this._timers.set(target, timer);
},

View File

@ -19,8 +19,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="227354333a185180b85471f2cc6abfb029e44718"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -15,9 +15,9 @@
<project name="platform_build" path="build" remote="b2g" revision="7945ca73e687be5edbc7b928dc7fe3a208242144">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>

View File

@ -19,8 +19,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="227354333a185180b85471f2cc6abfb029e44718"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "d581b7149d25fcff1786f914ed6b83d499999645",
"revision": "41b3413a893fef684b380bb344f9d4a5f491f858",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,8 +17,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -15,8 +15,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -17,8 +17,8 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="71f5a35e3bc1801847413cff1f14fc3b5cd991ca"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>

View File

@ -17,8 +17,8 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="54c3c19d439f7dbafda5c6cc3b4850b545a068ba"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6822004d07064ea3ebbc0c94cd2e15be6a02069d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c45627132ae7f00026e361a14d5d084a1236af24"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b0b5df8c194be48fc8a2f8d1c4310c36388eec9e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>

View File

@ -97,13 +97,6 @@ MobileMessageDB.prototype = {
*/
lastMessageId: 0,
/**
* An optional hook to check if device storage is full.
*
* @return true if full.
*/
isDiskFull: null,
/**
* Prepare the database. This may include opening the database and upgrading
* it to the latest schema version.
@ -266,7 +259,7 @@ MobileMessageDB.prototype = {
update(currentVersion);
};
request.onerror = function(event) {
//TODO look at event.target.Code and change error constant accordingly
// TODO look at event.target.Code and change error constant accordingly.
if (DEBUG) debug("Error opening database!");
callback(Cr.NS_ERROR_FAILURE, null);
};
@ -294,11 +287,6 @@ MobileMessageDB.prototype = {
if (DEBUG) debug("Opening transaction for object stores: " + storeNames);
let self = this;
this.ensureDB(function(error, db) {
if (!error &&
txn_type === READ_WRITE &&
self.isDiskFull && self.isDiskFull()) {
error = Cr.NS_ERROR_FILE_NO_DEVICE_SPACE;
}
if (error) {
if (DEBUG) debug("Could not open database: " + error);
callback(error);
@ -307,13 +295,13 @@ MobileMessageDB.prototype = {
let txn = db.transaction(storeNames, txn_type);
if (DEBUG) debug("Started transaction " + txn + " of type " + txn_type);
if (DEBUG) {
txn.oncomplete = function oncomplete(event) {
txn.oncomplete = function(event) {
debug("Transaction " + txn + " completed.");
};
txn.onerror = function onerror(event) {
//TODO check event.target.errorCode and show an appropiate error
// message according to it.
debug("Error occurred during transaction: " + event.target.errorCode);
txn.onerror = function(event) {
// TODO check event.target.error.name and show an appropiate error
// message according to it.
debug("Error occurred during transaction: " + event.target.error.name);
};
}
let stores;
@ -365,7 +353,7 @@ MobileMessageDB.prototype = {
// In order to get the highest key value, we open a key cursor in reverse
// order and get only the first pointed value.
let request = messageStore.openCursor(null, PREV);
request.onsuccess = function onsuccess(event) {
request.onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
if (DEBUG) {
@ -377,10 +365,10 @@ MobileMessageDB.prototype = {
self.lastMessageId = cursor.key || 0;
if (DEBUG) debug("Last assigned message ID was " + self.lastMessageId);
};
request.onerror = function onerror(event) {
request.onerror = function(event) {
if (DEBUG) {
debug("Could not get the last key from mobile message database " +
event.target.errorCode);
event.target.error.name);
}
};
});
@ -843,7 +831,7 @@ MobileMessageDB.prototype = {
let messageStore = transaction.objectStore(MESSAGE_STORE_NAME);
let request = messageStore.mozGetAll(lastMessageId);
request.onsuccess = function onsuccess() {
request.onsuccess = function() {
let messageRecord = request.result[0];
if (!messageRecord) {
if (DEBUG) debug("Message ID " + lastMessageId + " not found");
@ -861,10 +849,10 @@ MobileMessageDB.prototype = {
cursor.continue();
};
request.onerror = function onerror(event) {
request.onerror = function(event) {
if (DEBUG) {
if (event.target) {
debug("Caught error on transaction", event.target.errorCode);
debug("Caught error on transaction", event.target.error.name);
}
}
cursor.continue();
@ -2068,8 +2056,11 @@ MobileMessageDB.prototype = {
notifyResult(Cr.NS_OK, capture.messageRecord);
};
aTransaction.onabort = function(event) {
// TODO bug 832140 check event.target.errorCode
notifyResult(Cr.NS_ERROR_FAILURE, null);
if (DEBUG) debug("transaction abort due to " + event.target.error.name);
let error = (event.target.error.name === 'QuotaExceededError')
? Cr.NS_ERROR_FILE_NO_DEVICE_SPACE
: Cr.NS_ERROR_FAILURE;
notifyResult(error, null);
};
aFunc(capture, aStores);
@ -2097,16 +2088,19 @@ MobileMessageDB.prototype = {
let deletedInfo = { messageIds: [], threadIds: [] };
txn.oncomplete = function oncomplete(event) {
txn.oncomplete = function(event) {
if (aMessageRecord.id > self.lastMessageId) {
self.lastMessageId = aMessageRecord.id;
}
notifyResult(Cr.NS_OK, aMessageRecord);
self.notifyDeletedInfo(deletedInfo);
};
txn.onabort = function onabort(event) {
// TODO bug 832140 check event.target.errorCode
notifyResult(Cr.NS_ERROR_FAILURE, null);
txn.onabort = function(event) {
if (DEBUG) debug("transaction abort due to " + event.target.error.name);
let error = (event.target.error.name === 'QuotaExceededError')
? Cr.NS_ERROR_FILE_NO_DEVICE_SPACE
: Cr.NS_ERROR_FAILURE;
notifyResult(error, null);
};
let messageStore = stores[0];
@ -2162,7 +2156,7 @@ MobileMessageDB.prototype = {
let participantId = participantRecord.id;
let range = IDBKeyRange.bound([participantId, 0], [participantId, ""]);
let request = aMessageStore.index("participantIds").openCursor(range);
request.onsuccess = function onsuccess(event) {
request.onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
self.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
@ -2237,8 +2231,8 @@ MobileMessageDB.prototype = {
self.updateThreadByMessageChange(aMessageStore,
aThreadStore,
oldMessageRecord.threadId,
aMessageRecord.id,
oldMessageRecord.read,
[aMessageRecord.id],
oldMessageRecord.read ? 0 : 1,
aDeletedInfo);
}
};
@ -2361,7 +2355,7 @@ MobileMessageDB.prototype = {
getRequest = aMessageStore.index("envelopeId").get(id);
}
getRequest.onsuccess = function onsuccess(event) {
getRequest.onsuccess = function(event) {
let messageRecord = event.target.result;
if (!messageRecord) {
if (DEBUG) debug("type = " + id + " is not found");
@ -2489,18 +2483,23 @@ MobileMessageDB.prototype = {
},
updateThreadByMessageChange: function(messageStore, threadStore, threadId,
messageId, messageRead, deletedInfo) {
removedMsgIds, ignoredUnreadCount, deletedInfo) {
let self = this;
threadStore.get(threadId).onsuccess = function(event) {
// This must exist.
let threadRecord = event.target.result;
if (DEBUG) debug("Updating thread record " + JSON.stringify(threadRecord));
if (!messageRead) {
threadRecord.unreadCount--;
if (ignoredUnreadCount > 0) {
if (DEBUG) {
debug("Updating unread count : " + threadRecord.unreadCount +
" -> " + (threadRecord.unreadCount - ignoredUnreadCount));
}
threadRecord.unreadCount -= ignoredUnreadCount;
}
if (threadRecord.lastMessageId == messageId) {
if (removedMsgIds.indexOf(threadRecord.lastMessageId) >= 0) {
if (DEBUG) debug("MRU entry was deleted.");
// Check most recent sender/receiver.
let range = IDBKeyRange.bound([threadId, 0], [threadId, ""]);
let request = messageStore.index("threadId")
@ -2509,7 +2508,7 @@ MobileMessageDB.prototype = {
let cursor = event.target.result;
if (!cursor) {
if (DEBUG) {
debug("Deleting mru entry for thread id " + threadId);
debug("All messages were deleted. Delete this thread.");
}
threadStore.delete(threadId);
if (deletedInfo) {
@ -2534,13 +2533,8 @@ MobileMessageDB.prototype = {
}
threadStore.put(threadRecord);
};
} else if (!messageRead) {
// Shortcut, just update the unread count.
if (DEBUG) {
debug("Updating unread count for thread id " + threadId + ": " +
(threadRecord.unreadCount + 1) + " -> " +
threadRecord.unreadCount);
}
} else if (ignoredUnreadCount > 0) {
if (DEBUG) debug("Shortcut, just update the unread count.");
threadStore.put(threadRecord);
}
};
@ -2732,7 +2726,7 @@ MobileMessageDB.prototype = {
let self = this;
this.newTxnWithCallback(aCallback, function(aCapture, aMessageStore) {
let getRequest = aMessageStore.index("envelopeId").get(aEnvelopeId);
getRequest.onsuccess = function onsuccess(event) {
getRequest.onsuccess = function(event) {
let messageRecord = event.target.result;
if (!messageRecord) {
if (DEBUG) debug("envelopeId '" + aEnvelopeId + "' not found");
@ -2783,7 +2777,7 @@ MobileMessageDB.prototype = {
}
let request = messageStore.index("transactionId").get(aTransactionId);
txn.oncomplete = function oncomplete(event) {
txn.oncomplete = function(event) {
if (DEBUG) debug("Transaction " + txn + " completed.");
let messageRecord = request.result;
if (!messageRecord) {
@ -2796,10 +2790,10 @@ MobileMessageDB.prototype = {
aCallback.notify(Cr.NS_OK, messageRecord, null);
};
txn.onerror = function onerror(event) {
txn.onerror = function(event) {
if (DEBUG) {
if (event.target) {
debug("Caught error on transaction", event.target.errorCode);
debug("Caught error on transaction", event.target.error.name);
}
}
aCallback.notify(Cr.NS_ERROR_FAILURE, null, null);
@ -2818,7 +2812,7 @@ MobileMessageDB.prototype = {
}
let request = messageStore.mozGetAll(aMessageId);
txn.oncomplete = function oncomplete() {
txn.oncomplete = function() {
if (DEBUG) debug("Transaction " + txn + " completed.");
if (request.result.length > 1) {
if (DEBUG) debug("Got too many results for id " + aMessageId);
@ -2843,10 +2837,10 @@ MobileMessageDB.prototype = {
aCallback.notify(Cr.NS_OK, messageRecord, domMessage);
};
txn.onerror = function onerror(event) {
txn.onerror = function(event) {
if (DEBUG) {
if (event.target) {
debug("Caught error on transaction", event.target.errorCode);
debug("Caught error on transaction", event.target.error.name);
}
}
aCallback.notify(Cr.NS_ERROR_FAILURE, null, null);
@ -2878,7 +2872,7 @@ MobileMessageDB.prototype = {
return;
}
txn.oncomplete = function oncomplete(event) {
txn.oncomplete = function(event) {
if (DEBUG) debug("Transaction " + txn + " completed.");
if (completeMessage) {
// Rebuild full body
@ -2910,9 +2904,12 @@ MobileMessageDB.prototype = {
aCallback.notify(Cr.NS_OK, completeMessage);
};
txn.onabort = function onerror(event) {
if (DEBUG) debug("Caught error on transaction", event.target.errorCode);
aCallback.notify(Cr.NS_ERROR_FAILURE, null, null);
txn.onabort = function(event) {
if (DEBUG) debug("transaction abort due to " + event.target.error.name);
let error = (event.target.error.name === 'QuotaExceededError')
? Cr.NS_ERROR_FILE_NO_DEVICE_SPACE
: Cr.NS_ERROR_FAILURE;
aCallback.notify(error, null);
};
aSmsSegment.hash = aSmsSegment.sender + ":" +
@ -3025,21 +3022,37 @@ MobileMessageDB.prototype = {
let deletedInfo = { messageIds: [], threadIds: [] };
txn.onerror = function onerror(event) {
if (DEBUG) debug("Caught error on transaction", event.target.errorCode);
//TODO look at event.target.errorCode, pick appropriate error constant
aRequest.notifyDeleteMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
txn.onabort = function(event) {
if (DEBUG) debug("transaction abort due to " + event.target.error.name);
let error = (event.target.error.name === 'QuotaExceededError')
? Ci.nsIMobileMessageCallback.STORAGE_FULL_ERROR
: Ci.nsIMobileMessageCallback.INTERNAL_ERROR;
aRequest.notifyDeleteMessageFailed(error);
};
const messageStore = stores[0];
const threadStore = stores[1];
txn.oncomplete = function oncomplete(event) {
txn.oncomplete = function(event) {
if (DEBUG) debug("Transaction " + txn + " completed.");
aRequest.notifyMessageDeleted(deleted, length);
self.notifyDeletedInfo(deletedInfo);
};
let threadsToUpdate = {};
let numOfMessagesToDelete = length;
let updateThreadInfo = function() {
for (let threadId in threadsToUpdate) {
let threadInfo = threadsToUpdate[threadId];
self.updateThreadByMessageChange(messageStore,
threadStore,
threadInfo.threadId,
threadInfo.removedMsgIds,
threadInfo.ignoredUnreadCount,
deletedInfo);
}
};
for (let i = 0; i < length; i++) {
let messageId = messageIds[i];
deleted[i] = false;
@ -3052,22 +3065,40 @@ MobileMessageDB.prototype = {
// First actually delete the message.
messageStore.delete(messageId).onsuccess = function(event) {
if (DEBUG) debug("Message id " + messageId + " deleted");
if (deletedInfo) {
deletedInfo.messageIds.push(messageId);
numOfMessagesToDelete--;
deleted[messageIndex] = true;
deletedInfo.messageIds.push(messageId);
// Cache thread info to be updated.
let threadId = messageRecord.threadId;
if (!threadsToUpdate[threadId]) {
threadsToUpdate[threadId] = {
threadId: threadId,
removedMsgIds: [messageId],
ignoredUnreadCount: (!messageRecord.read) ? 1 : 0
};
} else {
let threadInfo = threadsToUpdate[threadId];
threadInfo.removedMsgIds.push(messageId);
if (!messageRecord.read) {
threadInfo.ignoredUnreadCount++;
}
}
deleted[messageIndex] = true;
// Then update unread count and most recent message.
self.updateThreadByMessageChange(messageStore,
threadStore,
messageRecord.threadId,
messageId,
messageRecord.read,
deletedInfo);
// After all messsages are deleted, update unread count and most
// recent message of related threads at once.
if (!numOfMessagesToDelete) {
updateThreadInfo();
}
};
} else if (DEBUG) {
debug("Message id " + messageId + " does not exist");
} else {
if (DEBUG) debug("Message id " + messageId + " does not exist");
numOfMessagesToDelete--;
if (!numOfMessagesToDelete) {
updateThreadInfo();
}
}
}.bind(null, i);
}
@ -3109,14 +3140,17 @@ MobileMessageDB.prototype = {
return;
}
txn.onerror = function onerror(event) {
if (DEBUG) debug("Caught error on transaction ", event.target.errorCode);
aRequest.notifyMarkMessageReadFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
txn.onabort = function(event) {
if (DEBUG) debug("transaction abort due to " + event.target.error.name);
let error = (event.target.error.name === 'QuotaExceededError')
? Ci.nsIMobileMessageCallback.STORAGE_FULL_ERROR
: Ci.nsIMobileMessageCallback.INTERNAL_ERROR;
aRequest.notifyMarkMessageReadFailed(error);
};
let messageStore = stores[0];
let threadStore = stores[1];
messageStore.get(messageId).onsuccess = function onsuccess(event) {
messageStore.get(messageId).onsuccess = function(event) {
let messageRecord = event.target.result;
if (!messageRecord) {
if (DEBUG) debug("Message ID " + messageId + " not found");
@ -3158,7 +3192,7 @@ MobileMessageDB.prototype = {
}
if (DEBUG) debug("Message.read set to: " + value);
messageStore.put(messageRecord).onsuccess = function onsuccess(event) {
messageStore.put(messageRecord).onsuccess = function(event) {
if (DEBUG) {
debug("Update successfully completed. Message: " +
JSON.stringify(event.target.result));
@ -3201,8 +3235,8 @@ MobileMessageDB.prototype = {
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);
txn.onerror = function(event) {
if (DEBUG) debug("Caught error on transaction ", event.target.error.name);
collector.collect(null, COLLECT_ID_ERROR, COLLECT_TIMESTAMP_UNUSED);
};
let request = threadStore.index("lastTimestamp").openKeyCursor(null, PREV);
@ -3240,7 +3274,7 @@ let FilterSearcherHelper = {
filterIndex: function(index, range, direction, txn, collect) {
let messageStore = txn.objectStore(MESSAGE_STORE_NAME);
let request = messageStore.index(index).openKeyCursor(range, direction);
request.onsuccess = function onsuccess(event) {
request.onsuccess = function(event) {
let cursor = event.target.result;
// Once the cursor has retrieved all keys that matches its key range,
// the filter search is done.
@ -3253,8 +3287,8 @@ let FilterSearcherHelper = {
collect(txn, COLLECT_ID_END, COLLECT_TIMESTAMP_UNUSED);
}
};
request.onerror = function onerror(event) {
if (DEBUG && event) debug("IDBRequest error " + event.target.errorCode);
request.onerror = function(event) {
if (DEBUG && event) debug("IDBRequest error " + event.target.error.name);
collect(txn, COLLECT_ID_ERROR, COLLECT_TIMESTAMP_UNUSED);
};
},
@ -3306,8 +3340,8 @@ let FilterSearcherHelper = {
*/
transact: function(mmdb, txn, error, filter, reverse, collect) {
if (error) {
//TODO look at event.target.errorCode, pick appropriate error constant.
if (DEBUG) debug("IDBRequest error " + error.target.errorCode);
// TODO look at event.target.error.name, pick appropriate error constant.
if (DEBUG) debug("IDBRequest error " + event.target.error.name);
collect(txn, COLLECT_ID_ERROR, COLLECT_TIMESTAMP_UNUSED);
return;
}
@ -3745,7 +3779,7 @@ GetMessagesCursor.prototype = {
let getRequest = messageStore.get(messageId);
let self = this;
getRequest.onsuccess = function onsuccess(event) {
getRequest.onsuccess = function(event) {
if (DEBUG) {
debug("notifyNextMessageInListGot - messageId: " + messageId);
}
@ -3753,7 +3787,7 @@ GetMessagesCursor.prototype = {
self.mmdb.createDomMessageFromRecord(event.target.result);
self.callback.notifyCursorResult(domMessage);
};
getRequest.onerror = function onerror(event) {
getRequest.onerror = function(event) {
if (DEBUG) {
debug("notifyCursorError - messageId: " + messageId);
}
@ -3819,7 +3853,7 @@ GetThreadsCursor.prototype = {
let getRequest = threadStore.get(threadId);
let self = this;
getRequest.onsuccess = function onsuccess(event) {
getRequest.onsuccess = function(event) {
let threadRecord = event.target.result;
if (DEBUG) {
debug("notifyCursorResult: " + JSON.stringify(threadRecord));
@ -3834,7 +3868,7 @@ GetThreadsCursor.prototype = {
threadRecord.lastMessageType);
self.callback.notifyCursorResult(thread);
};
getRequest.onerror = function onerror(event) {
getRequest.onerror = function(event) {
if (DEBUG) {
debug("notifyCursorError - threadId: " + threadId);
}

View File

@ -17,10 +17,6 @@ const RIL_MOBILEMESSAGEDATABASESERVICE_CONTRACTID =
const RIL_MOBILEMESSAGEDATABASESERVICE_CID =
Components.ID("{29785f90-6b5b-11e2-9201-3b280170b2ec}");
XPCOMUtils.defineLazyServiceGetter(this, "gDiskSpaceWatcher",
"@mozilla.org/toolkit/disk-space-watcher;1",
"nsIDiskSpaceWatcher");
const DB_NAME = "sms";
/**
@ -33,9 +29,6 @@ function MobileMessageDatabaseService() {
let mmdb = new MMDB.MobileMessageDB();
mmdb.init(DB_NAME, 0, mmdb.updatePendingTransactionToError.bind(mmdb));
mmdb.isDiskFull = function() {
return gDiskSpaceWatcher.isDiskFull;
};
this.mmdb = mmdb;
}
MobileMessageDatabaseService.prototype = {

View File

@ -234,6 +234,44 @@ function markMessageRead(aMmdb, aMessageId, aRead) {
return deferred.promise;
}
/**
* A convenient function for calling |mmdb.deleteMessage(...)|.
*
* Fulfill params: array of deleted flags.
* Reject params: Ci.nsIMobileMessageCallback.FOO.
*
* @return A deferred promise.
*/
function deleteMessage(aMmdb, aMessageIds, aLength) {
let deferred = Promise.defer();
aMmdb.deleteMessage(aMessageIds, aLength, {
notifyDeleteMessageFailed: function(aRv) {
ok(true, "deleteMessage returns a unsuccessful code: " + aRv);
deferred.reject(aRv);
},
notifyMessageDeleted: function(aDeleted, aLength) {
ok(true, "deleteMessage successfully!");
deferred.resolve(aDeleted);
}
});
return deferred.promise;
}
/**
* A convenient function for calling |mmdb.saveSmsSegment(...)|.
*
* Fulfill params: [<Cr.NS_ERROR_FOO>, <completeMessage>].
* Reject params: same as fulfill params.
*
* @return A deferred promise.
*/
function saveSmsSegment(aMmdb, aSmsSegment) {
return callMmdbMethod(aMmdb, "saveSmsSegment", aSmsSegment);
}
/**
* Utility function for calling cursor-based MMDB methods.
*

View File

@ -6,13 +6,11 @@ MARIONETTE_HEAD_JS = 'mmdb_head.js';
const DBNAME = "test_mmdb_full_storage:" + newUUID();
let gIsDiskFull = true;
function newSavableMessage() {
function newSavableMessage(aSender, aReceiver) {
return {
type: "sms",
sender: "+0987654321",
receiver: "+1234567890",
sender: aSender ? aSender : "+0987654321",
receiver: aReceiver? aReceiver : "+1234567890",
body: "quick fox jump over the lazy dog",
deliveryStatusRequested: false,
messageClass: "normal",
@ -21,6 +19,12 @@ function newSavableMessage() {
};
}
function setStorageFull(aFull) {
SpecialPowers.notifyObserversInParentProcess(null,
"disk-space-watcher",
aFull ? "full" : "free");
}
function isFileNoDeviceSpaceError(aErrorResult) {
is(aErrorResult, Cr.NS_ERROR_FILE_NO_DEVICE_SPACE, "Database error code");
}
@ -33,85 +37,157 @@ function isCallbackStorageFullError(aErrorCode) {
function testSaveSendingMessage(aMmdb) {
log("testSaveSendingMessage()");
gIsDiskFull = true;
setStorageFull(true);
return saveSendingMessage(aMmdb, newSavableMessage())
// Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>],
// and we need only the error code in both cases.
.then((aValue) => aValue[0],
(aValue) => aValue[0])
.then(isFileNoDeviceSpaceError);
.then(isFileNoDeviceSpaceError)
.then(() => setStorageFull(false));
}
function testSaveReceivedMessage(aMmdb) {
log("testSaveReceivedMessage()");
gIsDiskFull = true;
setStorageFull(true);
return saveReceivedMessage(aMmdb, newSavableMessage())
// Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>],
// and we need only the error code in both cases.
.then((aValue) => aValue[0],
(aValue) => aValue[0])
.then(isFileNoDeviceSpaceError);
.then(isFileNoDeviceSpaceError)
.then(() => setStorageFull(false));
}
function testGetMessageRecordById(aMmdb) {
log("testGetMessageRecordById()");
gIsDiskFull = false;
setStorageFull(false);
return saveReceivedMessage(aMmdb, newSavableMessage())
// Resolved result is [<Cr.NS_ERROR_FOO>, <DOM message>],
.then(function(aValue) {
let domMessage = aValue[1];
gIsDiskFull = true;
return getMessageRecordById(aMmdb, domMessage.id);
setStorageFull(true);
return getMessageRecordById(aMmdb, domMessage.id)
.then(() => setStorageFull(false));
});
}
function testMarkMessageRead(aMmdb) {
log("testMarkMessageRead()");
gIsDiskFull = false;
setStorageFull(false);
return saveReceivedMessage(aMmdb, newSavableMessage())
// Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <DOM message>].
.then(function(aValue) {
let domMessage = aValue[1];
gIsDiskFull = true;
setStorageFull(true);
return markMessageRead(aMmdb, domMessage.id, true)
.then(null, (aValue) => aValue)
.then(isCallbackStorageFullError);
.then(isCallbackStorageFullError)
.then(() => setStorageFull(false));
});
}
function testDeleteMessage(aMmdb) {
log("testDeleteMessage()");
// Note:
// Due to thread-based design in MobileMessageDB and transaction-based design
// in indexedDB, There are 2 restrictions to delete a message when storage full
// in the following condition:
// If the deletion won't remove all the messages in a thead and
// 1. the last message of the thread or
// 2. an unread message
// are to be deleted.
//
// This will trigger an update of the thread's subject, message body,
// unread count, etc but update operation is restricted when storage is full.
let testAddress = "1111111111";
let savedMsgIds = [];
let promises = [];
let numOfTestMessages = 5;
setStorageFull(false);
// Save several unread messages to the same thread then delete them.
for (let i = 0; i < numOfTestMessages; i++) {
promises.push(saveReceivedMessage(aMmdb, newSavableMessage(testAddress))
.then((aValue) => { savedMsgIds.push(aValue[1].id); }));
}
return Promise.all(promises)
.then(() => setStorageFull(true))
// Failure is expected when deleting the last one.
.then(() => deleteMessage(aMmdb, [savedMsgIds[numOfTestMessages - 1]], 1))
.then(null, (aValue) => aValue)
.then(isCallbackStorageFullError)
// Failure is expected when deleting an unread message.
.then(() => deleteMessage(aMmdb, [savedMsgIds[0]], 1))
.then(null, (aValue) => aValue)
.then(isCallbackStorageFullError)
// Delete all messages in the thread.
.then(() => deleteMessage(aMmdb, savedMsgIds, savedMsgIds.length))
.then(() => setStorageFull(false));
}
function testSaveSmsSegment(aMmdb) {
log("testSaveSmsSegment()");
let smsSegment = {
sender: "+0987654321",
encoding: 0x00, // GSM 7bit alphabet
iccId: "1029384756",
segmentRef: 0,
segmentSeq: 1,
segmentMaxSeq: 3,
body: "quick fox jump over the lazy dog"
}
setStorageFull(true);
return saveSmsSegment(aMmdb, smsSegment)
// Resolved/rejected results are both [<Cr.NS_ERROR_FOO>, <completeMessage>],
// and we need only the error code in both cases.
.then((aValue) => aValue[0],
(aValue) => aValue[0])
.then(isFileNoDeviceSpaceError)
.then(() => setStorageFull(false));
}
function testCreateMessageCursor(aMmdb) {
log("testCreateMessageCursor()");
gIsDiskFull = true;
return createMessageCursor(aMmdb, {}, false);
setStorageFull(true);
return createMessageCursor(aMmdb, {}, false)
.then(() => setStorageFull(false));
}
function testCreateThreadCursor(aMmdb) {
log("testCreateThreadCursor()");
gIsDiskFull = true;
return createThreadCursor(aMmdb);
setStorageFull(true);
return createThreadCursor(aMmdb)
.then(() => setStorageFull(false));
}
startTestBase(function testCaseMain() {
let mmdb = newMobileMessageDB();
return initMobileMessageDB(mmdb, DBNAME, 0)
.then(function() {
mmdb.isDiskFull = function() {
return gIsDiskFull;
};
})
.then(() => testSaveSendingMessage(mmdb))
.then(() => testSaveReceivedMessage(mmdb))
.then(() => testGetMessageRecordById(mmdb))
.then(() => testMarkMessageRead(mmdb))
.then(() => testDeleteMessage(mmdb))
.then(() => testSaveSmsSegment(mmdb))
.then(() => testCreateMessageCursor(mmdb))
.then(() => testCreateThreadCursor(mmdb))

View File

@ -192,8 +192,9 @@ let LEGACY = {
self.updateThreadByMessageChange(aMessageStore,
aThreadStore,
oldMessageRecord.threadId,
aMessageRecord.id,
oldMessageRecord.read);
[aMessageRecord.id],
oldMessageRecord.read ? 0 : 1,
null);
}
};
};

View File

@ -810,12 +810,8 @@ XPCOMUtils.defineLazyGetter(this, "gDataConnectionManager", function () {
let connHandler = this._connectionHandlers[this._currentDataClientId];
if (connHandler.allDataDisconnected() &&
typeof this._pendingDataCallRequest === "function") {
if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND) {
let radioInterface = connHandler.radioInterface;
radioInterface.setDataRegistration(false);
}
if (DEBUG) {
this.debug("All data calls disconnected, setup pending data call.");
this.debug("All data calls disconnected, process pending data settings.");
}
this._pendingDataCallRequest();
this._pendingDataCallRequest = null;
@ -828,8 +824,8 @@ XPCOMUtils.defineLazyGetter(this, "gDataConnectionManager", function () {
}
this._dataDefaultClientId = newDefault;
// This is to handle boot up stage.
if (this._currentDataClientId == -1) {
// This is to handle boot up stage.
this._currentDataClientId = this._dataDefaultClientId;
let connHandler = this._connectionHandlers[this._currentDataClientId];
let radioInterface = connHandler.radioInterface;
@ -853,35 +849,37 @@ XPCOMUtils.defineLazyGetter(this, "gDataConnectionManager", function () {
let newIface = newConnHandler.radioInterface;
let newSettings = newConnHandler.dataCallSettings;
if (!this._dataEnabled) {
let applyPendingDataSettings = (function() {
if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
RILQUIRKS_SUBSCRIPTION_CONTROL) {
oldIface.setDataRegistration(false);
newIface.setDataRegistration(true);
oldIface.setDataRegistration(false)
.then(() => {
if (this._dataEnabled) {
newSettings.oldEnabled = newSettings.enabled;
newSettings.enabled = true;
}
this._currentDataClientId = this._dataDefaultClientId;
return newIface.setDataRegistration(true);
})
.then(() => newConnHandler.updateRILNetworkInterface());
return;
}
if (this._dataEnabled) {
newSettings.oldEnabled = newSettings.enabled;
newSettings.enabled = true;
}
this._currentDataClientId = this._dataDefaultClientId;
return;
newConnHandler.updateRILNetworkInterface();
}).bind(this);
if (this._dataEnabled) {
oldSettings.oldEnabled = oldSettings.enabled;
oldSettings.enabled = false;
}
oldSettings.oldEnabled = oldSettings.enabled;
oldSettings.enabled = false;
if (oldConnHandler.anyDataConnected()) {
this._pendingDataCallRequest = function () {
if (DEBUG) {
this.debug("Executing pending data call request.");
}
if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
RILQUIRKS_SUBSCRIPTION_CONTROL) {
newIface.setDataRegistration(true);
}
newSettings.oldEnabled = newSettings.enabled;
newSettings.enabled = this._dataEnabled;
this._currentDataClientId = this._dataDefaultClientId;
newConnHandler.updateRILNetworkInterface();
};
this._pendingDataCallRequest = applyPendingDataSettings;
if (DEBUG) {
this.debug("_handleDataClientIdChange: existing data call(s) active" +
", wait for them to get disconnected.");
@ -890,16 +888,7 @@ XPCOMUtils.defineLazyGetter(this, "gDataConnectionManager", function () {
return;
}
newSettings.oldEnabled = newSettings.enabled;
newSettings.enabled = true;
this._currentDataClientId = this._dataDefaultClientId;
if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND ||
RILQUIRKS_SUBSCRIPTION_CONTROL) {
oldIface.setDataRegistration(false);
newIface.setDataRegistration(true);
}
newConnHandler.updateRILNetworkInterface();
applyPendingDataSettings();
},
_shutdown: function() {
@ -2821,7 +2810,15 @@ RadioInterface.prototype = {
},
setDataRegistration: function(attach) {
this.workerMessenger.send("setDataRegistration", {attach: attach});
let deferred = Promise.defer();
this.workerMessenger.send("setDataRegistration",
{attach: attach},
(function(response) {
// Always resolve to proceed with the following steps.
deferred.resolve(response.errorMsg ? response.errorMsg : null);
}).bind(this));
return deferred.promise;
},
/**

View File

@ -2317,7 +2317,7 @@ RilObject.prototype = {
if (RILQUIRKS_DATA_REGISTRATION_ON_DEMAND) {
let request = options.attach ? RIL_REQUEST_GPRS_ATTACH :
RIL_REQUEST_GPRS_DETACH;
this.context.Buf.simpleRequest(request);
this.context.Buf.simpleRequest(request, options);
} else if (RILQUIRKS_SUBSCRIPTION_CONTROL && options.attach) {
this.context.Buf.simpleRequest(REQUEST_SET_DATA_SUBSCRIPTION, options);
}
@ -6688,7 +6688,17 @@ RilObject.prototype[REQUEST_SET_UICC_SUBSCRIPTION] = function REQUEST_SET_UICC_S
this.setDataRegistration({attach: true});
}
};
RilObject.prototype[REQUEST_SET_DATA_SUBSCRIPTION] = null;
RilObject.prototype[REQUEST_SET_DATA_SUBSCRIPTION] = function REQUEST_SET_DATA_SUBSCRIPTION(length, options) {
if (!options.rilMessageType) {
// The request was made by ril_worker itself. Don't report.
return;
}
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_UICC_SUBSCRIPTION] = null;
RilObject.prototype[REQUEST_GET_DATA_SUBSCRIPTION] = null;
RilObject.prototype[REQUEST_GET_UNLOCK_RETRY_COUNT] = function REQUEST_GET_UNLOCK_RETRY_COUNT(length, options) {
@ -6699,8 +6709,24 @@ RilObject.prototype[REQUEST_GET_UNLOCK_RETRY_COUNT] = function REQUEST_GET_UNLOC
options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
this.sendChromeMessage(options);
};
RilObject.prototype[RIL_REQUEST_GPRS_ATTACH] = null;
RilObject.prototype[RIL_REQUEST_GPRS_DETACH] = null;
RilObject.prototype[RIL_REQUEST_GPRS_ATTACH] = function RIL_REQUEST_GPRS_ATTACH(length, options) {
if (!options.rilMessageType) {
// The request was made by ril_worker itself. Don't report.
return;
}
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RilObject.prototype[RIL_REQUEST_GPRS_DETACH] = function RIL_REQUEST_GPRS_DETACH(length, options) {
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RilObject.prototype[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
let radioState = this.context.Buf.readInt32();
let newState;

View File

@ -402,9 +402,16 @@ function createExecuteContentSandbox(aWindow, timeout) {
}
});
XPCOMUtils.defineLazyGetter(sandbox, 'SpecialPowers', function() {
return new SpecialPowers(aWindow);
});
if (aWindow.wrappedJSObject.SpecialPowers != undefined) {
XPCOMUtils.defineLazyGetter(sandbox, 'SpecialPowers', function() {
return aWindow.wrappedJSObject.SpecialPowers;
});
}
else {
XPCOMUtils.defineLazyGetter(sandbox, 'SpecialPowers', function() {
return new SpecialPowers(aWindow);
});
}
sandbox.asyncComplete = function sandbox_asyncComplete(value, status, stack, commandId) {
if (commandId == asyncTestCommandId) {

View File

@ -756,7 +756,7 @@ class B2GOptions(MochitestOptions):
defaults["testPath"] = ""
defaults["extensionsToExclude"] = ["specialpowers"]
# See dependencies of bug 1038943.
defaults["leakThreshold"] = 5099
defaults["leakThreshold"] = 4991
self.set_defaults(**defaults)
def verifyRemoteOptions(self, options):