This commit is contained in:
Ryan VanderMeulen 2013-11-19 20:40:17 -05:00
Родитель 27e2b44c9e 10d3875eb2
Коммит 9c932cff15
31 изменённых файлов: 538 добавлений и 247 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{
"revision": "4e8959a60a4ee1373e71fe31229ba5bd7575c02c",
"revision": "14a570c0af0ad29420a47318576fc365ebf7b10a",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -123,12 +123,6 @@ public:
NS_IMPL_ISUPPORTS1(nsContentView, nsIContentView)
bool
nsContentView::IsRoot() const
{
return mScrollId == FrameMetrics::ROOT_SCROLL_ID;
}
nsresult
nsContentView::Update(const ViewConfig& aConfig)
{
@ -2376,7 +2370,7 @@ nsFrameLoader::GetRootContentView(nsIContentView** aContentView)
return NS_OK;
}
nsContentView* view = rfp->GetContentView();
nsContentView* view = rfp->GetRootContentView();
NS_ABORT_IF_FALSE(view, "Should always be able to create root scrollable!");
nsRefPtr<nsIContentView>(view).forget(aContentView);

Просмотреть файл

@ -103,7 +103,7 @@ public:
float mYScale;
};
nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId,
nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId, bool aIsRoot,
ViewConfig aConfig = ViewConfig())
: mViewportSize(0, 0)
, mContentSize(0, 0)
@ -111,10 +111,14 @@ public:
, mParentScaleY(1.0)
, mFrameLoader(aFrameLoader)
, mScrollId(aScrollId)
, mIsRoot(aIsRoot)
, mConfig(aConfig)
{}
bool IsRoot() const;
bool IsRoot() const
{
return mIsRoot;
}
ViewID GetId() const
{
@ -137,6 +141,7 @@ private:
nsresult Update(const ViewConfig& aConfig);
ViewID mScrollId;
bool mIsRoot;
ViewConfig mConfig;
};

Просмотреть файл

@ -1699,22 +1699,6 @@ nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
return NS_ERROR_DOM_SECURITY_ERR;
}
if (aID == FrameMetrics::ROOT_SCROLL_ID) {
nsPresContext* presContext = GetPresContext();
if (!presContext) {
return NS_ERROR_NOT_AVAILABLE;
}
nsIDocument* document = presContext->Document();
Element* rootElement = document->GetRootElement();
if (!rootElement) {
return NS_ERROR_NOT_AVAILABLE;
}
CallQueryInterface(rootElement, aResult);
return NS_OK;
}
nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
return content ? CallQueryInterface(content, aResult) : NS_OK;
}

Просмотреть файл

@ -293,7 +293,7 @@ parent:
* The zoom controller code lives on the parent side and so this allows it to
* have up-to-date zoom constraints.
*/
UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId,
UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot,
bool aAllowZoom, CSSToScreenScale aMinZoom, CSSToScreenScale aMaxZoom);
/**

Просмотреть файл

@ -303,7 +303,6 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent)
ViewID viewId;
uint32_t presShellId;
nsIScrollableFrame* scrollFrame = nullptr;
nsCOMPtr<nsIContent> content;
if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(target))
@ -317,27 +316,19 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent)
if (!nsLayoutUtils::FindIDFor(content, &viewId))
return NS_ERROR_UNEXPECTED;
// Note that we cannot use FindScrollableFrameFor(ROOT_SCROLL_ID) because
// it might return the root element from a different page in the case where
// that page is in the bfcache and this page is not run through layout
// before being drawn to the screen. Hence the code blocks below treat
// ROOT_SCROLL_ID separately from the non-ROOT_SCROLL_ID case.
nsIScrollableFrame* scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId);
if (!scrollFrame)
return NS_OK;
CSSIntPoint scrollOffset;
if (viewId != FrameMetrics::ROOT_SCROLL_ID) {
scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId);
if (!scrollFrame) {
return NS_OK;
}
scrollOffset = scrollFrame->GetScrollPositionCSSPixels();
} else {
CSSIntPoint scrollOffset = scrollFrame->GetScrollPositionCSSPixels();
if (viewId == mLastMetrics.mScrollId) {
// For the root frame, we store the last metrics, including the last
// scroll offset, sent by APZC. (This is updated in ProcessUpdateFrame()).
// We use this here to avoid sending APZC back a scroll event that
// originally came from APZC (besides being unnecessary, the event might
// be slightly out of date by the time it reaches APZC).
// We should probably do this for subframes, too.
utils->GetScrollXY(false, &scrollOffset.x, &scrollOffset.y);
if (RoundedToInt(mLastMetrics.mScrollOffset) == scrollOffset) {
return NS_OK;
}
@ -347,6 +338,7 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent)
// gets a chance to update it.
mLastMetrics.mScrollOffset = scrollOffset;
}
SendUpdateScrollOffset(presShellId, viewId, scrollOffset);
}
@ -547,6 +539,7 @@ TabChild::HandlePossibleViewportChange()
nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
SendUpdateZoomConstraints(presShellId,
viewId,
/* isRoot = */ true,
viewportInfo.IsZoomAllowed(),
viewportInfo.GetMinZoom(),
viewportInfo.GetMaxZoom());
@ -1537,14 +1530,14 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
{
MOZ_ASSERT(aFrameMetrics.mScrollId != FrameMetrics::NULL_SCROLL_ID);
if (aFrameMetrics.mScrollId == FrameMetrics::ROOT_SCROLL_ID) {
if (aFrameMetrics.mIsRoot) {
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
if (APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) {
return ProcessUpdateFrame(aFrameMetrics);
}
} else {
// aFrameMetrics.mScrollId is not FrameMetrics::ROOT_SCROLL_ID,
// so we are trying to update a subframe. This requires special handling.
// aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
// This requires special handling.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(
aFrameMetrics.mScrollId);
if (content) {

Просмотреть файл

@ -1628,12 +1628,13 @@ TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
bool
TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const bool& aIsRoot,
const bool& aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->UpdateZoomConstraints(aPresShellId, aViewId, aAllowZoom, aMinZoom, aMaxZoom);
rfp->UpdateZoomConstraints(aPresShellId, aViewId, aIsRoot, aAllowZoom, aMinZoom, aMaxZoom);
}
return true;
}

Просмотреть файл

@ -167,6 +167,7 @@ public:
const CSSRect& aRect);
virtual bool RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const bool& aIsRoot,
const bool& aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom);

Просмотреть файл

@ -25,7 +25,7 @@ interface nsIRilMobileMessageDatabaseRecordCallback : nsISupports
void notify(in nsresult aRv, in jsval aMessageRecord, in nsISupports aDomMessage);
};
[scriptable, uuid(f6cd671e-f9af-11e2-b64b-1fb87e9c217c)]
[scriptable, uuid(d5374151-7451-4590-a70e-40c49c1369ce)]
interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
{
/**
@ -38,6 +38,7 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
* - If |type| == "sms", we also need:
* - |messageClass| DOMString: the message class of received message
* - |receiver| DOMString: the phone number of receiver
* - |pid| Number: the TP-PID field of the SMS TPDU, default 0.
*
* - If |type| == "mms", we also need:
* - |delivery| DOMString: the delivery state of received message
@ -49,7 +50,7 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
* Note: |deliveryStatus| should only contain single string to specify
* the delivery status of MMS message for the phone owner self.
*/
long saveReceivedMessage(in jsval aMessage,
void saveReceivedMessage(in jsval aMessage,
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
/**
@ -66,7 +67,7 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
* - If |type| == "mms", we also need:
* - |receivers| DOMString Array: the phone numbers of receivers
*/
long saveSendingMessage(in jsval aMessage,
void saveSendingMessage(in jsval aMessage,
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
/**

Просмотреть файл

@ -10,6 +10,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
var RIL = {};
Cu.import("resource://gre/modules/ril_consts.js", RIL);
const RIL_MOBILEMESSAGEDATABASESERVICE_CONTRACTID =
"@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1";
const RIL_MOBILEMESSAGEDATABASESERVICE_CID =
@ -24,7 +27,7 @@ const DISABLE_MMS_GROUPING_FOR_RECEIVING = true;
const DB_NAME = "sms";
const DB_VERSION = 18;
const DB_VERSION = 19;
const MESSAGE_STORE_NAME = "sms";
const THREAD_STORE_NAME = "thread";
const PARTICIPANT_STORE_NAME = "participant";
@ -252,6 +255,10 @@ MobileMessageDatabaseService.prototype = {
self.upgradeSchema17(event.target.transaction, next);
break;
case 18:
if (DEBUG) debug("Upgrade to version 19. Add pid for incoming SMS.");
self.upgradeSchema18(event.target.transaction, next);
break;
case 19:
// This will need to be moved for each new version
if (DEBUG) debug("Upgrade finished.");
break;
@ -1151,6 +1158,28 @@ MobileMessageDatabaseService.prototype = {
};
},
/**
* Add pid for incoming SMS.
*/
upgradeSchema18: function upgradeSchema18(transaction, next) {
let messageStore = transaction.objectStore(MESSAGE_STORE_NAME);
messageStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
next();
return;
}
let messageRecord = cursor.value;
if (messageRecord.type == "sms") {
messageRecord.pid = RIL.PDU_PID_DEFAULT;
cursor.update(messageRecord);
}
cursor.continue();
};
},
matchParsedPhoneNumbers: function matchParsedPhoneNumbers(addr1, parsedAddr1,
addr2, parsedAddr2) {
if ((parsedAddr1.internationalNumber &&
@ -1455,30 +1484,26 @@ MobileMessageDatabaseService.prototype = {
},
saveRecord: function saveRecord(aMessageRecord, aAddresses, aCallback) {
let isOverriding = (aMessageRecord.id !== undefined);
if (!isOverriding) {
// Assign a new id.
this.lastMessageId += 1;
aMessageRecord.id = this.lastMessageId;
}
if (DEBUG) debug("Going to store " + JSON.stringify(aMessageRecord));
let self = this;
function notifyResult(rv) {
if (!aCallback) {
return;
}
let domMessage = self.createDomMessageFromRecord(aMessageRecord);
aCallback.notify(rv, domMessage);
}
this.newTxn(READ_WRITE, function(error, txn, stores) {
let notifyResult = function(rv) {
if (aCallback) {
aCallback.notify(rv, self.createDomMessageFromRecord(aMessageRecord));
}
};
if (error) {
// TODO bug 832140 check event.target.errorCode
notifyResult(Cr.NS_ERROR_FAILURE);
return;
}
txn.oncomplete = function oncomplete(event) {
if (aMessageRecord.id > self.lastMessageId) {
self.lastMessageId = aMessageRecord.id;
}
notifyResult(Cr.NS_OK);
};
txn.onabort = function onabort(event) {
@ -1489,99 +1514,172 @@ MobileMessageDatabaseService.prototype = {
let messageStore = stores[0];
let participantStore = stores[1];
let threadStore = stores[2];
self.findThreadRecordByParticipants(threadStore, participantStore,
aAddresses, true,
function (threadRecord,
participantIds) {
if (!participantIds) {
notifyResult(Cr.NS_ERROR_FAILURE);
return;
}
let insertMessageRecord = function (threadId) {
// Setup threadId & threadIdIndex.
aMessageRecord.threadId = threadId;
aMessageRecord.threadIdIndex = [threadId, timestamp];
// Setup participantIdsIndex.
aMessageRecord.participantIdsIndex = [];
for each (let id in participantIds) {
aMessageRecord.participantIdsIndex.push([id, timestamp]);
}
if (!isOverriding) {
// Really add to message store.
messageStore.put(aMessageRecord);
return;
}
// If we're going to override an old message, we need to update the
// info of the original thread containing the overridden message.
// To get the original thread ID and read status of the overridden
// message record, we need to retrieve it before overriding it.
messageStore.get(aMessageRecord.id).onsuccess = function(event) {
let oldMessageRecord = event.target.result;
messageStore.put(aMessageRecord);
if (oldMessageRecord) {
self.updateThreadByMessageChange(messageStore,
threadStore,
oldMessageRecord.threadId,
aMessageRecord.id,
oldMessageRecord.read);
}
};
};
let timestamp = aMessageRecord.timestamp;
if (threadRecord) {
let needsUpdate = false;
if (threadRecord.lastTimestamp <= timestamp) {
let lastMessageSubject;
if (aMessageRecord.type == "mms") {
lastMessageSubject = aMessageRecord.headers.subject;
}
threadRecord.lastMessageSubject = lastMessageSubject || null;
threadRecord.lastTimestamp = timestamp;
threadRecord.body = aMessageRecord.body;
threadRecord.lastMessageId = aMessageRecord.id;
threadRecord.lastMessageType = aMessageRecord.type;
needsUpdate = true;
}
if (!aMessageRecord.read) {
threadRecord.unreadCount++;
needsUpdate = true;
}
if (needsUpdate) {
threadStore.put(threadRecord);
}
insertMessageRecord(threadRecord.id);
return;
}
let lastMessageSubject;
if (aMessageRecord.type == "mms") {
lastMessageSubject = aMessageRecord.headers.subject;
}
threadStore.add({participantIds: participantIds,
participantAddresses: aAddresses,
lastMessageId: aMessageRecord.id,
lastTimestamp: timestamp,
lastMessageSubject: lastMessageSubject || null,
body: aMessageRecord.body,
unreadCount: aMessageRecord.read ? 0 : 1,
lastMessageType: aMessageRecord.type})
.onsuccess = function (event) {
let threadId = event.target.result;
insertMessageRecord(threadId);
};
});
self.replaceShortMessageOnSave(txn, messageStore, participantStore,
threadStore, aMessageRecord, aAddresses);
}, [MESSAGE_STORE_NAME, PARTICIPANT_STORE_NAME, THREAD_STORE_NAME]);
// We return the key that we expect to store in the db
return aMessageRecord.id;
},
replaceShortMessageOnSave:
function replaceShortMessageOnSave(aTransaction, aMessageStore,
aParticipantStore, aThreadStore,
aMessageRecord, aAddresses) {
if (aMessageRecord.type != "sms" ||
aMessageRecord.delivery != DELIVERY_RECEIVED ||
!(aMessageRecord.pid >= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 &&
aMessageRecord.pid <= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7)) {
this.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
aThreadStore, aMessageRecord, aAddresses);
return;
}
// 3GPP TS 23.040 subclause 9.2.3.9 "TP-Protocol-Identifier (TP-PID)":
//
// ... the MS shall check the originating address and replace any
// existing stored message having the same Protocol Identifier code
// and originating address with the new short message and other
// parameter values. If there is no message to be replaced, the MS
// shall store the message in the normal way. ... it is recommended
// that the SC address should not be checked by the MS."
let self = this;
this.findParticipantRecordByAddress(aParticipantStore,
aMessageRecord.sender, false,
function(participantRecord) {
if (!participantRecord) {
self.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
aThreadStore, aMessageRecord, aAddresses);
return;
}
let participantId = participantRecord.id;
let range = IDBKeyRange.bound([participantId, 0], [participantId, ""]);
let request = aMessageStore.index("participantIds").openCursor(range);
request.onsuccess = function onsuccess(event) {
let cursor = event.target.result;
if (!cursor) {
self.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
aThreadStore, aMessageRecord, aAddresses);
return;
}
// A message record with same participantId found.
// Verify matching criteria.
let foundMessageRecord = cursor.value;
if (foundMessageRecord.type != "sms" ||
foundMessageRecord.sender != aMessageRecord.sender ||
foundMessageRecord.pid != aMessageRecord.pid) {
cursor.continue();
return;
}
// Match! Now replace that found message record with current one.
aMessageRecord.id = foundMessageRecord.id;
self.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
aThreadStore, aMessageRecord, aAddresses);
};
});
},
realSaveRecord: function realSaveRecord(aTransaction, aMessageStore,
aParticipantStore, aThreadStore,
aMessageRecord, aAddresses) {
let self = this;
this.findThreadRecordByParticipants(aThreadStore, aParticipantStore,
aAddresses, true,
function(threadRecord, participantIds) {
if (!participantIds) {
aTransaction.abort();
return;
}
let isOverriding = (aMessageRecord.id !== undefined);
if (!isOverriding) {
// |self.lastMessageId| is only updated in |txn.oncomplete|.
aMessageRecord.id = self.lastMessageId + 1;
}
let timestamp = aMessageRecord.timestamp;
let insertMessageRecord = function(threadId) {
// Setup threadId & threadIdIndex.
aMessageRecord.threadId = threadId;
aMessageRecord.threadIdIndex = [threadId, timestamp];
// Setup participantIdsIndex.
aMessageRecord.participantIdsIndex = [];
for each (let id in participantIds) {
aMessageRecord.participantIdsIndex.push([id, timestamp]);
}
if (!isOverriding) {
// Really add to message store.
aMessageStore.put(aMessageRecord);
return;
}
// If we're going to override an old message, we need to update the
// info of the original thread containing the overridden message.
// To get the original thread ID and read status of the overridden
// message record, we need to retrieve it before overriding it.
aMessageStore.get(aMessageRecord.id).onsuccess = function(event) {
let oldMessageRecord = event.target.result;
aMessageStore.put(aMessageRecord);
if (oldMessageRecord) {
self.updateThreadByMessageChange(aMessageStore,
aThreadStore,
oldMessageRecord.threadId,
aMessageRecord.id,
oldMessageRecord.read);
}
};
};
if (threadRecord) {
let needsUpdate = false;
if (threadRecord.lastTimestamp <= timestamp) {
let lastMessageSubject;
if (aMessageRecord.type == "mms") {
lastMessageSubject = aMessageRecord.headers.subject;
}
threadRecord.lastMessageSubject = lastMessageSubject || null;
threadRecord.lastTimestamp = timestamp;
threadRecord.body = aMessageRecord.body;
threadRecord.lastMessageId = aMessageRecord.id;
threadRecord.lastMessageType = aMessageRecord.type;
needsUpdate = true;
}
if (!aMessageRecord.read) {
threadRecord.unreadCount++;
needsUpdate = true;
}
if (needsUpdate) {
aThreadStore.put(threadRecord);
}
insertMessageRecord(threadRecord.id);
return;
}
let lastMessageSubject;
if (aMessageRecord.type == "mms") {
lastMessageSubject = aMessageRecord.headers.subject;
}
threadRecord = {
participantIds: participantIds,
participantAddresses: aAddresses,
lastMessageId: aMessageRecord.id,
lastTimestamp: timestamp,
lastMessageSubject: lastMessageSubject || null,
body: aMessageRecord.body,
unreadCount: aMessageRecord.read ? 0 : 1,
lastMessageType: aMessageRecord.type,
};
aThreadStore.add(threadRecord).onsuccess = function(event) {
let threadId = event.target.result;
insertMessageRecord(threadId);
};
});
},
forEachMatchedMmsDeliveryInfo:
@ -1882,6 +1980,10 @@ MobileMessageDatabaseService.prototype = {
aMessage.delivery = DELIVERY_RECEIVED;
aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
if (aMessage.pid == undefined) {
aMessage.pid = RIL.PDU_PID_DEFAULT;
}
// If |deliveryTimestamp| is not specified, use 0 as default.
if (aMessage.deliveryTimestamp == undefined) {
aMessage.deliveryTimestamp = 0;
@ -1889,7 +1991,7 @@ MobileMessageDatabaseService.prototype = {
}
aMessage.deliveryIndex = [aMessage.delivery, timestamp];
return this.saveRecord(aMessage, threadParticipants, aCallback);
this.saveRecord(aMessage, threadParticipants, aCallback);
},
saveSendingMessage: function saveSendingMessage(aMessage, aCallback) {
@ -1951,7 +2053,7 @@ MobileMessageDatabaseService.prototype = {
} else if (aMessage.type == "mms") {
addresses = aMessage.receivers;
}
return this.saveRecord(aMessage, addresses, aCallback);
this.saveRecord(aMessage, addresses, aCallback);
},
setMessageDeliveryByMessageId: function setMessageDeliveryByMessageId(

Просмотреть файл

@ -196,7 +196,7 @@ function getThreadById(aThreadId) {
return getAllThreads()
.then(function(aThreads) {
for (let thread of aThreads) {
if (thread.id == aThreadId) {
if (thread.id === aThreadId) {
return thread;
}
}
@ -267,6 +267,70 @@ function deleteAllMessages() {
return getAllMessages().then(deleteMessages);
}
let pendingEmulatorCmdCount = 0;
/* Send emulator command with safe guard.
*
* We should only call |finish()| after all emulator command transactions
* end, so here comes with the pending counter. Resolve when the emulator
* gives positive response, and reject otherwise.
*
* Forfill params:
* result -- an array of emulator response lines.
*
* Reject params:
* result -- an array of emulator response lines.
*
* @return A deferred promise.
*/
function runEmulatorCmdSafe(aCommand) {
let deferred = Promise.defer();
++pendingEmulatorCmdCount;
runEmulatorCmd(aCommand, function(aResult) {
--pendingEmulatorCmdCount;
ok(true, "Emulator response: " + JSON.stringify(aResult));
if (Array.isArray(aResult) && aResult[0] === "OK") {
deferred.resolve(aResult);
} else {
deferred.reject(aResult);
}
});
return deferred.promise;
}
/* Send simple text SMS to emulator.
*
* Forfill params:
* result -- an array of emulator response lines.
*
* Reject params:
* result -- an array of emulator response lines.
*
* @return A deferred promise.
*/
function sendTextSmsToEmulator(aFrom, aText) {
let command = "sms send " + aFrom + " " + aText;
return runEmulatorCmdSafe(command);
}
/* Send raw SMS TPDU to emulator.
*
* Forfill params:
* result -- an array of emulator response lines.
*
* Reject params:
* result -- an array of emulator response lines.
*
* @return A deferred promise.
*/
function sendRawSmsToEmulator(aPdu) {
let command = "sms pdu " + aPdu;
return runEmulatorCmdSafe(command);
}
/* Create a new array of id attribute of input messages.
*
* @param aMessages an array of {Sms,Mms}Message instances.
@ -284,11 +348,15 @@ function messagesToIds(aMessages) {
/* Flush permission settings and call |finish()|.
*/
function cleanUp() {
SpecialPowers.flushPermissions(function() {
// Use ok here so that we have at least one test run.
ok(true, "permissions flushed");
waitFor(function() {
SpecialPowers.flushPermissions(function() {
// Use ok here so that we have at least one test run.
ok(true, "permissions flushed");
finish();
finish();
});
}, function() {
return pendingEmulatorCmdCount === 0;
});
}
@ -297,5 +365,8 @@ function startTestCommon(aTestCaseMain) {
.then(deleteAllMessages)
.then(aTestCaseMain)
.then(deleteAllMessages)
.then(cleanUp, cleanUp);
.then(cleanUp, function() {
ok(false, 'promise rejects during test.');
cleanUp();
});
}

Просмотреть файл

@ -40,3 +40,4 @@ qemu = true
[test_dsds_default_service_id.js]
[test_thread_subject.js]
[test_mmdb_setmessagedeliverybyid_sms.js]
[test_replace_short_message_type.js]

Просмотреть файл

@ -0,0 +1,121 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const PDU_SMSC_NONE = "00"; // no SMSC Address
const PDU_FIRST_OCTET = "00"; // RP:no, UDHI:no, SRI:no, MMS:no, MTI:SMS-DELIVER
const PDU_SENDER_0 = "0A912143658709"; // +1234567890
const PDU_SENDER_1 = "0A912143658719"; // +1234567891
const SENDER_0 = "+1234567890";
const SENDER_1 = "+1234567891";
const PDU_PID_NORMAL = "00";
const PDU_PIDS = ["00", "41", "42", "43", "44", "45", "46", "47"];
const PDU_DCS_NORMAL = "00";
const PDU_TIMESTAMP = "00101000000000"; // 2000/01/01
const PDU_UDL = "01";
const PDU_UD_A = "41"; // "A"
const PDU_UD_B = "42"; // "B"
const BODY_A = "A";
const BODY_B = "B";
function buildPdu(aSender, aPid, aBody) {
return PDU_SMSC_NONE + PDU_FIRST_OCTET + aSender + aPid + PDU_DCS_NORMAL +
PDU_TIMESTAMP + PDU_UDL + aBody;
}
let receivedMessage;
function consumeReceivedMessage() {
let message = receivedMessage;
receivedMessage = null;
return message;
}
function waitForIncomingMessage() {
if (receivedMessage) {
return consumeReceivedMessage();
}
let deferred = Promise.defer();
waitFor(function() {
deferred.resolve(consumeReceivedMessage());
}, function() {
return receivedMessage != null;
});
return deferred.promise;
}
function sendRawSmsAndWait(aPdu) {
sendRawSmsToEmulator(aPdu);
return waitForIncomingMessage();
}
function verifyReplacing(aVictim, aSender, aPid, aCompare) {
let readableSender = aSender === PDU_SENDER_0 ? SENDER_0 : SENDER_1;
log(" Checking ('" + readableSender + "', '" + aPid + "', '" + BODY_B + "')");
let pdu = buildPdu(aSender, aPid, PDU_UD_B);
ok(true, "Sending " + pdu);
return sendRawSmsAndWait(pdu)
.then(function(aReceivedMessage) {
is(aReceivedMessage.sender, readableSender, "SmsMessage sender");
is(aReceivedMessage.body, BODY_B, "SmsMessage body");
aCompare(aReceivedMessage.id, aVictim.id, "SmsMessage id");
});
}
function verifyNotReplaced(aVictim, aSender, aPid) {
return verifyReplacing(aVictim, aSender, aPid, isnot);
}
function verifyReplaced(aVictim, aSender, aPid) {
return verifyReplacing(aVictim, aSender, aPid, is);
}
function testPid(aPid) {
log("Test message PID '" + aPid + "'");
return sendRawSmsAndWait(buildPdu(PDU_SENDER_0, aPid, PDU_UD_A))
.then(function(aReceivedMessage) {
let promise = Promise.resolve();
for (let pid of PDU_PIDS) {
let verify = (aPid !== PDU_PID_NORMAL && pid === aPid)
? verifyReplaced : verifyNotReplaced;
promise =
promise.then(verify.bind(null, aReceivedMessage, PDU_SENDER_0, pid))
.then(verifyNotReplaced.bind(null, aReceivedMessage,
PDU_SENDER_1, pid));
}
return promise;
});
}
startTestCommon(function testCaseMain() {
manager.onreceived = function(event) {
receivedMessage = event.message;
};
let promise = Promise.resolve();
for (let pid of PDU_PIDS) {
promise = promise.then(testPid.bind(null, pid))
.then(deleteAllMessages);
}
// Clear |manager.onreceived| handler.
return promise.then(function() {
manager.onreceived = null;
});
});

Просмотреть файл

@ -1935,7 +1935,7 @@ RadioInterface.prototype = {
// At this point we could send a message to content to notify the user
// that storing an incoming SMS failed, most likely due to a full disk.
if (DEBUG) {
this.debug("Could not store SMS " + message.id + ", error code " + rv);
this.debug("Could not store SMS, error code " + rv);
}
return;
}
@ -1945,8 +1945,8 @@ RadioInterface.prototype = {
}.bind(this);
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
notifyReceived);
gMobileMessageDatabaseService.saveReceivedMessage(message,
notifyReceived);
} else {
message.id = -1;
message.threadId = 0;
@ -3146,8 +3146,8 @@ RadioInterface.prototype = {
return;
}
let id = gMobileMessageDatabaseService.saveSendingMessage(
sendingMessage, notifyResult);
gMobileMessageDatabaseService.saveSendingMessage(sendingMessage,
notifyResult);
},
registerDataCallCallback: function registerDataCallCallback(callback) {

Просмотреть файл

@ -584,6 +584,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mDevPixelsPerCSSPixel);
WriteParam(aMsg, aParam.mMayHaveTouchListeners);
WriteParam(aMsg, aParam.mPresShellId);
WriteParam(aMsg, aParam.mIsRoot);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
@ -600,7 +601,8 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mZoom) &&
ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) &&
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners) &&
ReadParam(aMsg, aIter, &aResult->mPresShellId));
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mIsRoot));
}
};

Просмотреть файл

@ -36,7 +36,6 @@ public:
// We use IDs to identify frames across processes.
typedef uint64_t ViewID;
static const ViewID NULL_SCROLL_ID; // This container layer does not scroll.
static const ViewID ROOT_SCROLL_ID; // This is the root scroll frame.
static const ViewID START_SCROLL_ID; // This is the ID that scrolling subframes
// will begin at.
@ -54,6 +53,7 @@ public:
, mDevPixelsPerCSSPixel(1)
, mMayHaveTouchListeners(false)
, mPresShellId(-1)
, mIsRoot(false)
{}
// Default copy ctor and operator= are fine
@ -71,7 +71,8 @@ public:
mCumulativeResolution == aOther.mCumulativeResolution &&
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
mMayHaveTouchListeners == aOther.mMayHaveTouchListeners &&
mPresShellId == aOther.mPresShellId;
mPresShellId == aOther.mPresShellId &&
mIsRoot == aOther.mIsRoot;
}
bool operator!=(const FrameMetrics& aOther) const
{
@ -88,7 +89,7 @@ public:
bool IsRootScrollable() const
{
return mScrollId == ROOT_SCROLL_ID;
return mIsRoot;
}
bool IsScrollable() const
@ -206,8 +207,7 @@ public:
// not any parents, regardless of parent transforms.
CSSPoint mScrollOffset;
// A unique ID assigned to each scrollable frame (unless this is
// ROOT_SCROLL_ID, in which case it is not unique).
// A unique ID assigned to each scrollable frame.
ViewID mScrollId;
// The scrollable bounds of a frame. This is determined by reflow.
@ -253,6 +253,9 @@ public:
bool mMayHaveTouchListeners;
uint32_t mPresShellId;
// Whether or not this is the root scroll frame for the root content document.
bool mIsRoot;
};
/**
@ -293,16 +296,6 @@ struct ScrollableLayerGuid {
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId)
: mLayersId(aLayersId)
, mPresShellId(0)
, mScrollId(FrameMetrics::ROOT_SCROLL_ID)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
// TODO: get rid of this constructor once all callers know their
// presShellId and scrollId
}
~ScrollableLayerGuid()
{
MOZ_COUNT_DTOR(ScrollableLayerGuid);

Просмотреть файл

@ -37,8 +37,7 @@ using namespace mozilla::gfx;
typedef FrameMetrics::ViewID ViewID;
const ViewID FrameMetrics::NULL_SCROLL_ID = 0;
const ViewID FrameMetrics::ROOT_SCROLL_ID = 1;
const ViewID FrameMetrics::START_SCROLL_ID = 2;
const ViewID FrameMetrics::START_SCROLL_ID = 1;
uint8_t gLayerManagerLayerBuilder;

Просмотреть файл

@ -1527,19 +1527,19 @@ void AsyncPanZoomController::SendAsyncScrollEvent() {
return;
}
FrameMetrics::ViewID scrollId;
bool isRoot;
CSSRect contentRect;
CSSSize scrollableSize;
{
ReentrantMonitorAutoEnter lock(mMonitor);
scrollId = mFrameMetrics.mScrollId;
isRoot = mFrameMetrics.mIsRoot;
scrollableSize = mFrameMetrics.mScrollableRect.Size();
contentRect = mFrameMetrics.CalculateCompositedRectInCssPixels();
contentRect.MoveTo(mCurrentAsyncScrollOffset);
}
controller->SendAsyncScrollDOMEvent(scrollId, contentRect, scrollableSize);
controller->SendAsyncScrollDOMEvent(isRoot, contentRect, scrollableSize);
}
void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset)

Просмотреть файл

@ -54,7 +54,7 @@ public:
* |aContentRect| is in CSS pixels, relative to the current cssPage.
* |aScrollableSize| is the current content width/height in CSS pixels.
*/
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId,
virtual void SendAsyncScrollDOMEvent(bool aIsRoot,
const CSSRect &aContentRect,
const CSSSize &aScrollableSize) = 0;

Просмотреть файл

@ -28,7 +28,7 @@ public:
MOCK_METHOD1(HandleDoubleTap, void(const CSSIntPoint&));
MOCK_METHOD1(HandleSingleTap, void(const CSSIntPoint&));
MOCK_METHOD1(HandleLongTap, void(const CSSIntPoint&));
MOCK_METHOD3(SendAsyncScrollDOMEvent, void(FrameMetrics::ViewID aScrollId, const CSSRect &aContentRect, const CSSSize &aScrollableSize));
MOCK_METHOD3(SendAsyncScrollDOMEvent, void(bool aIsRoot, const CSSRect &aContentRect, const CSSSize &aScrollableSize));
MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs));
};
@ -273,10 +273,10 @@ TEST(AsyncPanZoomController, ComplexTransform) {
metrics.mResolution = ParentLayerToLayerScale(2);
metrics.mZoom = CSSToScreenScale(6);
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3);
metrics.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
metrics.mScrollId = FrameMetrics::START_SCROLL_ID;
FrameMetrics childMetrics = metrics;
childMetrics.mScrollId = FrameMetrics::START_SCROLL_ID;
childMetrics.mScrollId = FrameMetrics::START_SCROLL_ID + 1;
layers[0]->AsContainerLayer()->SetFrameMetrics(metrics);
layers[1]->AsContainerLayer()->SetFrameMetrics(childMetrics);
@ -521,7 +521,7 @@ TEST(APZCTreeManager, HitTesting1) {
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
// Now we have a root APZC that will match the page
SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID);
SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
@ -530,7 +530,7 @@ TEST(APZCTreeManager, HitTesting1) {
EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15)));
// Now we have a sub APZC with a better fit
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID);
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController());
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
@ -542,7 +542,7 @@ TEST(APZCTreeManager, HitTesting1) {
// Now test hit testing when we have two scrollable layers
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1);
SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 2);
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
@ -592,9 +592,9 @@ TEST(APZCTreeManager, HitTesting2) {
layers[2]->SetBaseTransform(transform);
// Make some other layers scrollable.
SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, CSSRect(0, 0, 200, 200));
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 80, 80));
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 200, 200));
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 2, CSSRect(0, 0, 80, 80));
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);

Просмотреть файл

@ -593,6 +593,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
nsRect* aDisplayPort,
nsRect* aCriticalDisplayPort,
ViewID aScrollId,
bool aIsRoot,
const ContainerLayerParameters& aContainerParameters) {
nsPresContext* presContext = aForFrame->PresContext();
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
@ -629,6 +630,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
}
metrics.mScrollId = aScrollId;
metrics.mIsRoot = aIsRoot;
// Only the root scrollable frame for a given presShell should pick up
// the presShell's resolution. All the other frames are 1.0.
@ -1150,8 +1152,8 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
root->SetPostScale(1.0f/containerParameters.mXScale,
1.0f/containerParameters.mYScale);
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
: FrameMetrics::NULL_SCROLL_ID;
ViewID id = FrameMetrics::NULL_SCROLL_ID;
bool isRoot = presContext->IsRootContentDocument();
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsRect displayport, criticalDisplayport;
@ -1164,11 +1166,9 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
usingCriticalDisplayport =
nsLayoutUtils::GetCriticalDisplayPort(content, &criticalDisplayport);
if (id == FrameMetrics::ROOT_SCROLL_ID) {
// Record the mapping between the root scroll frame's content and
// ROOT_SCROLL_ID so that users of nsLayoutUtils::FindIDFor() and
// nsLayoutUtils::FindContentFor() don't have to special-case the root.
nsLayoutUtils::FindOrCreateIDFor(content, true);
// If this is the root content document, we want it to have a scroll id.
if (isRoot) {
id = nsLayoutUtils::FindOrCreateIDFor(content);
}
}
}
@ -1180,7 +1180,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
root, mVisibleRect, viewport,
(usingDisplayport ? &displayport : nullptr),
(usingCriticalDisplayport ? &criticalDisplayport : nullptr),
id, containerParameters);
id, isRoot, containerParameters);
if (usingDisplayport &&
!(root->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
// See bug 693938, attachment 567017
@ -3450,7 +3450,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
mVisibleRect, viewport,
(usingDisplayport ? &displayport : nullptr),
(usingCriticalDisplayport ? &criticalDisplayport : nullptr),
scrollId, aContainerParameters);
scrollId, false, aContainerParameters);
return layer.forget();
}

Просмотреть файл

@ -528,22 +528,12 @@ nsLayoutUtils::FindIDFor(const nsIContent* aContent, ViewID* aOutViewId)
}
ViewID
nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent, bool aRoot)
nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent)
{
ViewID scrollId;
if (!FindIDFor(aContent, &scrollId)) {
scrollId = aRoot ? FrameMetrics::ROOT_SCROLL_ID : sScrollIdCounter++;
if (aRoot) {
// We are possibly replacing the old ROOT_SCROLL_ID content with a new one, so
// we should clear the property on the old content if there is one. Otherwise when
// that content is destroyed it will clear its property list and clobber ROOT_SCROLL_ID.
nsIContent* oldRoot;
bool oldExists = GetContentMap().Get(scrollId, &oldRoot);
if (oldExists) {
oldRoot->DeleteProperty(nsGkAtoms::RemoteId);
}
}
scrollId = sScrollIdCounter++;
aContent->SetProperty(nsGkAtoms::RemoteId, new ViewID(scrollId),
DestroyViewID);
GetContentMap().Put(scrollId, aContent);

Просмотреть файл

@ -95,10 +95,9 @@ public:
/**
* Finds previously assigned or generates a unique ViewID for the given
* content element. If aRoot is true, the special ID
* FrameMetrics::ROOT_SCROLL_ID is used.
* content element.
*/
static ViewID FindOrCreateIDFor(nsIContent* aContent, bool aRoot = false);
static ViewID FindOrCreateIDFor(nsIContent* aContent);
/**
* Find content for given ID.

Просмотреть файл

@ -109,7 +109,7 @@ AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
"Expected frame to be in top-level chrome document");
}
// Return view for given ID in aArray, nullptr if not found.
// Return view for given ID in aMap, nullptr if not found.
static nsContentView*
FindViewForId(const ViewMap& aMap, ViewID aId)
{
@ -117,6 +117,19 @@ FindViewForId(const ViewMap& aMap, ViewID aId)
return iter != aMap.end() ? iter->second : nullptr;
}
// Return the root content view in aMap, nullptr if not found.
static nsContentView*
FindRootView(const ViewMap& aMap)
{
for (ViewMap::const_iterator iter = aMap.begin(), end = aMap.end();
iter != end;
++iter) {
if (iter->second->IsRoot())
return iter->second;
}
return nullptr;
}
static const FrameMetrics*
GetFrameMetrics(Layer* aLayer)
{
@ -403,7 +416,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
config.mScrollOffset = nsPoint(
NSIntPixelsToAppUnits(metrics.mScrollOffset.x, auPerCSSPixel) * aXScale,
NSIntPixelsToAppUnits(metrics.mScrollOffset.y, auPerCSSPixel) * aYScale);
view = new nsContentView(aFrameLoader, scrollId, config);
view = new nsContentView(aFrameLoader, scrollId, metrics.mIsRoot, config);
view->mParentScaleX = aAccConfigXScale;
view->mParentScaleY = aAccConfigYScale;
}
@ -554,7 +567,7 @@ public:
void ClearRenderFrame() { mRenderFrame = nullptr; }
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId,
virtual void SendAsyncScrollDOMEvent(bool aIsRoot,
const CSSRect& aContentRect,
const CSSSize& aContentSize) MOZ_OVERRIDE
{
@ -563,10 +576,10 @@ public:
FROM_HERE,
NewRunnableMethod(this,
&RemoteContentController::SendAsyncScrollDOMEvent,
aScrollId, aContentRect, aContentSize));
aIsRoot, aContentRect, aContentSize));
return;
}
if (mRenderFrame && aScrollId == FrameMetrics::ROOT_SCROLL_ID) {
if (mRenderFrame && aIsRoot) {
TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
BrowserElementParent::DispatchAsyncScrollEvent(browser, aContentRect,
aContentSize);
@ -627,9 +640,6 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
, mFrameLoaderDestroyed(false)
, mBackgroundColor(gfxRGBA(1, 1, 1))
{
mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID);
*aId = 0;
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
@ -640,6 +650,13 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
*aTextureFactoryIdentifier = TextureFactoryIdentifier();
}
if (lm && lm->GetRoot() && lm->GetRoot()->AsContainerLayer()) {
ViewID rootScrollId = lm->GetRoot()->AsContainerLayer()->GetFrameMetrics().mScrollId;
if (rootScrollId != FrameMetrics::NULL_SCROLL_ID) {
mContentViews[rootScrollId] = new nsContentView(aFrameLoader, rootScrollId, true);
}
}
if (CompositorParent::CompositorLoop()) {
// Our remote frame will push layers updates to the compositor,
// and we'll keep an indirect reference to that tree.
@ -695,6 +712,12 @@ RenderFrameParent::GetContentView(ViewID aId)
return FindViewForId(mContentViews, aId);
}
nsContentView*
RenderFrameParent::GetRootContentView()
{
return FindRootView(mContentViews);
}
void
RenderFrameParent::ContentViewScaleChanged(nsContentView* aView)
{
@ -805,7 +828,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
mContainer->SetClipRect(nullptr);
if (mFrameLoader->AsyncScrollEnabled()) {
const nsContentView* view = GetContentView(FrameMetrics::ROOT_SCROLL_ID);
const nsContentView* view = GetRootContentView();
BuildBackgroundPatternFor(mContainer,
shadowRoot,
view->GetViewConfig(),
@ -927,8 +950,9 @@ RenderFrameParent::BuildViewMap()
// the content view map should only contain the root view and content
// views that are present in the layer tree.
if (newContentViews.empty()) {
newContentViews[FrameMetrics::ROOT_SCROLL_ID] =
FindViewForId(mContentViews, FrameMetrics::ROOT_SCROLL_ID);
nsContentView* rootView = FindRootView(mContentViews);
if (rootView)
newContentViews[rootView->GetId()] = rootView;
}
mContentViews = newContentViews;
@ -1023,11 +1047,12 @@ RenderFrameParent::ContentReceivedTouch(const ScrollableLayerGuid& aGuid,
void
RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId,
ViewID aViewId,
bool aIsRoot,
bool aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom)
{
if (mContentController && aViewId == FrameMetrics::ROOT_SCROLL_ID) {
if (mContentController && aIsRoot) {
mContentController->SaveZoomConstraints(aAllowZoom, aMinZoom, aMaxZoom);
}
if (GetApzcTreeManager()) {

Просмотреть файл

@ -68,10 +68,11 @@ public:
void Destroy();
/**
* Helper function for getting a non-owning reference to a scrollable.
* Helper functions for getting a non-owning reference to a scrollable.
* @param aId The ID of the frame.
*/
nsContentView* GetContentView(ViewID aId = FrameMetrics::ROOT_SCROLL_ID);
nsContentView* GetContentView(ViewID aId);
nsContentView* GetRootContentView();
void ContentViewScaleChanged(nsContentView* aView);
@ -117,6 +118,7 @@ public:
void UpdateZoomConstraints(uint32_t aPresShellId,
ViewID aViewId,
bool aIsRoot,
bool aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom);

Просмотреть файл

@ -1939,7 +1939,7 @@ AndroidBridge::HandleLongTap(const CSSIntPoint& aPoint)
}
void
AndroidBridge::SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId,
AndroidBridge::SendAsyncScrollDOMEvent(bool aIsRoot,
const CSSRect& aContentRect,
const CSSSize& aScrollableSize)
{

Просмотреть файл

@ -419,7 +419,7 @@ public:
void HandleDoubleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
void HandleSingleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
void HandleLongTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
void SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId,
void SendAsyncScrollDOMEvent(bool aIsRoot,
const CSSRect& aContentRect,
const CSSSize& aScrollableSize) MOZ_OVERRIDE;
void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE;

Просмотреть файл

@ -850,7 +850,8 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_abortAnimation(JNIEnv* env, j
{
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
if (controller) {
controller->CancelAnimation(ScrollableLayerGuid(nsWindow::RootLayerTreeId()));
// TODO: Pass in correct values for presShellId and viewId.
controller->CancelAnimation(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0));
}
}
@ -918,7 +919,8 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(
{
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
if (controller) {
controller->ContentReceivedTouch(ScrollableLayerGuid(nsWindow::RootLayerTreeId()), prevented);
// TODO: Pass in correct values for presShellId and viewId.
controller->ContentReceivedTouch(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0), prevented);
}
}
@ -947,7 +949,8 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_updateScrollOffset(JNIEnv* en
{
APZCTreeManager *controller = nsWindow::GetAPZCTreeManager();
if (controller) {
controller->UpdateScrollOffset(ScrollableLayerGuid(nsWindow::RootLayerTreeId()), CSSPoint(cssX, cssY));
// TODO: Pass in correct values for presShellId and viewId.
controller->UpdateScrollOffset(ScrollableLayerGuid(nsWindow::RootLayerTreeId(), 0, 0), CSSPoint(cssX, cssY));
}
}

Просмотреть файл

@ -225,8 +225,12 @@ sendKeyEventWithMsg(uint32_t keyCode,
bool isRepeat)
{
WidgetKeyboardEvent event(true, msg, nullptr);
event.keyCode = keyCode;
event.charCode = charCode;
if (msg == NS_KEY_PRESS && charCode >= ' ') {
event.charCode = charCode;
} else {
event.keyCode = keyCode;
}
event.isChar = !!event.charCode;
event.mIsRepeat = isRepeat;
event.mKeyNameIndex = keyNameIndex;
event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;

Просмотреть файл

@ -299,7 +299,7 @@ APZController::HandleLongTap(const CSSIntPoint& aPoint)
// requests that we send a mozbrowserasyncscroll domevent. not in use.
void
APZController::SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId,
APZController::SendAsyncScrollDOMEvent(bool aIsRoot,
const CSSRect &aContentRect,
const CSSSize &aScrollableSize)
{

Просмотреть файл

@ -35,7 +35,7 @@ public:
virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint);
virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint);
virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint);
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
virtual void PostDelayedTask(Task* aTask, int aDelayMs);
virtual void HandlePanBegin();
virtual void HandlePanEnd();