mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1157064 - implementation of font-display. r=heycam,khuey (43fe566f45)
- Bug 1235186 - fix small userfont logging nit. r=m_kato (d40bead913)
- Bug 1188802 - only rebuild local webfont rules when needed. r=heycam (f74200aeb2)
- Backout unrelated code landed in dee3e26cc1c0 by mistake. (5d254b78b6)
- Bug 1236506: Add support for "-webkit-filter" as an alias for CSS property "filter". r=heycam (1e7ac6554a)
- Bug 1230426 - Remove support for -webkit-border-image longhand CSS property aliases. r=dholbert (a1a2d5e82a)
- Bug 1246101 - Restore some auto-completion for the align-/justify-* properties. r=dholbert (a33dd2e7c2)
- Bug 1195142 patch 1 - Set CSS_PROPERTY_CREATES_STACKING_CONTEXT for the opacity property. r=BenWa (e547f7b420)
- Bug 1195142 patch 2 - Add reftests for will-change creating a stacking context. r=BenWa (3bb9dc17b9)
- Bug 1195142 patch 3 - Link to correct specification URLs so the CSSWG test suite system is happy. (a8121cdcf0)
- Bug 1234966 - nsStylePosition::MaxDifference should include nsChangeHint_NeutralChange because CalcDiffrence returns it. r=heycam (aa0bf89e54)
- Bug 1244166: Don't ignore stroke/fill properties in high-contrast mode, since doing so can produce icons that are invisible or whose colors are unrelated to the user's chosen high-contrast colors. r=longsonr (6448b05118)
- Bug 1157057 - Rewrite the handling of the nsITimer object in nrappkitTimerCallback; r=ekr (7cc88409b0)
- Bug 1117984: added proxy connection state enum. r=bwc (0c643ff34a)
- Bug 1231971 - Refactor the NAT simulator to use e10s sockets when appropriate. r=drno (c0722c431b)
- Bug 1231973 - Allow NAT simulator to be enabled with the pref system. r=drno (c92ca4fefa)
- Bug 1201209 - Extend the timeout on socket readiness in test_nr_socket_unittest. r=drno (e9e5400902)
- Bug 1216815 - fix memory leaks in test TCP STUN server. r=mjf (11219f41fc)
- Bug 1194385 - Add new unit tests which demonstrate the current behavior. r=bwc (900c621491)
- crashreporte (2ac99868b6)
- Bug 1150966: Check whether |streams_| is null on stats methods in NrIceMediaStream. r=drno (130a9ac2da)
- Bug 1241690: reduce logging output for unconnected PCs. r=bwc (aa236d7184)
- Bug 1224845 - close sockets on errors and don't connect to IPv4 TURN TCP from IPv6 sockets. r=jesup (f128a67692)
- Bug 1189961 - added DNS AAAA convertion to nICEr transport addr. r=bwc (30c14fe7dd)
- Bug 1247536 - Fix -Wunreachable-code warning in media/mtransport/. r=drno (f6768f8539)
- Bug 1194259: nsresult != NS_IMETHODIMP rs=bustage (3a922e6e14)
- Bug 1237909 part 1 - Remove unused TransportLayer::RunOnThread function. r=bwc (d2d219d63a)
- Bug 1237909 part 2 - Do not return value from task for sync dispatch. r=froydnj (c5ec2aecfc)
- Bug 1245035 - Move LOCAL_INCLUDES to moz.build in media/omx-plugin/lib/ics/libvideoeditorplayer. r=mshal (54c363c9f7)
- Bug 1232069 - Check box sizes before alloc©. r=jya (86cfe660e7)
- Bug 1234778: Mark all audio frames as keyframes. r=kentuckyfriedtakahe (5e4f1b54d5)
- Bug 1231169 - report rust mp4parse track status in telemetry. r=kinetik,vladan (260d0fed99)
- Bug 1238420 - Update mp4parse-rust invocations in MP4Metadata to match CAPI changes. r=rillian (64c5d6a1ef)
- Bug 1238420 - Report mp4parse-rust errors via Telemetry. r=rillian,vladan (ff72f8dead)
- Bug 1219452 - Update script for rust mp4parser. r=kinetik (9abc268b60)
- Bug 1220754 - Update rust mp4parse import script for v0.1.3. r=kinetik (7185657598)
- Bug 1224785, Part 1 - Implement alert favicons backend. r=wchen (665c44b0cb)
- Bug 1224785, Part 2 - Show the site favicon in OS X notifications. r=mstange (814ff022ba)
- Bug 1224785, Part 3 - Don't include ShowWith{Icon}Backend on Android. r=me (fe323c2960)
- Bug 1243418 - Fix up incorrect 'aOverwrite' usage and impl in GLUploadHelpers r=jgilbert (67677b4921)
- clarify comment (88003aaf96)
- Bug 1204284: Show paper size options in OS X print dialog. r=smichaud (8bb40b4349)
- Bug 1214511 - Show copies, page range selection, and more on the expanded OSX print dialog. r=mstange (301d5cdccc)
- Bug 1216478 - prefer tooltiptext on a XUL element over title attribute on a containing toolbaritem when determining accessible name, r=surkov (ec1dfcad37)
- Bug 1248838 - ARIA owns change may fail, r=yzen (d183be3f3c)
- Bug 1222531 - turn off -Wextra-tokens on clang-cl in accessible/ directories; r=tbsaunde (6dd4dcae20)
- bug 1241453 - add DocAccessibleParent::GetXPCAccessible() r=davidb (f243398399)
- Bug 1087608 - eliminating a pref observer leak and fixing test timeout overflow that cause intermittents. r=eeejay (413354c349)
- Bug 1238368 - Re-introduce workaround for Android tap gesture. r=yzen (04bb9cea5a)
- Bug 1233863 - ARM64: Disable tests that require ion.enable = 1. r=jimb (b268c03c22)
- Bug 1191976 - Intentionally crash if we hit an IPC FatalError in the parent process. r=billm (b6e9d90d34)
- Bug 1194721: Add |DaemonRunnable8|, r=shuang (0b293cb8a5)
- Bug 1194721: Add PDU_ prefix to daemon PDU constants, r=shuang (834240b14b)
- Bug 1228546 - Implement peripheral mode support for GATT API. r=brsun, r=mrbkap (01a711cac6)
- Bug 1194721: Add helpers for Gonk sensors daemon, r=gsvelto (524d1d6792)
This commit is contained in:
@@ -815,9 +815,17 @@ Accessible::XULElmName(DocAccessible* aDocument,
|
||||
nsIContent *bindingParent = aElm->GetBindingParent();
|
||||
nsIContent* parent =
|
||||
bindingParent? bindingParent->GetParent() : aElm->GetParent();
|
||||
nsAutoString ancestorTitle;
|
||||
while (parent) {
|
||||
if (parent->IsXULElement(nsGkAtoms::toolbaritem) &&
|
||||
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
|
||||
parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, ancestorTitle)) {
|
||||
// Before returning this, check if the element itself has a tooltip:
|
||||
if (aElm->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
|
||||
aName.CompressWhitespace();
|
||||
return;
|
||||
}
|
||||
|
||||
aName.Assign(ancestorTitle);
|
||||
aName.CompressWhitespace();
|
||||
return;
|
||||
}
|
||||
@@ -2116,6 +2124,51 @@ Accessible::RemoveChild(Accessible* aChild)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Accessible::MoveChild(uint32_t aNewIndex, Accessible* aChild)
|
||||
{
|
||||
MOZ_ASSERT(aChild, "No child was given");
|
||||
MOZ_ASSERT(aChild->mParent == this, "A child from different subtree was given");
|
||||
MOZ_ASSERT(aChild->mIndexInParent != -1, "Unbound child was given");
|
||||
MOZ_ASSERT(static_cast<uint32_t>(aChild->mIndexInParent) != aNewIndex,
|
||||
"No move, same index");
|
||||
MOZ_ASSERT(aNewIndex <= mChildren.Length(), "Wrong new index was given");
|
||||
|
||||
#ifdef DEBUG
|
||||
// AutoTreeMutation should update group info.
|
||||
AssertInMutatingSubtree();
|
||||
#endif
|
||||
|
||||
mEmbeddedObjCollector = nullptr;
|
||||
mChildren.RemoveElementAt(aChild->mIndexInParent);
|
||||
|
||||
uint32_t startIdx = aNewIndex, endIdx = aChild->mIndexInParent;
|
||||
|
||||
// If the child is moved after its current position.
|
||||
if (static_cast<uint32_t>(aChild->mIndexInParent) < aNewIndex) {
|
||||
startIdx = aChild->mIndexInParent;
|
||||
|
||||
if (aNewIndex == mChildren.Length() + 1) {
|
||||
// The child is moved to the end.
|
||||
mChildren.AppendElement(aChild);
|
||||
endIdx = mChildren.Length() - 1;
|
||||
}
|
||||
else {
|
||||
mChildren.InsertElementAt(aNewIndex - 1, aChild);
|
||||
endIdx = aNewIndex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The child is moved prior its current position.
|
||||
mChildren.InsertElementAt(aNewIndex, aChild);
|
||||
}
|
||||
|
||||
for (uint32_t idx = startIdx; idx <= endIdx; idx++) {
|
||||
mChildren[idx]->mIndexInParent = idx;
|
||||
mChildren[idx]->mInt.mIndexOfEmbeddedChild = -1;
|
||||
}
|
||||
}
|
||||
|
||||
Accessible*
|
||||
Accessible::GetChildAt(uint32_t aIndex) const
|
||||
{
|
||||
|
||||
@@ -396,6 +396,11 @@ public:
|
||||
virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild);
|
||||
virtual bool RemoveChild(Accessible* aChild);
|
||||
|
||||
/**
|
||||
* Reallocates the child withing its parent.
|
||||
*/
|
||||
void MoveChild(uint32_t aNewIndex, Accessible* aChild);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible tree traverse methods
|
||||
|
||||
|
||||
@@ -2062,7 +2062,10 @@ DocAccessible::DoARIAOwnsRelocation(Accessible* aOwner)
|
||||
}
|
||||
|
||||
if (child->Parent() == aOwner) {
|
||||
MoveChild(child, insertIdx - 1);
|
||||
if (child->IsRelocated()) {
|
||||
children->RemoveElement(child);
|
||||
}
|
||||
MoveChild(child, insertIdx);
|
||||
children->InsertElementAt(arrayIdx, child);
|
||||
arrayIdx++;
|
||||
|
||||
@@ -2145,9 +2148,7 @@ DocAccessible::MoveChild(Accessible* aChild, int32_t aIdxInParent)
|
||||
reorderEvent->AddSubMutationEvent(hideEvent);
|
||||
|
||||
AutoTreeMutation mut(parent);
|
||||
parent->RemoveChild(aChild);
|
||||
|
||||
parent->InsertChildAt(aIdxInParent, aChild);
|
||||
parent->MoveChild(aIdxInParent, aChild);
|
||||
aChild->SetRelocated(true);
|
||||
|
||||
FireDelayedEvent(hideEvent);
|
||||
@@ -2178,6 +2179,7 @@ DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
|
||||
RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
|
||||
RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(child, false);
|
||||
reorderEvent->AddSubMutationEvent(hideEvent);
|
||||
FireDelayedEvent(hideEvent);
|
||||
|
||||
{
|
||||
AutoTreeMutation mut(owner);
|
||||
@@ -2185,7 +2187,6 @@ DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
|
||||
child->SetRelocated(false);
|
||||
}
|
||||
|
||||
FireDelayedEvent(hideEvent);
|
||||
MaybeNotifyOfValueChange(owner);
|
||||
FireDelayedEvent(reorderEvent);
|
||||
}
|
||||
|
||||
@@ -17,3 +17,11 @@ OS_LIBS += [
|
||||
'ole32',
|
||||
'oleaut32',
|
||||
]
|
||||
|
||||
# The Windows MIDL code generator creates things like:
|
||||
#
|
||||
# #endif !_MIDL_USE_GUIDDEF_
|
||||
#
|
||||
# which clang-cl complains about. MSVC doesn't, so turn this warning off.
|
||||
if CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += ['-Wno-extra-tokens']
|
||||
|
||||
@@ -25,3 +25,11 @@ OS_LIBS += [
|
||||
'rpcrt4',
|
||||
'oleaut32',
|
||||
]
|
||||
|
||||
# The Windows MIDL code generator creates things like:
|
||||
#
|
||||
# #endif !_MIDL_USE_GUIDDEF_
|
||||
#
|
||||
# which clang-cl complains about. MSVC doesn't, so turn this warning off.
|
||||
if CONFIG['CLANG_CL']:
|
||||
CFLAGS += ['-Wno-extra-tokens']
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "mozilla/a11y/Platform.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "xpcAccessibleDocument.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@@ -292,5 +293,13 @@ DocAccessibleParent::CheckDocTree() const
|
||||
return true;
|
||||
}
|
||||
|
||||
xpcAccessibleGeneric*
|
||||
DocAccessibleParent::GetXPCAccessible(ProxyAccessible* aProxy)
|
||||
{
|
||||
xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
|
||||
MOZ_ASSERT(doc);
|
||||
|
||||
return doc->GetXPCAccessible(aProxy);
|
||||
}
|
||||
} // a11y
|
||||
} // mozilla
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class xpcAccessibleGeneric;
|
||||
|
||||
/*
|
||||
* These objects live in the main process and comunicate with and represent
|
||||
* an accessible document in a content process.
|
||||
@@ -159,6 +161,7 @@ private:
|
||||
const nsTArray<AccessibleData>& aNewTree, uint32_t aIdx,
|
||||
uint32_t aIdxInParent);
|
||||
MOZ_WARN_UNUSED_RESULT bool CheckDocTree() const;
|
||||
xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
|
||||
|
||||
nsTArray<DocAccessibleParent*> mChildDocs;
|
||||
DocAccessibleParent* mParentDoc;
|
||||
|
||||
@@ -46,7 +46,7 @@ this.AccessFu = { // jshint ignore:line
|
||||
this._enableOrDisable();
|
||||
});
|
||||
aWindow.navigator.mozSettings.addObserver(
|
||||
SCREENREADER_SETTING, this.handleEvent.bind(this));
|
||||
SCREENREADER_SETTING, this.handleEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,12 +68,21 @@ this.AccessFu = { // jshint ignore:line
|
||||
Services.obs.removeObserver(this, 'Accessibility:Settings');
|
||||
} else if (Utils.win.navigator.mozSettings) {
|
||||
Utils.win.navigator.mozSettings.removeObserver(
|
||||
SCREENREADER_SETTING, this.handleEvent.bind(this));
|
||||
SCREENREADER_SETTING, this.handleEvent);
|
||||
}
|
||||
delete this._activatePref;
|
||||
Utils.uninit();
|
||||
},
|
||||
|
||||
/**
|
||||
* A lazy getter for event handler that binds the scope to AccessFu object.
|
||||
*/
|
||||
get handleEvent() {
|
||||
delete this.handleEvent;
|
||||
this.handleEvent = this._handleEvent.bind(this);
|
||||
return this.handleEvent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Start AccessFu mode, this primarily means controlling the virtual cursor
|
||||
* with arrow keys.
|
||||
@@ -344,7 +353,7 @@ this.AccessFu = { // jshint ignore:line
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function handleEvent(aEvent) {
|
||||
_handleEvent: function _handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case 'TabOpen':
|
||||
{
|
||||
|
||||
@@ -79,6 +79,10 @@ const MOUSE_ID = 'mouse';
|
||||
const EDGE = 0.1;
|
||||
// Multiply timeouts by this constant, x2 works great too for slower users.
|
||||
const TIMEOUT_MULTIPLIER = 1;
|
||||
// A single pointer down/up sequence periodically precedes the tripple swipe
|
||||
// gesture on Android. This delay acounts for that.
|
||||
const IS_ANDROID = Utils.MozBuildApp === 'mobile/android' &&
|
||||
Utils.AndroidSdkVersion >= 14;
|
||||
|
||||
/**
|
||||
* A point object containing distance travelled data.
|
||||
@@ -156,6 +160,14 @@ this.GestureSettings = { // jshint ignore:line
|
||||
maxConsecutiveGestureDelay:
|
||||
MAX_CONSECUTIVE_GESTURE_DELAY * TIMEOUT_MULTIPLIER,
|
||||
|
||||
/**
|
||||
* A maximum time we wait for a next pointer down event to consider a sequence
|
||||
* a multi-action gesture.
|
||||
* @type {Number}
|
||||
*/
|
||||
maxGestureResolveTimeout:
|
||||
MAX_CONSECUTIVE_GESTURE_DELAY * TIMEOUT_MULTIPLIER,
|
||||
|
||||
/**
|
||||
* Delay before tap turns into dwell
|
||||
* @type {Number}
|
||||
@@ -194,13 +206,13 @@ this.GestureTracker = { // jshint ignore:line
|
||||
* @param {Number} aTimeStamp A new pointer event timeStamp.
|
||||
* @param {Function} aGesture A gesture constructor (default: Tap).
|
||||
*/
|
||||
_init: function GestureTracker__init(aDetail, aTimeStamp, aGesture = Tap) {
|
||||
_init: function GestureTracker__init(aDetail, aTimeStamp, aGesture) {
|
||||
// Only create a new gesture on |pointerdown| event.
|
||||
if (aDetail.type !== 'pointerdown') {
|
||||
return;
|
||||
}
|
||||
let points = aDetail.points;
|
||||
let GestureConstructor = aGesture;
|
||||
let GestureConstructor = aGesture || (IS_ANDROID ? DoubleTap : Tap);
|
||||
this._create(GestureConstructor);
|
||||
this._update(aDetail, aTimeStamp);
|
||||
},
|
||||
@@ -359,7 +371,7 @@ Gesture.prototype = {
|
||||
let delay = this._getDelay(aTimeStamp);
|
||||
let handler = () => {
|
||||
Logger.gesture('timer handler');
|
||||
delete this._timer;
|
||||
this.clearTimer();
|
||||
if (!this._inProgress) {
|
||||
this._deferred.reject();
|
||||
} else if (this._rejectToOnWait) {
|
||||
@@ -502,6 +514,7 @@ Gesture.prototype = {
|
||||
}
|
||||
Logger.gesture('Resolving', this.id, 'gesture.');
|
||||
this.isComplete = true;
|
||||
this.clearTimer();
|
||||
let detail = this.compile();
|
||||
if (detail) {
|
||||
this._emit(detail);
|
||||
@@ -526,6 +539,7 @@ Gesture.prototype = {
|
||||
}
|
||||
Logger.gesture('Rejecting', this.id, 'gesture.');
|
||||
this.isComplete = true;
|
||||
this.clearTimer();
|
||||
return {
|
||||
id: this.id,
|
||||
gestureType: aRejectTo
|
||||
@@ -692,11 +706,12 @@ TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) {
|
||||
let complete = this._update(aPoints, 'pointerup', false, true);
|
||||
if (complete) {
|
||||
this.clearTimer();
|
||||
if (GestureSettings.maxConsecutiveGestureDelay) {
|
||||
if (GestureSettings.maxGestureResolveTimeout) {
|
||||
this._pointerUpTimer = setTimeout(() => {
|
||||
clearTimeout(this._pointerUpTimer);
|
||||
delete this._pointerUpTimer;
|
||||
this._deferred.resolve();
|
||||
}, GestureSettings.maxConsecutiveGestureDelay);
|
||||
}, GestureSettings.maxGestureResolveTimeout);
|
||||
} else {
|
||||
this._deferred.resolve();
|
||||
}
|
||||
|
||||
@@ -110,6 +110,27 @@ function isLogged(aModule)
|
||||
return gAccRetrieval.isLogged(aModule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the accessible tree into console.
|
||||
*/
|
||||
function dumpTree(aId, aMsg)
|
||||
{
|
||||
function dumpTreeIntl(acc, indent)
|
||||
{
|
||||
dump(indent + prettyName(acc) + "\n");
|
||||
|
||||
var children = acc.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children.queryElementAt(i, nsIAccessible);
|
||||
dumpTreeIntl(child, indent + " ");
|
||||
}
|
||||
}
|
||||
|
||||
dump(aMsg + "\n");
|
||||
var root = getAccessible(aId);
|
||||
dumpTreeIntl(root, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given function when document is loaded and focused. Preferable
|
||||
* to mochitests 'addLoadEvent' function -- additionally ensures state of the
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
SimpleTest, getBoundsForDOMElm, Point, Utils */
|
||||
/* exported loadJSON, eventMap */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
Cu.import('resource://gre/modules/Geometry.jsm');
|
||||
Cu.import("resource://gre/modules/accessibility/Gestures.jsm");
|
||||
|
||||
var win = getMainChromeWindow(window);
|
||||
|
||||
@@ -100,11 +98,6 @@ var eventMap = {
|
||||
touchmove: sendTouchEvent
|
||||
};
|
||||
|
||||
var originalDwellThreshold = GestureSettings.dwellThreshold;
|
||||
var originalSwipeMaxDuration = GestureSettings.swipeMaxDuration;
|
||||
var originalConsecutiveGestureDelay =
|
||||
GestureSettings.maxConsecutiveGestureDelay;
|
||||
|
||||
/**
|
||||
* Attach a listener for the mozAccessFuGesture event that tests its
|
||||
* type.
|
||||
@@ -158,9 +151,11 @@ function setTimers(aTimeStamp, aRemoveDwellThreshold, aRemoveSwipeMaxDuration) {
|
||||
GestureTracker.current.startTimer(aTimeStamp);
|
||||
}
|
||||
|
||||
function resetTimers() {
|
||||
GestureSettings.dwellThreshold = originalDwellThreshold;
|
||||
GestureSettings.swipeMaxDuration = originalSwipeMaxDuration;
|
||||
function resetTimers(aRemoveGestureResolveDelay) {
|
||||
GestureSettings.dwellThreshold = AccessFuTest.dwellThreshold;
|
||||
GestureSettings.swipeMaxDuration = AccessFuTest.swipeMaxDuration;
|
||||
GestureSettings.maxGestureResolveTimeout = aRemoveGestureResolveDelay ?
|
||||
0 : AccessFuTest.maxGestureResolveTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,10 +174,7 @@ AccessFuTest.addSequence = function AccessFuTest_addSequence(aSequence) {
|
||||
type: aEvent.type
|
||||
};
|
||||
var timeStamp = Date.now();
|
||||
resetTimers();
|
||||
GestureSettings.maxConsecutiveGestureDelay =
|
||||
aEvent.removeConsecutiveGestureDelay ?
|
||||
0 : originalConsecutiveGestureDelay;
|
||||
resetTimers(aEvent.removeGestureResolveDelay);
|
||||
GestureTracker.handle(event, timeStamp);
|
||||
setTimers(timeStamp, aEvent.removeDwellThreshold,
|
||||
aEvent.removeSwipeMaxDuration);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"events": [
|
||||
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
|
||||
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}],
|
||||
"removeConsecutiveGestureDelay": true }
|
||||
"removeGestureResolveDelay": true }
|
||||
],
|
||||
"expectedGestures": [{ "type": "tap" }]
|
||||
},
|
||||
@@ -13,7 +13,7 @@
|
||||
{"type": "pointermove",
|
||||
"points": [{"x": 1.03, "y": 1.03, "identifier": 1}]},
|
||||
{"type": "pointerup", "points": [{"x": 1.03, "y": 1.03, "identifier": 1}],
|
||||
"removeConsecutiveGestureDelay": true }
|
||||
"removeGestureResolveDelay": true }
|
||||
],
|
||||
"expectedGestures": [{ "type": "tap" }]
|
||||
},
|
||||
@@ -37,7 +37,7 @@
|
||||
"points": [{"x": 0.97, "y": 1.01, "identifier": 1}]},
|
||||
{"type": "pointerup",
|
||||
"points": [{"x": 0.97, "y": 1.01, "identifier": 1}],
|
||||
"removeConsecutiveGestureDelay": true }
|
||||
"removeGestureResolveDelay": true }
|
||||
],
|
||||
"expectedGestures": [{ "type": "doubletap" }]
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
|
||||
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
|
||||
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}],
|
||||
"removeConsecutiveGestureDelay": true }
|
||||
"removeGestureResolveDelay": true }
|
||||
],
|
||||
"expectedGestures": [{ "type": "tripletap" }]
|
||||
},
|
||||
@@ -292,7 +292,7 @@
|
||||
{"y": 1.30098, "x": 1.52602, "identifier": 0},
|
||||
{"y": 1.94093, "x": 1.02672, "identifier": 1},
|
||||
{"y": 2.67229, "x": 0.75246, "identifier": 2}], "type": "pointerup",
|
||||
"removeConsecutiveGestureDelay": false}],
|
||||
"removeGestureResolveDelay": true}],
|
||||
"expectedGestures": [{ "type": "tripletap", "fingers": 3 }]
|
||||
},
|
||||
{
|
||||
@@ -343,14 +343,8 @@
|
||||
"points": [{"identifier": 0, "x": 1.4375, "y": 2.59375},
|
||||
{"identifier": 2, "x": 2.15625, "y": 1.489583}]},
|
||||
{"type": "pointerup",
|
||||
"points": [{"identifier": 1, "x": 1.083333, "y": 3.71875}]},
|
||||
{"type": "pointermove",
|
||||
"points": [{"identifier": 0, "x": 1.427083, "y": 2.59375}]},
|
||||
{"type": "pointerup",
|
||||
"points": [{"identifier": 0, "x": 1.427083, "y": 2.59375}]},
|
||||
{"type": "pointerup",
|
||||
"points": [{"identifier": 2, "x": 2.15625, "y": 1.489583}],
|
||||
"removeConsecutiveGestureDelay": false}
|
||||
"points": [{"identifier": 1, "x": 1.083333, "y": 3.71875}],
|
||||
"removeGestureResolveDelay": true}
|
||||
],
|
||||
"expectedGestures": [{ "type": "tripletap", "fingers": 3 }]
|
||||
}
|
||||
|
||||
@@ -19,17 +19,6 @@ Components.utils.import("resource://gre/modules/accessibility/Utils.jsm");
|
||||
Components.utils.import("resource://gre/modules/accessibility/EventManager.jsm");
|
||||
Components.utils.import("resource://gre/modules/accessibility/Gestures.jsm");
|
||||
|
||||
const dwellThreshold = GestureSettings.dwellThreshold;
|
||||
const swipeMaxDuration = GestureSettings.swipeMaxDuration;
|
||||
const maxConsecutiveGestureDelay = GestureSettings.maxConsecutiveGestureDelay;
|
||||
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1001945 - sometimes
|
||||
// SimpleTest.executeSoon timeout is bigger than the timer settings in
|
||||
// GestureSettings that causes intermittents.
|
||||
GestureSettings.dwellThreshold = dwellThreshold * 10;
|
||||
GestureSettings.swipeMaxDuration = swipeMaxDuration * 10;
|
||||
GestureSettings.maxConsecutiveGestureDelay = maxConsecutiveGestureDelay * 10;
|
||||
|
||||
var AccessFuTest = {
|
||||
|
||||
addFunc: function AccessFuTest_addFunc(aFunc) {
|
||||
@@ -111,9 +100,13 @@ var AccessFuTest = {
|
||||
Logger.test = false;
|
||||
Logger.logLevel = Logger.INFO;
|
||||
// Reset Gesture Settings.
|
||||
GestureSettings.dwellThreshold = dwellThreshold;
|
||||
GestureSettings.swipeMaxDuration = swipeMaxDuration;
|
||||
GestureSettings.maxConsecutiveGestureDelay = maxConsecutiveGestureDelay;
|
||||
GestureSettings.dwellThreshold = this.dwellThreshold =
|
||||
this.originalDwellThreshold;
|
||||
GestureSettings.swipeMaxDuration = this.swipeMaxDuration =
|
||||
this.originalSwipeMaxDuration;
|
||||
GestureSettings.maxGestureResolveTimeout =
|
||||
this.maxGestureResolveTimeout =
|
||||
this.originalMaxGestureResolveTimeout;
|
||||
// Finish through idle callback to let AccessFu._disable complete.
|
||||
SimpleTest.executeSoon(function () {
|
||||
AccessFu.detach();
|
||||
@@ -160,6 +153,20 @@ var AccessFuTest = {
|
||||
['dom.mozSettings.enabled', true]];
|
||||
prefs.push.apply(prefs, aAdditionalPrefs);
|
||||
|
||||
this.originalDwellThreshold = GestureSettings.dwellThreshold;
|
||||
this.originalSwipeMaxDuration = GestureSettings.swipeMaxDuration;
|
||||
this.originalMaxGestureResolveTimeout =
|
||||
GestureSettings.maxGestureResolveTimeout;
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1001945 - sometimes
|
||||
// SimpleTest.executeSoon timeout is bigger than the timer settings in
|
||||
// GestureSettings that causes intermittents.
|
||||
this.dwellThreshold = GestureSettings.dwellThreshold =
|
||||
GestureSettings.dwellThreshold * 10;
|
||||
this.swipeMaxDuration = GestureSettings.swipeMaxDuration =
|
||||
GestureSettings.swipeMaxDuration * 10;
|
||||
this.maxGestureResolveTimeout = GestureSettings.maxGestureResolveTimeout =
|
||||
GestureSettings.maxGestureResolveTimeout * 10;
|
||||
|
||||
SpecialPowers.pushPrefEnv({ 'set': prefs }, function () {
|
||||
if (AccessFuTest._waitForExplicitFinish) {
|
||||
// Run all test functions asynchronously.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const Cu = Components.utils;
|
||||
var Cu = Components.utils;
|
||||
const PREF_UTTERANCE_ORDER = "accessibility.accessfu.utterance";
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
function stopAccessFu() {
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
|
||||
AccessFuTest.once_log("EventManager.stop", AccessFuTest.finish);
|
||||
AccessFuTest.once_log("EventManager.stop", () => AccessFuTest.finish());
|
||||
}
|
||||
|
||||
function hide(id) {
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
// Listen for initial 'EventManager.start' and disable AccessFu.
|
||||
function prefStop() {
|
||||
ok(AccessFu._enabled, "AccessFu was started via preference.");
|
||||
AccessFuTest.once_log("EventManager.stop", AccessFuTest.finish);
|
||||
AccessFuTest.once_log("EventManager.stop", () => AccessFuTest.finish());
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,4 +13,5 @@ support-files =
|
||||
[test_list.html]
|
||||
[test_markup.html]
|
||||
[test_svg.html]
|
||||
[test_toolbaritem.xul]
|
||||
[test_tree.xul]
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<?xml-stylesheet href="general.css"
|
||||
type="text/css"?>
|
||||
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessibility Name Calculating Test.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../name.js"></script>
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
var gQueue = null;
|
||||
function doTest() {
|
||||
let ids = [];
|
||||
for (let item of ["button", "textbox"]) {
|
||||
ids.push(item + "withtooltip");
|
||||
ids.push(item + "withouttooltip");
|
||||
ids.push("nested" + item + "withtooltip");
|
||||
ids.push("nested" + item + "withouttooltip");
|
||||
}
|
||||
|
||||
for (let id of ids) {
|
||||
if (id.endsWith("withtooltip")) {
|
||||
testName(id, id, id + " should have individual name from its tooltip - ");
|
||||
} else {
|
||||
testName(id, "Toolbaritem title", id + " should have toolbaritem's title for a name - ");
|
||||
}
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1216478"
|
||||
title="Items with tooltips inside items with a label should use their own tooltip as an accessible name, not the ancestor's label">
|
||||
Mozilla Bug 1216478
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<toolbox>
|
||||
<toolbar>
|
||||
<toolbaritem title="Toolbaritem title">
|
||||
<toolbarbutton id="buttonwithtooltip" tooltiptext="buttonwithtooltip"/>
|
||||
<toolbarbutton id="buttonwithouttooltip"/>
|
||||
<textbox id="textboxwithtooltip" tooltiptext="textboxwithtooltip"/>
|
||||
<textbox id="textboxwithouttooltip"/>
|
||||
<vbox>
|
||||
<toolbarbutton id="nestedbuttonwithtooltip" tooltiptext="nestedbuttonwithtooltip"/>
|
||||
<toolbarbutton id="nestedbuttonwithouttooltip"/>
|
||||
<textbox id="nestedtextboxwithtooltip" tooltiptext="nestedtextboxwithtooltip"/>
|
||||
<textbox id="nestedtextboxwithouttooltip"/>
|
||||
</vbox>
|
||||
</toolbaritem>
|
||||
</toolbar>
|
||||
</toolbox>
|
||||
|
||||
|
||||
</vbox> <!-- close tests area -->
|
||||
</hbox> <!-- close main area -->
|
||||
</window>
|
||||
@@ -23,19 +23,21 @@
|
||||
// Invokers
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function removeARIAOwns()
|
||||
function changeARIAOwns()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_checkbox")),
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_button")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("t1_button")),
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_checkbox")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("t1_checkbox")),
|
||||
new invokerChecker(EVENT_REORDER, getNode("t1_container"))
|
||||
];
|
||||
|
||||
this.invoke = function removeARIAOwns_invoke()
|
||||
this.invoke = function setARIAOwns_invoke()
|
||||
{
|
||||
// children are swapped
|
||||
// children are swapped by ARIA owns
|
||||
var tree =
|
||||
{ SECTION: [
|
||||
{ CHECKBUTTON: [
|
||||
@@ -45,6 +47,41 @@
|
||||
] };
|
||||
testAccessibleTree("t1_container", tree);
|
||||
|
||||
getNode("t1_container").
|
||||
setAttribute("aria-owns", "t1_button t1_subdiv");
|
||||
}
|
||||
|
||||
this.finalCheck = function setARIAOwns_finalCheck()
|
||||
{
|
||||
// children are swapped again, button and subdiv are appended to
|
||||
// the children.
|
||||
var tree =
|
||||
{ SECTION: [
|
||||
{ CHECKBUTTON: [ ] }, // checkbox, native order
|
||||
{ PUSHBUTTON: [ ] }, // button, rearranged by ARIA own
|
||||
{ SECTION: [ ] } // subdiv from the subtree, ARIA owned
|
||||
] };
|
||||
testAccessibleTree("t1_container", tree);
|
||||
}
|
||||
|
||||
this.getID = function setARIAOwns_getID()
|
||||
{
|
||||
return "Change @aria-owns attribute";
|
||||
}
|
||||
}
|
||||
|
||||
function removeARIAOwns()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_button")),
|
||||
new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("t1_button")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
|
||||
new invokerChecker(EVENT_REORDER, getNode("t1_container"))
|
||||
];
|
||||
|
||||
this.invoke = function removeARIAOwns_invoke()
|
||||
{
|
||||
getNode("t1_container").removeAttribute("aria-owns");
|
||||
}
|
||||
|
||||
@@ -418,6 +455,7 @@
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// test1
|
||||
gQueue.push(new changeARIAOwns());
|
||||
gQueue.push(new removeARIAOwns());
|
||||
gQueue.push(new setARIAOwns());
|
||||
gQueue.push(new addIdToARIAOwns());
|
||||
|
||||
@@ -50,4 +50,12 @@ FINAL_LIBRARY = 'xul'
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
# The Windows MIDL code generator creates things like:
|
||||
#
|
||||
# #endif !_MIDL_USE_GUIDDEF_
|
||||
#
|
||||
# which clang-cl complains about. MSVC doesn't, so turn this warning off.
|
||||
if CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += ['-Wno-extra-tokens']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
@@ -58,6 +58,14 @@ LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
]
|
||||
|
||||
# The Windows MIDL code generator creates things like:
|
||||
#
|
||||
# #endif !_MIDL_USE_GUIDDEF_
|
||||
#
|
||||
# which clang-cl complains about. MSVC doesn't, so turn this warning off.
|
||||
if CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += ['-Wno-extra-tokens']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
@@ -588,9 +588,9 @@ nsresult
|
||||
BluetoothDaemonGattModule::ClientSetAdvDataCmd(
|
||||
int aServerIf, bool aIsScanRsp, bool aIsNameIncluded,
|
||||
bool aIsTxPowerIncluded, int aMinInterval, int aMaxInterval, int aApperance,
|
||||
uint16_t aManufacturerLen, char* aManufacturerData,
|
||||
uint16_t aServiceDataLen, char* aServiceData,
|
||||
uint16_t aServiceUuidLen, char* aServiceUuid,
|
||||
const nsTArray<uint8_t>& aManufacturerData,
|
||||
const nsTArray<uint8_t>& aServiceData,
|
||||
const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothGattResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -598,6 +598,17 @@ BluetoothDaemonGattModule::ClientSetAdvDataCmd(
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_SET_ADV_DATA, 0));
|
||||
|
||||
uint16_t manufacturerDataByteLen =
|
||||
aManufacturerData.Length() * sizeof(uint8_t);
|
||||
uint16_t serviceDataByteLen = aServiceData.Length() * sizeof(uint8_t);
|
||||
uint16_t serviceUuidsByteLen =
|
||||
aServiceUuids.Length() * sizeof(BluetoothUuid::mUuid);
|
||||
uint8_t* manufacturerData =
|
||||
const_cast<uint8_t*>(aManufacturerData.Elements());
|
||||
uint8_t* serviceData = const_cast<uint8_t*>(aServiceData.Elements());
|
||||
BluetoothUuid* serviceUuids =
|
||||
const_cast<BluetoothUuid*>(aServiceUuids.Elements());
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<int, int32_t>(aServerIf),
|
||||
PackConversion<bool, uint8_t>(aIsScanRsp),
|
||||
@@ -606,10 +617,12 @@ BluetoothDaemonGattModule::ClientSetAdvDataCmd(
|
||||
PackConversion<int, int32_t>(aMinInterval),
|
||||
PackConversion<int, int32_t>(aMaxInterval),
|
||||
PackConversion<int, int32_t>(aApperance),
|
||||
aManufacturerLen, aServiceDataLen, aServiceUuidLen,
|
||||
PackArray<char>(aManufacturerData, aManufacturerLen),
|
||||
PackArray<char>(aServiceData, aServiceDataLen),
|
||||
PackArray<char>(aServiceUuid, aServiceUuidLen), *pdu);
|
||||
manufacturerDataByteLen, serviceDataByteLen, serviceUuidsByteLen,
|
||||
PackArray<uint8_t>(manufacturerData, aManufacturerData.Length()),
|
||||
PackArray<uint8_t>(serviceData, aServiceData.Length()),
|
||||
PackArray<PackReversed<BluetoothUuid>>(
|
||||
serviceUuids, aServiceUuids.Length()),
|
||||
*pdu);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -2415,17 +2428,17 @@ void
|
||||
BluetoothDaemonGattInterface::SetAdvData(
|
||||
int aServerIf, bool aIsScanRsp, bool aIsNameIncluded,
|
||||
bool aIsTxPowerIncluded, int aMinInterval, int aMaxInterval, int aApperance,
|
||||
uint16_t aManufacturerLen, char* aManufacturerData,
|
||||
uint16_t aServiceDataLen, char* aServiceData,
|
||||
uint16_t aServiceUUIDLen, char* aServiceUUID,
|
||||
const nsTArray<uint8_t>& aManufacturerData,
|
||||
const nsTArray<uint8_t>& aServiceData,
|
||||
const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothGattResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(mModule);
|
||||
|
||||
nsresult rv = mModule->ClientSetAdvDataCmd(
|
||||
aServerIf, aIsScanRsp, aIsNameIncluded, aIsTxPowerIncluded, aMinInterval,
|
||||
aMaxInterval, aApperance, aManufacturerLen, aManufacturerData,
|
||||
aServiceDataLen, aServiceData, aServiceUUIDLen, aServiceUUID, aRes);
|
||||
aMaxInterval, aApperance, aManufacturerData, aServiceData, aServiceUuids,
|
||||
aRes);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
DispatchError(aRes, rv);
|
||||
|
||||
@@ -203,12 +203,9 @@ public:
|
||||
int aMinInterval,
|
||||
int aMaxInterval,
|
||||
int aApperance,
|
||||
uint16_t aManufacturerLen,
|
||||
char* aManufacturerData,
|
||||
uint16_t aServiceDataLen,
|
||||
char* aServiceData,
|
||||
uint16_t aServiceUUIDLen,
|
||||
char* aServiceUUID,
|
||||
const nsTArray<uint8_t>& aManufacturerData,
|
||||
const nsTArray<uint8_t>& aServiceData,
|
||||
const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothGattResultHandler* aRes);
|
||||
|
||||
nsresult ClientTestCommandCmd(int aCommand,
|
||||
@@ -908,9 +905,9 @@ public:
|
||||
int aMinInterval,
|
||||
int aMaxInterval,
|
||||
int aApperance,
|
||||
uint16_t aManufacturerLen, char* aManufacturerData,
|
||||
uint16_t aServiceDataLen, char* aServiceData,
|
||||
uint16_t aServiceUuidLen, char* aServiceUuid,
|
||||
const nsTArray<uint8_t>& aManufacturerData,
|
||||
const nsTArray<uint8_t>& aServiceData,
|
||||
const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothGattResultHandler* aRes) override;
|
||||
|
||||
void TestCommand(int aCommand,
|
||||
|
||||
@@ -190,6 +190,8 @@ public:
|
||||
int mClientIf;
|
||||
int mConnId;
|
||||
RefPtr<BluetoothReplyRunnable> mStartLeScanRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mStartAdvertisingRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mStopAdvertisingRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mConnectRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mDisconnectRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mDiscoverRunnable;
|
||||
@@ -203,6 +205,8 @@ public:
|
||||
BluetoothGattClientReadDescState mReadDescriptorState;
|
||||
BluetoothGattClientWriteDescState mWriteDescriptorState;
|
||||
|
||||
BluetoothGattAdvertisingData mAdvertisingData;
|
||||
|
||||
/**
|
||||
* These temporary arrays are used only during discover operations.
|
||||
* All of them are empty if there are no ongoing discover operations.
|
||||
@@ -293,6 +297,7 @@ public:
|
||||
*/
|
||||
bool mIsRegistering;
|
||||
|
||||
RefPtr<BluetoothReplyRunnable> mRegisterServerRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mConnectPeripheralRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mDisconnectPeripheralRunnable;
|
||||
RefPtr<BluetoothReplyRunnable> mUnregisterServerRunnable;
|
||||
@@ -887,6 +892,195 @@ BluetoothGattManager::StopLeScan(const BluetoothUuid& aScanUuid,
|
||||
new StopLeScanResultHandler(aRunnable, client->mClientIf));
|
||||
}
|
||||
|
||||
class BluetoothGattManager::StartAdvertisingResultHandler final
|
||||
: public BluetoothGattResultHandler
|
||||
{
|
||||
public:
|
||||
StartAdvertisingResultHandler(BluetoothGattClient* aClient)
|
||||
: mClient(aClient)
|
||||
{
|
||||
MOZ_ASSERT(mClient);
|
||||
}
|
||||
|
||||
void Listen() override
|
||||
{
|
||||
MOZ_ASSERT(mClient->mStartAdvertisingRunnable);
|
||||
|
||||
DispatchReplySuccess(mClient->mStartAdvertisingRunnable);
|
||||
mClient->mStartAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
BT_WARNING("BluetoothGattInterface::StartLeAdvertising failed: %d",
|
||||
(int)aStatus);
|
||||
MOZ_ASSERT(mClient->mStartAdvertisingRunnable);
|
||||
|
||||
// Unregister client if startAdvertising failed
|
||||
if (mClient->mClientIf > 0) {
|
||||
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(gattManager);
|
||||
|
||||
RefPtr<BluetoothVoidReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr);
|
||||
gattManager->UnregisterClient(mClient->mClientIf, result);
|
||||
}
|
||||
|
||||
DispatchReplyError(mClient->mStartAdvertisingRunnable, aStatus);
|
||||
mClient->mStartAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<BluetoothGattClient> mClient;
|
||||
};
|
||||
|
||||
class BluetoothGattManager::SetAdvDataResultHandler final
|
||||
: public BluetoothGattResultHandler
|
||||
{
|
||||
public:
|
||||
SetAdvDataResultHandler(BluetoothGattClient* aClient)
|
||||
: mClient(aClient)
|
||||
{
|
||||
MOZ_ASSERT(mClient);
|
||||
}
|
||||
|
||||
void SetAdvData() override
|
||||
{
|
||||
sBluetoothGattInterface->Listen(
|
||||
mClient->mClientIf,
|
||||
true /* Start */,
|
||||
new StartAdvertisingResultHandler(mClient));
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
BT_WARNING("BluetoothGattInterface::StartLeAdvertising failed: %d",
|
||||
(int)aStatus);
|
||||
MOZ_ASSERT(mClient->mStartAdvertisingRunnable);
|
||||
|
||||
// Unregister client if startAdvertising failed
|
||||
if (mClient->mClientIf > 0) {
|
||||
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(gattManager);
|
||||
|
||||
RefPtr<BluetoothVoidReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr);
|
||||
gattManager->UnregisterClient(mClient->mClientIf, result);
|
||||
}
|
||||
|
||||
DispatchReplyError(mClient->mStartAdvertisingRunnable, aStatus);
|
||||
mClient->mStartAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<BluetoothGattClient> mClient;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothGattManager::StartAdvertising(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aData,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
|
||||
// Reject the startAdvertising request if the clientIf is being used.
|
||||
if (NS_WARN_IF(index != sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("start advertising failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
index = sClients->Length();
|
||||
sClients->AppendElement(new BluetoothGattClient(aAppUuid,
|
||||
BluetoothAddress::ANY));
|
||||
RefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
client->mStartAdvertisingRunnable = aRunnable;
|
||||
client->mAdvertisingData = aData;
|
||||
|
||||
// 'startAdvertising' will be proceeded after client registered
|
||||
sBluetoothGattInterface->RegisterClient(
|
||||
aAppUuid, new RegisterClientResultHandler(client));
|
||||
}
|
||||
|
||||
class BluetoothGattManager::StopAdvertisingResultHandler final
|
||||
: public BluetoothGattResultHandler
|
||||
{
|
||||
public:
|
||||
StopAdvertisingResultHandler(BluetoothGattClient* aClient)
|
||||
: mClient(aClient)
|
||||
{
|
||||
MOZ_ASSERT(mClient);
|
||||
}
|
||||
|
||||
void Listen() override
|
||||
{
|
||||
MOZ_ASSERT(mClient->mStopAdvertisingRunnable);
|
||||
|
||||
// Unregister client when stopLeScan succeeded
|
||||
if (mClient->mClientIf > 0) {
|
||||
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
|
||||
NS_ENSURE_TRUE_VOID(gattManager);
|
||||
|
||||
RefPtr<BluetoothVoidReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr);
|
||||
gattManager->UnregisterClient(mClient->mClientIf, result);
|
||||
}
|
||||
|
||||
DispatchReplySuccess(mClient->mStopAdvertisingRunnable);
|
||||
mClient->mStopAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
BT_WARNING("BluetoothGattInterface::StopAdvertising failed: %d",
|
||||
(int)aStatus);
|
||||
MOZ_ASSERT(mClient->mStopAdvertisingRunnable);
|
||||
|
||||
DispatchReplyError(mClient->mStopAdvertisingRunnable, aStatus);
|
||||
mClient->mStopAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<BluetoothGattClient> mClient;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothGattManager::StopAdvertising(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
// Reject the stop advertising request
|
||||
DispatchReplyError(aRunnable, NS_LITERAL_STRING("StopAdvertising failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
// Reject the stop advertising request if there is an ongoing one.
|
||||
if (client->mStopAdvertisingRunnable) {
|
||||
DispatchReplyError(aRunnable, STATUS_BUSY);
|
||||
return;
|
||||
}
|
||||
|
||||
client->mStopAdvertisingRunnable = aRunnable;
|
||||
sBluetoothGattInterface->Listen(
|
||||
client->mClientIf,
|
||||
false /* Stop */,
|
||||
new StopAdvertisingResultHandler(client));
|
||||
}
|
||||
|
||||
class BluetoothGattManager::ConnectResultHandler final
|
||||
: public BluetoothGattResultHandler
|
||||
{
|
||||
@@ -1642,6 +1836,12 @@ public:
|
||||
mServer->mAddServiceState.Reset();
|
||||
}
|
||||
|
||||
if (mServer->mRegisterServerRunnable) {
|
||||
DispatchReplyError(mServer->mRegisterServerRunnable,
|
||||
NS_LITERAL_STRING("Register GATT server failed"));
|
||||
mServer->mRegisterServerRunnable = nullptr;
|
||||
}
|
||||
|
||||
mServer->mIsRegistering = false;
|
||||
sServers->RemoveElement(mServer);
|
||||
}
|
||||
@@ -1650,6 +1850,48 @@ private:
|
||||
RefPtr<BluetoothGattServer> mServer;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothGattManager::RegisterServer(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sServers->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (index == sServers->NoIndex) {
|
||||
index = sServers->Length();
|
||||
sServers->AppendElement(new BluetoothGattServer(aAppUuid));
|
||||
}
|
||||
RefPtr<BluetoothGattServer> server = (*sServers)[index];
|
||||
|
||||
/**
|
||||
* There are four cases here for handling aRunnable.
|
||||
* 1) Server interface is already registered: Resolve the runnable.
|
||||
* 2) Server interface is not registered, but there is
|
||||
* an existing |RegisterServerRunnable|: Reject with STATUS_BUSY.
|
||||
* 3) Server interface is registering without an existing
|
||||
* |RegisterServerRunnable|: Save the runnable into |GattServer| and will
|
||||
* resolve or reject it in |RegisterServerNotification| later.
|
||||
* 4) Server interface is neither registered nor registering: Save the
|
||||
* the runnable into |GattServer| and trigger a registration procedure.
|
||||
* The runnable will be resolved or rejected in
|
||||
* |RegisterServerNotification| later.
|
||||
*/
|
||||
if (server->mServerIf > 0) {
|
||||
DispatchReplySuccess(aRunnable);
|
||||
} else if (server->mRegisterServerRunnable) {
|
||||
DispatchReplyError(aRunnable, STATUS_BUSY);
|
||||
} else if (server->mIsRegistering) {
|
||||
server->mRegisterServerRunnable = aRunnable;
|
||||
} else {
|
||||
server->mRegisterServerRunnable = aRunnable;
|
||||
sBluetoothGattInterface->RegisterServer(
|
||||
aAppUuid, new RegisterServerResultHandler(server));
|
||||
}
|
||||
}
|
||||
|
||||
class BluetoothGattManager::ConnectPeripheralResultHandler final
|
||||
: public BluetoothGattResultHandler
|
||||
{
|
||||
@@ -2552,7 +2794,9 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
NS_LITERAL_STRING(
|
||||
"StartLeScan failed due to registration failed"));
|
||||
client->mStartLeScanRunnable = nullptr;
|
||||
} else if (client->mConnectRunnable) {
|
||||
}
|
||||
|
||||
if (client->mConnectRunnable) {
|
||||
// Reject the connect request
|
||||
DispatchReplyError(client->mConnectRunnable,
|
||||
NS_LITERAL_STRING(
|
||||
@@ -2560,6 +2804,15 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
client->mConnectRunnable = nullptr;
|
||||
}
|
||||
|
||||
if (client->mStartAdvertisingRunnable) {
|
||||
// Reject the start advertising request
|
||||
DispatchReplyError(
|
||||
client->mStartAdvertisingRunnable,
|
||||
NS_LITERAL_STRING(
|
||||
"StartAdvertising failed due to registration failed"));
|
||||
client->mStartAdvertisingRunnable = nullptr;
|
||||
}
|
||||
|
||||
sClients->RemoveElement(client);
|
||||
return;
|
||||
}
|
||||
@@ -2577,7 +2830,9 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
sBluetoothGattInterface->Scan(
|
||||
aClientIf, true /* start */,
|
||||
new StartLeScanResultHandler(client));
|
||||
} else if (client->mConnectRunnable) {
|
||||
}
|
||||
|
||||
if (client->mConnectRunnable) {
|
||||
// Client just registered, proceed remaining connect request.
|
||||
ENSURE_GATT_INTF_IS_READY_VOID(client->mConnectRunnable);
|
||||
sBluetoothGattInterface->Connect(
|
||||
@@ -2585,6 +2840,17 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
TRANSPORT_AUTO,
|
||||
new ConnectResultHandler(client));
|
||||
}
|
||||
|
||||
if (client->mStartAdvertisingRunnable) {
|
||||
// StartAdvertising request will be proceed after SetAdvData succeeded.
|
||||
ENSURE_GATT_INTF_IS_READY_VOID(client->mStartAdvertisingRunnable);
|
||||
BluetoothGattAdvertisingData* data = &(client->mAdvertisingData);
|
||||
sBluetoothGattInterface->SetAdvData(
|
||||
aClientIf, false /* isScanRsp */, data->mIncludeDevName,
|
||||
data->mIncludeTxPower, 0 /* min interval */, 0 /* max interval */,
|
||||
data->mAppearance, data->mManufacturerData, data->mServiceData,
|
||||
data->mServiceUuids, new SetAdvDataResultHandler(client));
|
||||
}
|
||||
}
|
||||
|
||||
class BluetoothGattManager::ScanDeviceTypeResultHandler final
|
||||
@@ -3355,6 +3621,14 @@ BluetoothGattManager::RegisterServerNotification(BluetoothGattStatus aStatus,
|
||||
server->mAddServiceState.Reset();
|
||||
}
|
||||
|
||||
if (server->mRegisterServerRunnable) {
|
||||
// Reject the register server request
|
||||
DispatchReplyError(
|
||||
server->mRegisterServerRunnable,
|
||||
NS_LITERAL_STRING("Register server failed"));
|
||||
server->mRegisterServerRunnable = nullptr;
|
||||
}
|
||||
|
||||
sServers->RemoveElement(server);
|
||||
return;
|
||||
}
|
||||
@@ -3382,6 +3656,11 @@ BluetoothGattManager::RegisterServerNotification(BluetoothGattStatus aStatus,
|
||||
server->mAddServiceState.mHandleCount,
|
||||
new ServerAddServiceResultHandler(server));
|
||||
}
|
||||
|
||||
if (server->mRegisterServerRunnable) {
|
||||
DispatchReplySuccess(server->mRegisterServerRunnable);
|
||||
server->mRegisterServerRunnable = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -35,6 +35,13 @@ public:
|
||||
void StopLeScan(const BluetoothUuid& aScanUuid,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
void StartAdvertising(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aData,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
void StopAdvertising(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
void Connect(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothAddress& aDeviceAddr,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
@@ -92,6 +99,9 @@ public:
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
void RegisterServer(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
void ConnectPeripheral(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothAddress& aAddress,
|
||||
@@ -176,6 +186,9 @@ private:
|
||||
class UnregisterClientResultHandler;
|
||||
class StartLeScanResultHandler;
|
||||
class StopLeScanResultHandler;
|
||||
class StartAdvertisingResultHandler;
|
||||
class SetAdvDataResultHandler;
|
||||
class StopAdvertisingResultHandler;
|
||||
class ConnectResultHandler;
|
||||
class DisconnectResultHandler;
|
||||
class DiscoverResultHandler;
|
||||
|
||||
@@ -362,6 +362,35 @@ BluetoothServiceBluedroid::StopLeScanInternal(
|
||||
gatt->StopLeScan(aScanUuid, aRunnable);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::StartAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ENSURE_BLUETOOTH_IS_ENABLED_VOID(aRunnable);
|
||||
|
||||
BluetoothGattManager* gatt = BluetoothGattManager::Get();
|
||||
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
|
||||
|
||||
gatt->StartAdvertising(aAppUuid, aAdvData, aRunnable);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::StopAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ENSURE_BLUETOOTH_IS_ENABLED_VOID(aRunnable);
|
||||
|
||||
BluetoothGattManager* gatt = BluetoothGattManager::Get();
|
||||
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
|
||||
|
||||
gatt->StopAdvertising(aAppUuid, aRunnable);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::ConnectGattClientInternal(
|
||||
const BluetoothUuid& aAppUuid, const BluetoothAddress& aDeviceAddress,
|
||||
@@ -543,6 +572,20 @@ BluetoothServiceBluedroid::GattClientWriteDescriptorValueInternal(
|
||||
}
|
||||
|
||||
// GATT Server
|
||||
void
|
||||
BluetoothServiceBluedroid::GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid, BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ENSURE_BLUETOOTH_IS_ENABLED_VOID(aRunnable);
|
||||
|
||||
BluetoothGattManager* gatt = BluetoothGattManager::Get();
|
||||
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
|
||||
|
||||
gatt->RegisterServer(aAppUuid, aRunnable);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid, const BluetoothAddress& aAddress,
|
||||
|
||||
@@ -284,6 +284,15 @@ public:
|
||||
virtual void StopLeScanInternal(const BluetoothUuid& aScanUuid,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
|
||||
virtual void StartAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void StopAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
ConnectGattClientInternal(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothAddress& aDeviceAddress,
|
||||
@@ -354,6 +363,11 @@ public:
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
|
||||
@@ -4300,6 +4300,21 @@ BluetoothDBusService::StopLeScanInternal(
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDBusService::StartAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDBusService::StopAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDBusService::ConnectGattClientInternal(
|
||||
const BluetoothUuid& aAppUuid, const BluetoothAddress& aDeviceAddress,
|
||||
@@ -4512,6 +4527,12 @@ BluetoothDBusService::ReplyToMapMessageUpdate(long aMasId, bool aStatus,
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDBusService::GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid, BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDBusService::GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid, const BluetoothAddress& aAddress,
|
||||
|
||||
@@ -292,6 +292,15 @@ public:
|
||||
StopLeScanInternal(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
StartAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
StopAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
ConnectGattClientInternal(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothAddress& aDeviceAddress,
|
||||
@@ -362,6 +371,11 @@ public:
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
|
||||
@@ -1306,6 +1306,62 @@ enum BluetoothGapDataType {
|
||||
GAP_COMPLETE_NAME = 0X09, // Complete Local Name
|
||||
};
|
||||
|
||||
struct BluetoothGattAdvertisingData {
|
||||
/**
|
||||
* Uuid value of Appearance characteristic of the GAP service which can be
|
||||
* mapped to an icon or string that describes the physical representation of
|
||||
* the device during the device discovery procedure.
|
||||
*/
|
||||
uint16_t mAppearance;
|
||||
|
||||
/**
|
||||
* Whether to broadcast with device name or not.
|
||||
*/
|
||||
bool mIncludeDevName;
|
||||
|
||||
/**
|
||||
* Whether to broadcast with TX power or not.
|
||||
*/
|
||||
bool mIncludeTxPower;
|
||||
|
||||
/**
|
||||
* Byte array of custom manufacturer specific data.
|
||||
*
|
||||
* The first 2 octets contain the Company Identifier Code followed by
|
||||
* additional manufacturer specific data. See Core Specification Supplement
|
||||
* (CSS) v6 1.4 for more details.
|
||||
*/
|
||||
nsTArray<uint8_t> mManufacturerData;
|
||||
|
||||
/**
|
||||
* Consists of a service UUID with the data associated with that service.
|
||||
* Please see Core Specification Supplement (CSS) v6 1.11 for more details.
|
||||
*/
|
||||
nsTArray<uint8_t> mServiceData;
|
||||
|
||||
/**
|
||||
* A list of Service or Service Class UUIDs.
|
||||
* Please see Core Specification Supplement (CSS) v6 1.1 for more details.
|
||||
*/
|
||||
nsTArray<BluetoothUuid> mServiceUuids;
|
||||
|
||||
BluetoothGattAdvertisingData()
|
||||
: mAppearance(0)
|
||||
, mIncludeDevName(false)
|
||||
, mIncludeTxPower(false)
|
||||
{ }
|
||||
|
||||
bool operator==(const BluetoothGattAdvertisingData& aOther) const
|
||||
{
|
||||
return mIncludeDevName == aOther.mIncludeDevName &&
|
||||
mIncludeTxPower == aOther.mIncludeTxPower &&
|
||||
mAppearance == aOther.mAppearance &&
|
||||
mManufacturerData == aOther.mManufacturerData &&
|
||||
mServiceData == aOther.mServiceData &&
|
||||
mServiceUuids == aOther.mServiceUuids;
|
||||
}
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_bluetooth_BluetoothCommon_h
|
||||
|
||||
@@ -1028,12 +1028,9 @@ public:
|
||||
int aMinInterval,
|
||||
int aMaxInterval,
|
||||
int aApperance,
|
||||
uint16_t aManufacturerLen,
|
||||
char* aManufacturerData,
|
||||
uint16_t aServiceDataLen,
|
||||
char* aServiceData,
|
||||
uint16_t aServiceUUIDLen,
|
||||
char* aServiceUUID,
|
||||
const nsTArray<uint8_t>& aManufacturerData,
|
||||
const nsTArray<uint8_t>& aServiceData,
|
||||
const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothGattResultHandler* aRes) = 0;
|
||||
|
||||
virtual void TestCommand(int aCommand,
|
||||
|
||||
@@ -239,6 +239,18 @@ public:
|
||||
StartLeScanInternal(const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
/**
|
||||
* Start/Stop advertising.
|
||||
*/
|
||||
virtual void
|
||||
StartAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable) { }
|
||||
|
||||
virtual void
|
||||
StopAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) { }
|
||||
|
||||
/**
|
||||
* Set a property for the specified object
|
||||
*
|
||||
@@ -586,6 +598,11 @@ public:
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "BluetoothService.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/BluetoothGattCharacteristicBinding.h"
|
||||
#include "mozilla/dom/BluetoothGattServerBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
@@ -413,7 +414,55 @@ GattPropertiesToBits(const GattCharacteristicProperties& aProperties,
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
AdvertisingDataToGattAdvertisingData(
|
||||
const BluetoothAdvertisingData& aAdvData,
|
||||
BluetoothGattAdvertisingData& aGattAdvData)
|
||||
{
|
||||
aGattAdvData.mAppearance = aAdvData.mAppearance;
|
||||
aGattAdvData.mIncludeDevName = aAdvData.mIncludeDevName;
|
||||
aGattAdvData.mIncludeTxPower = aAdvData.mIncludeTxPower;
|
||||
|
||||
for (size_t i = 0; i < aAdvData.mServiceUuids.Length(); i++) {
|
||||
BluetoothUuid uuid;
|
||||
if (NS_WARN_IF(NS_FAILED(StringToUuid(aAdvData.mServiceUuids[i], uuid)))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aGattAdvData.mServiceUuids.AppendElement(uuid);
|
||||
}
|
||||
|
||||
if (!aAdvData.mManufacturerData.IsNull()) {
|
||||
// First two bytes are manufacturer ID in little-endian.
|
||||
LittleEndian::writeUint16(aGattAdvData.mManufacturerData.Elements(),
|
||||
aAdvData.mManufacturerId);
|
||||
|
||||
// Concatenate custom manufacturer data.
|
||||
const ArrayBuffer& manufacturerData = aAdvData.mManufacturerData.Value();
|
||||
manufacturerData.ComputeLengthAndData();
|
||||
aGattAdvData.mManufacturerData.AppendElements(manufacturerData.Data(),
|
||||
manufacturerData.Length());
|
||||
}
|
||||
|
||||
if (!aAdvData.mServiceData.IsNull()) {
|
||||
BluetoothUuid uuid;
|
||||
if (NS_WARN_IF(NS_FAILED(StringToUuid(aAdvData.mServiceUuid, uuid)))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
// First 16 bytes are service UUID in little-endian.
|
||||
for (size_t i = 0; i < sizeof(uuid.mUuid); i++) {
|
||||
aGattAdvData.mServiceData[i] = uuid.mUuid[sizeof(uuid.mUuid) - i - 1];
|
||||
}
|
||||
|
||||
// Concatenate custom service data.
|
||||
const ArrayBuffer& serviceData = aAdvData.mServiceData.Value();
|
||||
serviceData.ComputeLengthAndData();
|
||||
aGattAdvData.mServiceData.AppendElements(serviceData.Data(),
|
||||
serviceData.Length());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class GattPermissions;
|
||||
class GattCharacteristicProperties;
|
||||
class BluetoothAdvertisingData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +176,19 @@ void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath);
|
||||
|
||||
/**
|
||||
* Convert BluetoothAdvertisingData object used by applications to
|
||||
* BluetoothGattAdvertisingData object used by gecko backend.
|
||||
*
|
||||
* @param aAdvData [in] BluetoothAdvertisingData object.
|
||||
* @param aGattAdData [out] Target BluetoothGattAdvertisingData.
|
||||
* @return NS_OK on success, NS_ERROR_ILLEGAL_VALUE otherwise.
|
||||
*/
|
||||
nsresult
|
||||
AdvertisingDataToGattAdvertisingData(
|
||||
const BluetoothAdvertisingData& aAdvData,
|
||||
BluetoothGattAdvertisingData& aGattAdvData);
|
||||
|
||||
//
|
||||
// Register/Unregister bluetooth signal handlers
|
||||
//
|
||||
|
||||
@@ -374,6 +374,195 @@ BluetoothGattServer::Disconnect(const nsAString& aAddress, ErrorResult& aRv)
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
class BluetoothGattServer::StartAdvertisingTask final
|
||||
: public BluetoothVoidReplyRunnable
|
||||
{
|
||||
public:
|
||||
StartAdvertisingTask(BluetoothGattServer* aServer, Promise* aPromise)
|
||||
: BluetoothVoidReplyRunnable(nullptr, aPromise)
|
||||
, mServer(aServer)
|
||||
{
|
||||
MOZ_ASSERT(aServer);
|
||||
MOZ_ASSERT(aPromise);
|
||||
}
|
||||
|
||||
virtual void
|
||||
ReleaseMembers() override
|
||||
{
|
||||
BluetoothReplyRunnable::ReleaseMembers();
|
||||
mServer = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void OnErrorFired() override
|
||||
{
|
||||
mServer->mAdvertisingAppUuid.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<BluetoothGattServer> mServer;
|
||||
};
|
||||
|
||||
class BluetoothGattServer::RegisterServerAndStartAdvertisingTask final
|
||||
: public BluetoothVoidReplyRunnable
|
||||
{
|
||||
public:
|
||||
RegisterServerAndStartAdvertisingTask(
|
||||
BluetoothGattServer* aServer,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
Promise* aPromise)
|
||||
: BluetoothVoidReplyRunnable(nullptr, nullptr)
|
||||
/**
|
||||
* aPromise is not managed by BluetoothVoidReplyRunnable. It would be
|
||||
* passed to |StartAdvertisingTask| after this one executes successfully.
|
||||
*/
|
||||
, mServer(aServer)
|
||||
, mAdvData(aAdvData)
|
||||
, mPromise(aPromise)
|
||||
{
|
||||
MOZ_ASSERT(mServer);
|
||||
MOZ_ASSERT(mPromise);
|
||||
}
|
||||
|
||||
void ReleaseMembers() override
|
||||
{
|
||||
BluetoothReplyRunnable::ReleaseMembers();
|
||||
mServer = nullptr;
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void OnSuccessFired() override
|
||||
{
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (NS_WARN_IF(!bs)) {
|
||||
mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(mServer->mAdvertisingAppUuid.IsCleared())) {
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
}
|
||||
|
||||
bs->StartAdvertisingInternal(
|
||||
mServer->mAdvertisingAppUuid, mAdvData,
|
||||
new StartAdvertisingTask(mServer, mPromise));
|
||||
}
|
||||
|
||||
virtual void OnErrorFired() override
|
||||
{
|
||||
mServer->mAdvertisingAppUuid.Clear();
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
||||
RefPtr<BluetoothGattServer> mServer;
|
||||
BluetoothGattAdvertisingData mAdvData;
|
||||
RefPtr<Promise> mPromise;
|
||||
};
|
||||
|
||||
already_AddRefed<Promise>
|
||||
BluetoothGattServer::StartAdvertising(const BluetoothAdvertisingData& aAdvData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
BT_ENSURE_TRUE_REJECT(mAdvertisingAppUuid.IsCleared(),
|
||||
promise,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
|
||||
nsresult rv = GenerateUuid(mAdvertisingAppUuid);
|
||||
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv) && !mAdvertisingAppUuid.IsCleared(),
|
||||
promise,
|
||||
NS_ERROR_DOM_OPERATION_ERR);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
BluetoothGattAdvertisingData data;
|
||||
rv = AdvertisingDataToGattAdvertisingData(aAdvData, data);
|
||||
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, rv);
|
||||
|
||||
BluetoothUuid appUuid;
|
||||
rv = StringToUuid(mAppUuid, appUuid);
|
||||
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), promise, rv);
|
||||
|
||||
bs->GattServerRegisterInternal(
|
||||
appUuid,
|
||||
new RegisterServerAndStartAdvertisingTask(this, data, promise));
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
class BluetoothGattServer::StopAdvertisingTask final
|
||||
: public BluetoothVoidReplyRunnable
|
||||
{
|
||||
public:
|
||||
StopAdvertisingTask(BluetoothGattServer* aServer, Promise* aPromise)
|
||||
: BluetoothVoidReplyRunnable(nullptr, aPromise)
|
||||
, mServer(aServer)
|
||||
{
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(aServer);
|
||||
}
|
||||
|
||||
virtual void
|
||||
ReleaseMembers() override
|
||||
{
|
||||
BluetoothReplyRunnable::ReleaseMembers();
|
||||
mServer = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void OnSuccessFired() override
|
||||
{
|
||||
mServer->mAdvertisingAppUuid.Clear();
|
||||
}
|
||||
|
||||
virtual void OnErrorFired() override
|
||||
{
|
||||
mServer->mAdvertisingAppUuid.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<BluetoothGattServer> mServer;
|
||||
};
|
||||
|
||||
already_AddRefed<Promise>
|
||||
BluetoothGattServer::StopAdvertising(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
if (mAdvertisingAppUuid.IsCleared()) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
bs->StopAdvertisingInternal(mAdvertisingAppUuid,
|
||||
new StopAdvertisingTask(this, promise));
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
class BluetoothGattServer::AddIncludedServiceTask final
|
||||
: public BluetoothReplyTaskQueue::SubTask
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Promise;
|
||||
struct BluetoothAdvertisingData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +58,16 @@ public:
|
||||
const nsAString& aAddress, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> Disconnect(
|
||||
const nsAString& aAddress, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> StartAdvertising(
|
||||
const BluetoothAdvertisingData& aAdvData, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> StopAdvertising(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> AddService(BluetoothGattService& aService,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<Promise> RemoveService(BluetoothGattService& aService,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> NotifyCharacteristicChanged(
|
||||
const nsAString& aAddress,
|
||||
BluetoothGattCharacteristic& aCharacteristic,
|
||||
@@ -97,6 +104,9 @@ public:
|
||||
private:
|
||||
~BluetoothGattServer();
|
||||
|
||||
class StartAdvertisingTask;
|
||||
class RegisterServerAndStartAdvertisingTask;
|
||||
class StopAdvertisingTask;
|
||||
class AddIncludedServiceTask;
|
||||
class AddCharacteristicTask;
|
||||
class AddDescriptorTask;
|
||||
@@ -106,6 +116,9 @@ private:
|
||||
class AddServiceTask;
|
||||
class RemoveServiceTask;
|
||||
|
||||
friend class StartAdvertisingTask;
|
||||
friend class RegisterServerAndStartAdvertisingTask;
|
||||
friend class StopAdvertisingTask;
|
||||
friend class AddIncludedServiceTask;
|
||||
friend class AddCharacteristicTask;
|
||||
friend class AddDescriptorTask;
|
||||
@@ -171,6 +184,11 @@ private:
|
||||
* Map request information from the request ID.
|
||||
*/
|
||||
nsClassHashtable<nsUint32HashKey, RequestData> mRequestMap;
|
||||
|
||||
/**
|
||||
* AppUuid of the GATT client interface which is used to advertise.
|
||||
*/
|
||||
BluetoothUuid mAdvertisingAppUuid;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -323,6 +323,36 @@ struct ParamTraits<mozilla::dom::bluetooth::ControlPlayStatus>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::bluetooth::BluetoothGattAdvertisingData>
|
||||
{
|
||||
typedef mozilla::dom::bluetooth::BluetoothGattAdvertisingData paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mAppearance);
|
||||
WriteParam(aMsg, aParam.mIncludeDevName);
|
||||
WriteParam(aMsg, aParam.mIncludeTxPower);
|
||||
WriteParam(aMsg, aParam.mManufacturerData);
|
||||
WriteParam(aMsg, aParam.mServiceData);
|
||||
WriteParam(aMsg, aParam.mServiceUuids);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mAppearance)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mIncludeDevName)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mIncludeTxPower)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mManufacturerData)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mServiceData)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mServiceUuids))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_dom_bluetooth_ipc_BluetoothMessageUtils_h
|
||||
|
||||
@@ -206,6 +206,10 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
|
||||
return actor->DoRequest(aRequest.get_StartLeScanRequest());
|
||||
case Request::TStopLeScanRequest:
|
||||
return actor->DoRequest(aRequest.get_StopLeScanRequest());
|
||||
case Request::TStartAdvertisingRequest:
|
||||
return actor->DoRequest(aRequest.get_StartAdvertisingRequest());
|
||||
case Request::TStopAdvertisingRequest:
|
||||
return actor->DoRequest(aRequest.get_StopAdvertisingRequest());
|
||||
case Request::TPairRequest:
|
||||
return actor->DoRequest(aRequest.get_PairRequest());
|
||||
case Request::TUnpairRequest:
|
||||
@@ -308,6 +312,9 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
|
||||
case Request::TGattClientWriteDescriptorValueRequest:
|
||||
return actor->DoRequest(
|
||||
aRequest.get_GattClientWriteDescriptorValueRequest());
|
||||
case Request::TGattServerRegisterRequest:
|
||||
return actor->DoRequest(
|
||||
aRequest.get_GattServerRegisterRequest());
|
||||
case Request::TGattServerConnectPeripheralRequest:
|
||||
return actor->DoRequest(
|
||||
aRequest.get_GattServerConnectPeripheralRequest());
|
||||
@@ -496,6 +503,30 @@ BluetoothRequestParent::DoRequest(const StopLeScanRequest& aRequest)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const StartAdvertisingRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TStartAdvertisingRequest);
|
||||
|
||||
mService->StartAdvertisingInternal(aRequest.appUuid(),
|
||||
aRequest.data(),
|
||||
mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const StopAdvertisingRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TStopAdvertisingRequest);
|
||||
|
||||
mService->StopAdvertisingInternal(aRequest.appUuid(), mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const PairRequest& aRequest)
|
||||
{
|
||||
@@ -1119,6 +1150,18 @@ BluetoothRequestParent::DoRequest(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const GattServerRegisterRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TGattServerRegisterRequest);
|
||||
|
||||
mService->GattServerRegisterInternal(aRequest.appUuid(),
|
||||
mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(
|
||||
const GattServerConnectPeripheralRequest& aRequest)
|
||||
|
||||
@@ -152,6 +152,12 @@ protected:
|
||||
bool
|
||||
DoRequest(const StopLeScanRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const StartAdvertisingRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const StopAdvertisingRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const PairRequest& aRequest);
|
||||
|
||||
@@ -295,6 +301,9 @@ protected:
|
||||
bool
|
||||
DoRequest(const GattClientWriteDescriptorValueRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const GattServerRegisterRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const GattServerConnectPeripheralRequest& aRequest);
|
||||
|
||||
|
||||
@@ -177,6 +177,23 @@ BluetoothServiceChildProcess::StartLeScanInternal(
|
||||
SendRequest(aRunnable, StartLeScanRequest(aServiceUuids));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::StartAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable, StartAdvertisingRequest(aAppUuid, aAdvData));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::StopAdvertisingInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable, StopAdvertisingRequest(aAppUuid));
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothServiceChildProcess::SetProperty(BluetoothObjectType aType,
|
||||
const BluetoothNamedValue& aValue,
|
||||
@@ -668,6 +685,14 @@ BluetoothServiceChildProcess::GattClientWriteDescriptorValueInternal(
|
||||
aValue));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable,GattServerRegisterRequest(aAppUuid));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
|
||||
@@ -67,6 +67,15 @@ public:
|
||||
StartLeScanInternal(const nsTArray<BluetoothUuid>& aServiceUuids,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
StartAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
const BluetoothGattAdvertisingData& aAdvData,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
StopAdvertisingInternal(const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual nsresult
|
||||
SetProperty(BluetoothObjectType aType,
|
||||
const BluetoothNamedValue& aValue,
|
||||
@@ -353,6 +362,11 @@ public:
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerRegisterInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
BluetoothReplyRunnable* aRunnable) override;
|
||||
|
||||
virtual void
|
||||
GattServerConnectPeripheralInternal(
|
||||
const BluetoothUuid& aAppUuid,
|
||||
|
||||
@@ -14,6 +14,8 @@ include "mozilla/dom/bluetooth/ipc/BluetoothMessageUtils.h";
|
||||
|
||||
using mozilla::dom::bluetooth::BluetoothAddress
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothGattAdvertisingData
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothObjectType
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothPinCode
|
||||
@@ -70,6 +72,17 @@ struct StopLeScanRequest
|
||||
BluetoothUuid scanUuid;
|
||||
};
|
||||
|
||||
struct StartAdvertisingRequest
|
||||
{
|
||||
BluetoothUuid appUuid;
|
||||
BluetoothGattAdvertisingData data;
|
||||
};
|
||||
|
||||
struct StopAdvertisingRequest
|
||||
{
|
||||
BluetoothUuid appUuid;
|
||||
};
|
||||
|
||||
struct PairRequest
|
||||
{
|
||||
BluetoothAddress address;
|
||||
@@ -348,6 +361,11 @@ struct GattClientWriteDescriptorValueRequest
|
||||
uint8_t[] value;
|
||||
};
|
||||
|
||||
struct GattServerRegisterRequest
|
||||
{
|
||||
BluetoothUuid appUuid;
|
||||
};
|
||||
|
||||
struct GattServerConnectPeripheralRequest
|
||||
{
|
||||
BluetoothUuid appUuid;
|
||||
@@ -444,6 +462,8 @@ union Request
|
||||
StopDiscoveryRequest;
|
||||
StartLeScanRequest;
|
||||
StopLeScanRequest;
|
||||
StartAdvertisingRequest;
|
||||
StopAdvertisingRequest;
|
||||
PairRequest;
|
||||
UnpairRequest;
|
||||
PinReplyRequest;
|
||||
@@ -491,6 +511,7 @@ union Request
|
||||
GattClientWriteCharacteristicValueRequest;
|
||||
GattClientReadDescriptorValueRequest;
|
||||
GattClientWriteDescriptorValueRequest;
|
||||
GattServerRegisterRequest;
|
||||
GattServerConnectPeripheralRequest;
|
||||
GattServerDisconnectPeripheralRequest;
|
||||
UnregisterGattServerRequest;
|
||||
|
||||
@@ -4,6 +4,68 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
dictionary BluetoothAdvertisingData
|
||||
{
|
||||
/**
|
||||
* Uuid value of Appearance characteristic of the GAP service which can be
|
||||
* mapped to an icon or string that describes the physical representation of
|
||||
* the device during the device discovery procedure.
|
||||
*/
|
||||
unsigned short appearance = 0;
|
||||
|
||||
/**
|
||||
* Whether to broadcast with device name or not.
|
||||
*/
|
||||
boolean includeDevName = false;
|
||||
|
||||
/**
|
||||
* Whether to broadcast with TX power or not.
|
||||
*/
|
||||
boolean includeTxPower = false;
|
||||
|
||||
/**
|
||||
* Company Identifier Code for manufacturer data.
|
||||
*
|
||||
* This ID will be combined with |manufacturerData| byte array specified
|
||||
* below as the broadcasting manufacturer data. Please see Core Specification
|
||||
* Supplement (CSS) v6 1.4 for more details.
|
||||
*/
|
||||
unsigned short manufacturerId = 0;
|
||||
|
||||
/**
|
||||
* Byte array of custom manufacturer specific data.
|
||||
*
|
||||
* These bytes will be appended to |manufacturerId| specified above as the
|
||||
* broadcasting manufacturer data. Please see Core Specification Supplement
|
||||
* (CSS) v6 1.4 for more details.
|
||||
*/
|
||||
ArrayBuffer? manufacturerData = null;
|
||||
|
||||
/**
|
||||
* 128-bit Service UUID for service data.
|
||||
*
|
||||
* This UUID will be combinded with |serviceData| specified below as the
|
||||
* broadcasting service data. Please see Core Specification Supplement (CSS)
|
||||
* v6 1.11 for more details.
|
||||
*/
|
||||
DOMString serviceUuid = "";
|
||||
|
||||
/**
|
||||
* Data associated with |serviceUuid|.
|
||||
*
|
||||
* These bytes will be appended to |serviceUuid| specified above as the
|
||||
* broadcasting manufacturer data. Please see Core Specification Supplement
|
||||
* (CSS) v6 1.11 for more details.
|
||||
*/
|
||||
ArrayBuffer? serviceData = null;
|
||||
|
||||
/**
|
||||
* A list of Service or Service Class UUIDs.
|
||||
* Please see Core Specification Supplement (CSS) v6 1.1 for more details.
|
||||
*/
|
||||
sequence<DOMString> serviceUuids = [];
|
||||
};
|
||||
|
||||
[CheckAnyPermissions="bluetooth"]
|
||||
interface BluetoothGattServer : EventTarget
|
||||
{
|
||||
@@ -28,6 +90,20 @@ interface BluetoothGattServer : EventTarget
|
||||
[NewObject]
|
||||
Promise<void> disconnect(DOMString address);
|
||||
|
||||
/**
|
||||
* Start or stop advertising data to nearby devices.
|
||||
*
|
||||
* Application may customize the advertising data by passing advData to
|
||||
* |startAdvertising|. By performing |startAdvertising|, remote central
|
||||
* devices can then discover and initiate a connection with our local device.
|
||||
* A 'connectionstatechanged' event will be fired when a remote central
|
||||
* device connects to the local device.
|
||||
*/
|
||||
[NewObject]
|
||||
Promise<void> startAdvertising(optional BluetoothAdvertisingData advData);
|
||||
[NewObject]
|
||||
Promise<void> stopAdvertising();
|
||||
|
||||
/**
|
||||
* Add a BLE service to the local GATT server.
|
||||
*
|
||||
|
||||
@@ -19,6 +19,7 @@ dictionary FontFaceDescriptors {
|
||||
DOMString unicodeRange = "U+0-10FFFF";
|
||||
DOMString variant = "normal";
|
||||
DOMString featureSettings = "normal";
|
||||
DOMString display = "auto";
|
||||
};
|
||||
|
||||
enum FontFaceLoadStatus { "unloaded", "loading", "loaded", "error" };
|
||||
@@ -37,6 +38,7 @@ interface FontFace {
|
||||
[SetterThrows] attribute DOMString unicodeRange;
|
||||
[SetterThrows] attribute DOMString variant;
|
||||
[SetterThrows] attribute DOMString featureSettings;
|
||||
[SetterThrows, Pref="layout.css.font-display.enabled"] attribute DOMString display;
|
||||
|
||||
readonly attribute FontFaceLoadStatus status;
|
||||
|
||||
|
||||
@@ -173,6 +173,7 @@ BasicTextureImage::EndUpdate()
|
||||
RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface();
|
||||
|
||||
bool relative = FinishedSurfaceUpdate();
|
||||
bool needInit = mTextureState == Created;
|
||||
size_t uploadSize;
|
||||
mTextureFormat =
|
||||
UploadSurfaceToTexture(mGLContext,
|
||||
@@ -180,7 +181,7 @@ BasicTextureImage::EndUpdate()
|
||||
mUpdateRegion,
|
||||
mTexture,
|
||||
&uploadSize,
|
||||
mTextureState == Created,
|
||||
needInit,
|
||||
mUpdateOffset,
|
||||
relative);
|
||||
FinishedSurfaceUpload();
|
||||
@@ -230,13 +231,14 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
|
||||
}
|
||||
|
||||
size_t uploadSize;
|
||||
bool needInit = mTextureState == Created;
|
||||
mTextureFormat =
|
||||
UploadSurfaceToTexture(mGLContext,
|
||||
aSurf,
|
||||
region,
|
||||
mTexture,
|
||||
&uploadSize,
|
||||
mTextureState == Created,
|
||||
needInit,
|
||||
bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y),
|
||||
false);
|
||||
if (uploadSize > 0) {
|
||||
|
||||
@@ -434,12 +434,12 @@ UploadImageDataToTexture(GLContext* gl,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
size_t* aOutUploadSize,
|
||||
bool aOverwrite,
|
||||
bool aNeedInit,
|
||||
bool aPixelBuffer,
|
||||
GLenum aTextureUnit,
|
||||
GLenum aTextureTarget)
|
||||
{
|
||||
bool textureInited = aOverwrite ? false : true;
|
||||
bool textureInited = aNeedInit ? false : true;
|
||||
gl->MakeCurrent();
|
||||
gl->fActiveTexture(aTextureUnit);
|
||||
|
||||
@@ -612,7 +612,7 @@ UploadSurfaceToTexture(GLContext* gl,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
size_t* aOutUploadSize,
|
||||
bool aOverwrite,
|
||||
bool aNeedInit,
|
||||
const gfx::IntPoint& aSrcPoint,
|
||||
bool aPixelBuffer,
|
||||
GLenum aTextureUnit,
|
||||
@@ -624,7 +624,7 @@ UploadSurfaceToTexture(GLContext* gl,
|
||||
data += DataOffset(aSrcPoint, stride, format);
|
||||
return UploadImageDataToTexture(gl, data, stride, format,
|
||||
aDstRegion, aTexture, aOutUploadSize,
|
||||
aOverwrite, aPixelBuffer, aTextureUnit,
|
||||
aNeedInit, aPixelBuffer, aTextureUnit,
|
||||
aTextureTarget);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ UploadImageDataToTexture(GLContext* gl,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
size_t* aOutUploadSize = nullptr,
|
||||
bool aOverwrite = false,
|
||||
bool aNeedInit = false,
|
||||
bool aPixelBuffer = false,
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
|
||||
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
|
||||
@@ -75,7 +75,7 @@ UploadSurfaceToTexture(GLContext* gl,
|
||||
const nsIntRegion& aDstRegion,
|
||||
GLuint& aTexture,
|
||||
size_t* aOutUploadSize = nullptr,
|
||||
bool aOverwrite = false,
|
||||
bool aNeedInit = false,
|
||||
const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0),
|
||||
bool aPixelBuffer = false,
|
||||
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
|
||||
|
||||
@@ -207,6 +207,7 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion&
|
||||
region = aRegion;
|
||||
}
|
||||
|
||||
bool needInit = mTextureState == Created;
|
||||
size_t uploadSize = 0;
|
||||
mTextureFormat =
|
||||
UploadSurfaceToTexture(mGLContext,
|
||||
@@ -214,7 +215,7 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion&
|
||||
region,
|
||||
mTexture,
|
||||
&uploadSize,
|
||||
mTextureState == Created,
|
||||
needInit,
|
||||
bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y),
|
||||
false);
|
||||
if (uploadSize > 0) {
|
||||
|
||||
@@ -111,11 +111,13 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet,
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
: gfxFontEntry(NS_LITERAL_STRING("userfont")),
|
||||
mUserFontLoadState(STATUS_NOT_LOADED),
|
||||
mFontDataLoadingState(NOT_LOADING),
|
||||
mUnsupportedFormat(false),
|
||||
mFontDisplay(aFontDisplay),
|
||||
mLoader(nullptr),
|
||||
mFontSet(aFontSet)
|
||||
{
|
||||
@@ -146,7 +148,8 @@ gfxUserFontEntry::Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
{
|
||||
return mWeight == aWeight &&
|
||||
mStretch == aStretch &&
|
||||
@@ -154,6 +157,7 @@ gfxUserFontEntry::Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
mFeatureSettings == aFeatureSettings &&
|
||||
mLanguageOverride == aLanguageOverride &&
|
||||
mSrcList == aFontFaceSrcList &&
|
||||
mFontDisplay == aFontDisplay &&
|
||||
((!aUnicodeRanges && !mCharacterMap) ||
|
||||
(aUnicodeRanges && mCharacterMap && mCharacterMap->Equals(aUnicodeRanges)));
|
||||
}
|
||||
@@ -732,7 +736,8 @@ gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
||||
mLoader = nullptr;
|
||||
|
||||
// download successful, make platform font using font data
|
||||
if (NS_SUCCEEDED(aDownloadStatus)) {
|
||||
if (NS_SUCCEEDED(aDownloadStatus) &&
|
||||
mFontDataLoadingState != LOADING_TIMED_OUT) {
|
||||
bool loaded = LoadPlatformFont(aFontData, aLength);
|
||||
aFontData = nullptr;
|
||||
|
||||
@@ -744,7 +749,9 @@ gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
||||
} else {
|
||||
// download failed
|
||||
mFontSet->LogMessage(this,
|
||||
"download failed", nsIScriptError::errorFlag,
|
||||
(mFontDataLoadingState != LOADING_TIMED_OUT ?
|
||||
"download failed" : "download timed out"),
|
||||
nsIScriptError::errorFlag,
|
||||
aDownloadStatus);
|
||||
}
|
||||
|
||||
@@ -752,8 +759,10 @@ gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
|
||||
moz_free((void*)aFontData);
|
||||
}
|
||||
|
||||
// error occurred, load next src
|
||||
LoadNextSrc();
|
||||
// error occurred, load next src if load not yet timed out
|
||||
if (mFontDataLoadingState != LOADING_TIMED_OUT) {
|
||||
LoadNextSrc();
|
||||
}
|
||||
|
||||
// We ignore the status returned by LoadNext();
|
||||
// even if loading failed, we need to bump the font-set generation
|
||||
@@ -773,6 +782,7 @@ gfxUserFontEntry::GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult)
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
: mFontFamilies(4),
|
||||
mLocalRulesUsed(false),
|
||||
mRebuildLocalRules(false),
|
||||
mDownloadCount(0),
|
||||
mDownloadSize(0)
|
||||
{
|
||||
@@ -800,7 +810,8 @@ gfxUserFontSet::FindOrCreateUserFontEntry(
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
{
|
||||
RefPtr<gfxUserFontEntry> entry;
|
||||
|
||||
@@ -815,13 +826,14 @@ gfxUserFontSet::FindOrCreateUserFontEntry(
|
||||
entry = FindExistingUserFontEntry(family, aFontFaceSrcList, aWeight,
|
||||
aStretch, aStyle,
|
||||
aFeatureSettings, aLanguageOverride,
|
||||
aUnicodeRanges);
|
||||
aUnicodeRanges, aFontDisplay);
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
entry = CreateUserFontEntry(aFontFaceSrcList, aWeight, aStretch,
|
||||
aStyle, aFeatureSettings,
|
||||
aLanguageOverride, aUnicodeRanges);
|
||||
aLanguageOverride, aUnicodeRanges,
|
||||
aFontDisplay);
|
||||
entry->mFamilyName = aFamilyName;
|
||||
}
|
||||
|
||||
@@ -836,13 +848,14 @@ gfxUserFontSet::CreateUserFontEntry(
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
{
|
||||
|
||||
RefPtr<gfxUserFontEntry> userFontEntry =
|
||||
new gfxUserFontEntry(this, aFontFaceSrcList, aWeight,
|
||||
aStretch, aStyle, aFeatureSettings,
|
||||
aLanguageOverride, aUnicodeRanges);
|
||||
aLanguageOverride, aUnicodeRanges, aFontDisplay);
|
||||
return userFontEntry.forget();
|
||||
}
|
||||
|
||||
@@ -855,7 +868,8 @@ gfxUserFontSet::FindExistingUserFontEntry(
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
{
|
||||
MOZ_ASSERT(aWeight != 0,
|
||||
"aWeight must not be 0; use NS_FONT_WEIGHT_NORMAL instead");
|
||||
@@ -872,7 +886,7 @@ gfxUserFontSet::FindExistingUserFontEntry(
|
||||
if (!existingUserFontEntry->Matches(aFontFaceSrcList,
|
||||
aWeight, aStretch, aStyle,
|
||||
aFeatureSettings, aLanguageOverride,
|
||||
aUnicodeRanges)) {
|
||||
aUnicodeRanges, aFontDisplay)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -891,11 +905,12 @@ gfxUserFontSet::AddUserFontEntry(const nsAString& aFamilyName,
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %d "
|
||||
"stretch: %d",
|
||||
"stretch: %d display: %d",
|
||||
this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry,
|
||||
(aUserFontEntry->IsItalic() ? "italic" :
|
||||
(aUserFontEntry->IsOblique() ? "oblique" : "normal")),
|
||||
aUserFontEntry->Weight(), aUserFontEntry->Stretch()));
|
||||
aUserFontEntry->Weight(), aUserFontEntry->Stretch(),
|
||||
aUserFontEntry->GetFontDisplay()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -942,6 +957,7 @@ void
|
||||
gfxUserFontSet::RebuildLocalRules()
|
||||
{
|
||||
if (mLocalRulesUsed) {
|
||||
mRebuildLocalRules = true;
|
||||
DoRebuildUserFontSet();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,8 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges) = 0;
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay) = 0;
|
||||
|
||||
// creates a font face for the specified family, or returns an existing
|
||||
// matching entry on the family if there is one
|
||||
@@ -226,7 +227,8 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay);
|
||||
|
||||
// add in a font face for which we have the gfxUserFontEntry already
|
||||
void AddUserFontEntry(const nsAString& aFamilyName,
|
||||
@@ -508,7 +510,8 @@ protected:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay);
|
||||
|
||||
// creates a new gfxUserFontFamily in mFontFamilies, or returns an existing
|
||||
// family if there is one
|
||||
@@ -523,6 +526,9 @@ protected:
|
||||
// true when local names have been looked up, false otherwise
|
||||
bool mLocalRulesUsed;
|
||||
|
||||
// true when rules using local names need to be redone
|
||||
bool mRebuildLocalRules;
|
||||
|
||||
// performance stats
|
||||
uint32_t mDownloadCount;
|
||||
uint64_t mDownloadSize;
|
||||
@@ -551,7 +557,8 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay);
|
||||
|
||||
virtual ~gfxUserFontEntry();
|
||||
|
||||
@@ -562,7 +569,8 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges);
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay);
|
||||
|
||||
virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle,
|
||||
bool aNeedsBold);
|
||||
@@ -591,6 +599,8 @@ public:
|
||||
return mCharacterMap.get();
|
||||
}
|
||||
|
||||
uint8_t GetFontDisplay() const { return mFontDisplay; }
|
||||
|
||||
// load the font - starts the loading of sources which continues until
|
||||
// a valid font resource is found or all sources fail
|
||||
void Load();
|
||||
@@ -665,11 +675,13 @@ protected:
|
||||
// so keep hiding fallback font
|
||||
LOADING_SLOWLY, // timeout happened and we're not nearly done,
|
||||
// so use the fallback font
|
||||
LOADING_TIMED_OUT, // font load took too long
|
||||
LOADING_FAILED // failed to load any source: use fallback
|
||||
};
|
||||
FontDataLoadingState mFontDataLoadingState;
|
||||
|
||||
bool mUnsupportedFormat;
|
||||
uint8_t mFontDisplay; // timing of userfont fallback
|
||||
|
||||
RefPtr<gfxFontEntry> mPlatformFontEntry;
|
||||
nsTArray<gfxFontFaceSrc> mSrcList;
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GonkSensorsHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal {
|
||||
|
||||
//
|
||||
// Unpacking
|
||||
//
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsEvent& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(aPDU, aOut.mTimestamp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(aPDU, aOut.mStatus);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
switch (aOut.mType) {
|
||||
case SENSORS_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
|
||||
case SENSORS_TYPE_GYROSCOPE_UNCALIBRATED:
|
||||
/* 6 data values */
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* fall through */
|
||||
case SENSORS_TYPE_ROTATION_VECTOR:
|
||||
case SENSORS_TYPE_GAME_ROTATION_VECTOR:
|
||||
case SENSORS_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
|
||||
/* 5 data values */
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* fall through */
|
||||
case SENSORS_TYPE_ACCELEROMETER:
|
||||
case SENSORS_TYPE_GEOMAGNETIC_FIELD:
|
||||
case SENSORS_TYPE_ORIENTATION:
|
||||
case SENSORS_TYPE_GYROSCOPE:
|
||||
case SENSORS_TYPE_GRAVITY:
|
||||
case SENSORS_TYPE_LINEAR_ACCELERATION:
|
||||
/* 3 data values */
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
/* fall through */
|
||||
case SENSORS_TYPE_LIGHT:
|
||||
case SENSORS_TYPE_PRESSURE:
|
||||
case SENSORS_TYPE_TEMPERATURE:
|
||||
case SENSORS_TYPE_PROXIMITY:
|
||||
case SENSORS_TYPE_RELATIVE_HUMIDITY:
|
||||
case SENSORS_TYPE_AMBIENT_TEMPERATURE:
|
||||
case SENSORS_TYPE_HEART_RATE:
|
||||
case SENSORS_TYPE_TILT_DETECTOR:
|
||||
case SENSORS_TYPE_WAKE_GESTURE:
|
||||
case SENSORS_TYPE_GLANCE_GESTURE:
|
||||
case SENSORS_TYPE_PICK_UP_GESTURE:
|
||||
case SENSORS_TYPE_WRIST_TILT_GESTURE:
|
||||
case SENSORS_TYPE_SIGNIFICANT_MOTION:
|
||||
case SENSORS_TYPE_STEP_DETECTED:
|
||||
/* 1 data value */
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mFloat[i++]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
case SENSORS_TYPE_STEP_COUNTER:
|
||||
/* 1 data value */
|
||||
rv = UnpackPDU(aPDU, aOut.mData.mUint[0]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (MOZ_HAL_IPC_UNPACK_WARN_IF(true, SensorsEvent)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
}
|
||||
rv = UnpackPDU(aPDU, aOut.mDeliveryMode);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
} // namespace mozilla
|
||||
@@ -0,0 +1,226 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef hal_gonk_GonkSensorsHelpers_h
|
||||
#define hal_gonk_GonkSensorsHelpers_h
|
||||
|
||||
#include <mozilla/ipc/DaemonSocketPDU.h>
|
||||
#include <mozilla/ipc/DaemonSocketPDUHelpers.h>
|
||||
#include "SensorsTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal {
|
||||
|
||||
using mozilla::ipc::DaemonSocketPDU;
|
||||
using mozilla::ipc::DaemonSocketPDUHeader;
|
||||
using mozilla::ipc::DaemonSocketPDUHelpers::Convert;
|
||||
using mozilla::ipc::DaemonSocketPDUHelpers::PackPDU;
|
||||
using mozilla::ipc::DaemonSocketPDUHelpers::UnpackPDU;
|
||||
|
||||
using namespace mozilla::ipc::DaemonSocketPDUHelpers;
|
||||
|
||||
//
|
||||
// Conversion
|
||||
//
|
||||
// The functions below convert the input value to the output value's
|
||||
// type and perform extension tests on the validity of the result. On
|
||||
// success the output value will be returned in |aOut|. The functions
|
||||
// return NS_OK on success, or an XPCOM error code otherwise.
|
||||
//
|
||||
// See the documentation of the HAL IPC framework for more information
|
||||
// on conversion functions.
|
||||
//
|
||||
|
||||
nsresult
|
||||
Convert(int32_t aIn, SensorsStatus& aOut)
|
||||
{
|
||||
static const uint8_t sStatus[] = {
|
||||
[0] = SENSORS_STATUS_NO_CONTACT, // '-1'
|
||||
[1] = SENSORS_STATUS_UNRELIABLE, // '0'
|
||||
[2] = SENSORS_STATUS_ACCURACY_LOW, // '1'
|
||||
[3] = SENSORS_STATUS_ACCURACY_MEDIUM, // '2'
|
||||
[4] = SENSORS_STATUS_ACCURACY_HIGH // '3'
|
||||
};
|
||||
static const int8_t sOffset = -1; // '-1' is the lower bound of the status
|
||||
|
||||
if (MOZ_HAL_IPC_CONVERT_WARN_IF(aIn < sOffset, int32_t, SensorsStatus) ||
|
||||
MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
aIn >= (static_cast<ssize_t>(MOZ_ARRAY_LENGTH(sStatus)) + sOffset),
|
||||
int32_t, SensorsStatus)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<SensorsStatus>(sStatus[aIn - sOffset]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, SensorsDeliveryMode& aOut)
|
||||
{
|
||||
static const uint8_t sMode[] = {
|
||||
[0x00] = SENSORS_DELIVERY_MODE_BEST_EFFORT,
|
||||
[0x01] = SENSORS_DELIVERY_MODE_IMMEDIATE
|
||||
};
|
||||
if (MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
aIn >= MOZ_ARRAY_LENGTH(sMode), uint8_t, SensorsDeliveryMode)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<SensorsDeliveryMode>(sMode[aIn]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, SensorsError& aOut)
|
||||
{
|
||||
static const uint8_t sError[] = {
|
||||
[0x00] = SENSORS_ERROR_NONE,
|
||||
[0x01] = SENSORS_ERROR_FAIL,
|
||||
[0x02] = SENSORS_ERROR_NOT_READY,
|
||||
[0x03] = SENSORS_ERROR_NOMEM,
|
||||
[0x04] = SENSORS_ERROR_BUSY,
|
||||
[0x05] = SENSORS_ERROR_DONE,
|
||||
[0x06] = SENSORS_ERROR_UNSUPPORTED,
|
||||
[0x07] = SENSORS_ERROR_PARM_INVALID
|
||||
};
|
||||
if (MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
aIn >= MOZ_ARRAY_LENGTH(sError), uint8_t, SensorsError)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<SensorsError>(sError[aIn]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, SensorsTriggerMode& aOut)
|
||||
{
|
||||
static const uint8_t sMode[] = {
|
||||
[0x00] = SENSORS_TRIGGER_MODE_CONTINUOUS,
|
||||
[0x01] = SENSORS_TRIGGER_MODE_ON_CHANGE,
|
||||
[0x02] = SENSORS_TRIGGER_MODE_ONE_SHOT,
|
||||
[0x03] = SENSORS_TRIGGER_MODE_SPECIAL
|
||||
};
|
||||
if (MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
aIn >= MOZ_ARRAY_LENGTH(sMode), uint8_t, SensorsTriggerMode)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<SensorsTriggerMode>(sMode[aIn]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint32_t aIn, SensorsType& aOut)
|
||||
{
|
||||
static const uint8_t sType[] = {
|
||||
[0x00] = 0, // invalid, required by gcc
|
||||
[0x01] = SENSORS_TYPE_ACCELEROMETER,
|
||||
[0x02] = SENSORS_TYPE_GEOMAGNETIC_FIELD,
|
||||
[0x03] = SENSORS_TYPE_ORIENTATION,
|
||||
[0x04] = SENSORS_TYPE_GYROSCOPE,
|
||||
[0x05] = SENSORS_TYPE_LIGHT,
|
||||
[0x06] = SENSORS_TYPE_PRESSURE,
|
||||
[0x07] = SENSORS_TYPE_TEMPERATURE,
|
||||
[0x08] = SENSORS_TYPE_PROXIMITY,
|
||||
[0x09] = SENSORS_TYPE_GRAVITY,
|
||||
[0x0a] = SENSORS_TYPE_LINEAR_ACCELERATION,
|
||||
[0x0b] = SENSORS_TYPE_ROTATION_VECTOR,
|
||||
[0x0c] = SENSORS_TYPE_RELATIVE_HUMIDITY,
|
||||
[0x0d] = SENSORS_TYPE_AMBIENT_TEMPERATURE,
|
||||
[0x0e] = SENSORS_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
|
||||
[0x0f] = SENSORS_TYPE_GAME_ROTATION_VECTOR,
|
||||
[0x10] = SENSORS_TYPE_GYROSCOPE_UNCALIBRATED,
|
||||
[0x11] = SENSORS_TYPE_SIGNIFICANT_MOTION,
|
||||
[0x12] = SENSORS_TYPE_STEP_DETECTED,
|
||||
[0x13] = SENSORS_TYPE_STEP_COUNTER,
|
||||
[0x14] = SENSORS_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
|
||||
[0x15] = SENSORS_TYPE_HEART_RATE,
|
||||
[0x16] = SENSORS_TYPE_TILT_DETECTOR,
|
||||
[0x17] = SENSORS_TYPE_WAKE_GESTURE,
|
||||
[0x18] = SENSORS_TYPE_GLANCE_GESTURE,
|
||||
[0x19] = SENSORS_TYPE_PICK_UP_GESTURE,
|
||||
[0x1a] = SENSORS_TYPE_WRIST_TILT_GESTURE
|
||||
};
|
||||
if (MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
!aIn, uint32_t, SensorsType) ||
|
||||
MOZ_HAL_IPC_CONVERT_WARN_IF(
|
||||
aIn >= MOZ_ARRAY_LENGTH(sType), uint32_t, SensorsType)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<SensorsType>(sType[aIn]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(nsresult aIn, SensorsError& aOut)
|
||||
{
|
||||
if (NS_SUCCEEDED(aIn)) {
|
||||
aOut = SENSORS_ERROR_NONE;
|
||||
} else if (aIn == NS_ERROR_OUT_OF_MEMORY) {
|
||||
aOut = SENSORS_ERROR_NOMEM;
|
||||
} else if (aIn == NS_ERROR_ILLEGAL_VALUE) {
|
||||
aOut = SENSORS_ERROR_PARM_INVALID;
|
||||
} else {
|
||||
aOut = SENSORS_ERROR_FAIL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Packing
|
||||
//
|
||||
// Pack functions store a value in PDU. See the documentation of the
|
||||
// HAL IPC framework for more information.
|
||||
//
|
||||
// There are currently no sensor-specific pack functions necessary. If
|
||||
// you add one, put it below.
|
||||
//
|
||||
|
||||
//
|
||||
// Unpacking
|
||||
//
|
||||
// Unpack function retrieve a value from a PDU. The functions return
|
||||
// NS_OK on success, or an XPCOM error code otherwise. On sucess, the
|
||||
// returned value is stored in the second argument |aOut|.
|
||||
//
|
||||
// See the documentation of the HAL IPC framework for more information
|
||||
// on unpack functions.
|
||||
//
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsDeliveryMode& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, SensorsDeliveryMode>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsError& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, SensorsError>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsEvent& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsStatus& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<int32_t, SensorsStatus>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsTriggerMode& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, SensorsTriggerMode>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, SensorsType& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint32_t, SensorsType>(aOut));
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // hal_gonk_GonkSensorsHelpers_h
|
||||
@@ -0,0 +1,140 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef hal_gonk_SensorsTypes_h
|
||||
#define hal_gonk_SensorsTypes_h
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal {
|
||||
|
||||
enum SensorsDeliveryMode {
|
||||
SENSORS_DELIVERY_MODE_BEST_EFFORT,
|
||||
SENSORS_DELIVERY_MODE_IMMEDIATE
|
||||
};
|
||||
|
||||
enum SensorsError {
|
||||
SENSORS_ERROR_NONE,
|
||||
SENSORS_ERROR_FAIL,
|
||||
SENSORS_ERROR_NOT_READY,
|
||||
SENSORS_ERROR_NOMEM,
|
||||
SENSORS_ERROR_BUSY,
|
||||
SENSORS_ERROR_DONE,
|
||||
SENSORS_ERROR_UNSUPPORTED,
|
||||
SENSORS_ERROR_PARM_INVALID
|
||||
};
|
||||
|
||||
enum SensorsStatus {
|
||||
SENSORS_STATUS_NO_CONTACT,
|
||||
SENSORS_STATUS_UNRELIABLE,
|
||||
SENSORS_STATUS_ACCURACY_LOW,
|
||||
SENSORS_STATUS_ACCURACY_MEDIUM,
|
||||
SENSORS_STATUS_ACCURACY_HIGH
|
||||
};
|
||||
|
||||
enum SensorsTriggerMode {
|
||||
SENSORS_TRIGGER_MODE_CONTINUOUS,
|
||||
SENSORS_TRIGGER_MODE_ON_CHANGE,
|
||||
SENSORS_TRIGGER_MODE_ONE_SHOT,
|
||||
SENSORS_TRIGGER_MODE_SPECIAL
|
||||
};
|
||||
|
||||
enum SensorsType {
|
||||
SENSORS_TYPE_ACCELEROMETER,
|
||||
SENSORS_TYPE_GEOMAGNETIC_FIELD,
|
||||
SENSORS_TYPE_ORIENTATION,
|
||||
SENSORS_TYPE_GYROSCOPE,
|
||||
SENSORS_TYPE_LIGHT,
|
||||
SENSORS_TYPE_PRESSURE,
|
||||
SENSORS_TYPE_TEMPERATURE,
|
||||
SENSORS_TYPE_PROXIMITY,
|
||||
SENSORS_TYPE_GRAVITY,
|
||||
SENSORS_TYPE_LINEAR_ACCELERATION,
|
||||
SENSORS_TYPE_ROTATION_VECTOR,
|
||||
SENSORS_TYPE_RELATIVE_HUMIDITY,
|
||||
SENSORS_TYPE_AMBIENT_TEMPERATURE,
|
||||
SENSORS_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
|
||||
SENSORS_TYPE_GAME_ROTATION_VECTOR,
|
||||
SENSORS_TYPE_GYROSCOPE_UNCALIBRATED,
|
||||
SENSORS_TYPE_SIGNIFICANT_MOTION,
|
||||
SENSORS_TYPE_STEP_DETECTED,
|
||||
SENSORS_TYPE_STEP_COUNTER,
|
||||
SENSORS_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
|
||||
SENSORS_TYPE_HEART_RATE,
|
||||
SENSORS_TYPE_TILT_DETECTOR,
|
||||
SENSORS_TYPE_WAKE_GESTURE,
|
||||
SENSORS_TYPE_GLANCE_GESTURE,
|
||||
SENSORS_TYPE_PICK_UP_GESTURE,
|
||||
SENSORS_TYPE_WRIST_TILT_GESTURE,
|
||||
SENSORS_NUM_TYPES
|
||||
};
|
||||
|
||||
struct SensorsEvent {
|
||||
SensorsType mType;
|
||||
SensorsStatus mStatus;
|
||||
SensorsDeliveryMode mDeliveryMode;
|
||||
int64_t mTimestamp;
|
||||
union {
|
||||
float mFloat[6];
|
||||
uint64_t mUint[1];
|
||||
} mData;
|
||||
};
|
||||
|
||||
/**
|
||||
* |SensorsSensor| represents a device sensor; either single or composite.
|
||||
*/
|
||||
struct SensorsSensor {
|
||||
SensorsSensor(int32_t aId, SensorsType aType,
|
||||
float aRange, float aResolution,
|
||||
float aPower, int32_t aMinPeriod,
|
||||
int32_t aMaxPeriod,
|
||||
SensorsTriggerMode aTriggerMode,
|
||||
SensorsDeliveryMode aDeliveryMode)
|
||||
: mId(aId)
|
||||
, mType(aType)
|
||||
, mRange(aRange)
|
||||
, mResolution(aResolution)
|
||||
, mPower(aPower)
|
||||
, mMinPeriod(aMinPeriod)
|
||||
, mMaxPeriod(aMaxPeriod)
|
||||
, mTriggerMode(aTriggerMode)
|
||||
, mDeliveryMode(aDeliveryMode)
|
||||
{ }
|
||||
|
||||
int32_t mId;
|
||||
SensorsType mType;
|
||||
float mRange;
|
||||
float mResolution;
|
||||
float mPower;
|
||||
int32_t mMinPeriod;
|
||||
int32_t mMaxPeriod;
|
||||
SensorsTriggerMode mTriggerMode;
|
||||
SensorsDeliveryMode mDeliveryMode;
|
||||
};
|
||||
|
||||
/**
|
||||
* |SensorClass| represents the status of a specific sensor type.
|
||||
*/
|
||||
struct SensorsSensorClass {
|
||||
SensorsSensorClass()
|
||||
: mActivated(0)
|
||||
, mMinValue(0)
|
||||
, mMaxValue(0)
|
||||
{ }
|
||||
|
||||
void UpdateFromSensor(const SensorsSensor& aSensor)
|
||||
{
|
||||
mMaxValue = std::max(aSensor.mRange, mMaxValue);
|
||||
}
|
||||
|
||||
uint32_t mActivated;
|
||||
float mMinValue;
|
||||
float mMaxValue;
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // hal_gonk_SensorsTypes_h
|
||||
@@ -48,6 +48,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
'gonk/GonkDiskSpaceWatcher.cpp',
|
||||
'gonk/GonkFMRadio.cpp',
|
||||
'gonk/GonkSensor.cpp',
|
||||
'gonk/GonkSensorsHelpers.cpp',
|
||||
'gonk/GonkSwitch.cpp',
|
||||
'gonk/UeventPoller.cpp',
|
||||
'linux/LinuxMemory.cpp',
|
||||
|
||||
+11
-13
@@ -315,20 +315,18 @@ FatalError(const char* aProtocolName, const char* aMsg,
|
||||
formattedMessage.AppendLiteral("]: \"");
|
||||
formattedMessage.AppendASCII(aMsg);
|
||||
if (aIsParent) {
|
||||
formattedMessage.AppendLiteral("\". Killing child side as a result.");
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// We're going to crash the parent process because at this time
|
||||
// there's no other really nice way of getting a minidump out of
|
||||
// this process if we're off the main thread.
|
||||
formattedMessage.AppendLiteral("\". Intentionally crashing.");
|
||||
NS_ERROR(formattedMessage.get());
|
||||
|
||||
if (aOtherPid != kInvalidProcessId && aOtherPid != base::GetCurrentProcId()) {
|
||||
ScopedProcessHandle otherProcessHandle;
|
||||
if (base::OpenProcessHandle(aOtherPid, &otherProcessHandle.rwget())) {
|
||||
if (!base::KillProcess(otherProcessHandle,
|
||||
base::PROCESS_END_KILLED_BY_USER, false)) {
|
||||
NS_ERROR("May have failed to kill child!");
|
||||
}
|
||||
} else {
|
||||
NS_ERROR("Failed to open child process when attempting kill.");
|
||||
}
|
||||
}
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
|
||||
nsDependentCString(aProtocolName));
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorMsg"),
|
||||
nsDependentCString(aMsg));
|
||||
#endif
|
||||
MOZ_CRASH("IPC FatalError in the parent process!");
|
||||
} else {
|
||||
formattedMessage.AppendLiteral("\". abort()ing as a result.");
|
||||
NS_RUNTIMEABORT(formattedMessage.get());
|
||||
|
||||
@@ -713,6 +713,94 @@ private:
|
||||
Tin6 mArg6;
|
||||
};
|
||||
|
||||
template <typename ObjectWrapper, typename Res,
|
||||
typename Tin1, typename Tin2, typename Tin3,
|
||||
typename Tin4, typename Tin5, typename Tin6,
|
||||
typename Tin7, typename Tin8,
|
||||
typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
|
||||
typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6,
|
||||
typename Arg7=Tin7, typename Arg8=Tin8>
|
||||
class DaemonNotificationRunnable8 final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef typename ObjectWrapper::ObjectType ObjectType;
|
||||
typedef DaemonNotificationRunnable8<ObjectWrapper, Res,
|
||||
Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8,
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> SelfType;
|
||||
|
||||
template <typename InitOp>
|
||||
static already_AddRefed<SelfType> Create(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
RefPtr<SelfType> runnable(new SelfType(aMethod));
|
||||
if (NS_FAILED(runnable->Init(aInitOp))) {
|
||||
return nullptr;
|
||||
}
|
||||
return runnable.forget();
|
||||
}
|
||||
|
||||
template <typename InitOp>
|
||||
static void
|
||||
Dispatch(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
RefPtr<SelfType> runnable = Create(aMethod, aInitOp);
|
||||
if (!runnable) {
|
||||
return;
|
||||
}
|
||||
Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ObjectType* obj = ObjectWrapper::GetInstance();
|
||||
if (!obj) {
|
||||
NS_WARNING("Notification handler not initialized");
|
||||
} else {
|
||||
((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4,
|
||||
mArg5, mArg6, mArg7, mArg8);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
DaemonNotificationRunnable8(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8))
|
||||
: mMethod(aMethod)
|
||||
{
|
||||
MOZ_ASSERT(mMethod);
|
||||
}
|
||||
|
||||
template<typename InitOp>
|
||||
nsresult Init(const InitOp& aInitOp)
|
||||
{
|
||||
nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4,
|
||||
mArg5, mArg6, mArg7, mArg8);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Res (ObjectType::*mMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
|
||||
Tin1 mArg1;
|
||||
Tin2 mArg2;
|
||||
Tin3 mArg3;
|
||||
Tin4 mArg4;
|
||||
Tin5 mArg5;
|
||||
Tin6 mArg6;
|
||||
Tin7 mArg7;
|
||||
Tin8 mArg8;
|
||||
};
|
||||
|
||||
template <typename ObjectWrapper, typename Res,
|
||||
typename Tin1, typename Tin2, typename Tin3,
|
||||
typename Tin4, typename Tin5, typename Tin6,
|
||||
|
||||
@@ -103,7 +103,7 @@ DaemonSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
|
||||
|
||||
if (!mPDU) {
|
||||
/* There's only one PDU for receiving. We reuse it every time. */
|
||||
mPDU = new DaemonSocketPDU(DaemonSocketPDU::MAX_PAYLOAD_LENGTH);
|
||||
mPDU = new DaemonSocketPDU(DaemonSocketPDU::PDU_MAX_PAYLOAD_LENGTH);
|
||||
}
|
||||
*aBuffer = mPDU.get();
|
||||
|
||||
|
||||
+13
-13
@@ -35,17 +35,17 @@ DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode,
|
||||
MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer);
|
||||
|
||||
// Allocate memory
|
||||
size_t availableSpace = HEADER_SIZE + aPayloadSize;
|
||||
size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize;
|
||||
ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
|
||||
|
||||
// Reserve PDU header
|
||||
uint8_t* data = Append(HEADER_SIZE);
|
||||
uint8_t* data = Append(PDU_HEADER_SIZE);
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
// Setup PDU header
|
||||
data[OFF_SERVICE] = aService;
|
||||
data[OFF_OPCODE] = aOpcode;
|
||||
memcpy(data + OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
|
||||
data[PDU_OFF_SERVICE] = aService;
|
||||
data[PDU_OFF_OPCODE] = aOpcode;
|
||||
memcpy(data + PDU_OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
|
||||
}
|
||||
|
||||
DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize)
|
||||
@@ -53,7 +53,7 @@ DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize)
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer);
|
||||
|
||||
size_t availableSpace = HEADER_SIZE + aPayloadSize;
|
||||
size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize;
|
||||
ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace);
|
||||
}
|
||||
|
||||
@@ -69,9 +69,9 @@ void
|
||||
DaemonSocketPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode,
|
||||
uint16_t& aPayloadSize)
|
||||
{
|
||||
memcpy(&aService, GetData(OFF_SERVICE), sizeof(aService));
|
||||
memcpy(&aOpcode, GetData(OFF_OPCODE), sizeof(aOpcode));
|
||||
memcpy(&aPayloadSize, GetData(OFF_LENGTH), sizeof(aPayloadSize));
|
||||
memcpy(&aService, GetData(PDU_OFF_SERVICE), sizeof(aService));
|
||||
memcpy(&aOpcode, GetData(PDU_OFF_OPCODE), sizeof(aOpcode));
|
||||
memcpy(&aPayloadSize, GetData(PDU_OFF_LENGTH), sizeof(aPayloadSize));
|
||||
}
|
||||
|
||||
ssize_t
|
||||
@@ -164,12 +164,12 @@ nsresult
|
||||
DaemonSocketPDU::UpdateHeader()
|
||||
{
|
||||
size_t len = GetPayloadSize();
|
||||
if (len >= MAX_PAYLOAD_LENGTH) {
|
||||
if (len >= PDU_MAX_PAYLOAD_LENGTH) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
uint16_t len16 = static_cast<uint16_t>(len);
|
||||
|
||||
memcpy(GetData(OFF_LENGTH), &len16, sizeof(len16));
|
||||
memcpy(GetData(PDU_OFF_LENGTH), &len16, sizeof(len16));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -177,9 +177,9 @@ DaemonSocketPDU::UpdateHeader()
|
||||
size_t
|
||||
DaemonSocketPDU::GetPayloadSize() const
|
||||
{
|
||||
MOZ_ASSERT(GetSize() >= HEADER_SIZE);
|
||||
MOZ_ASSERT(GetSize() >= PDU_HEADER_SIZE);
|
||||
|
||||
return GetSize() - HEADER_SIZE;
|
||||
return GetSize() - PDU_HEADER_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -39,12 +39,12 @@ class DaemonSocketPDU final : public UnixSocketIOBuffer
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
OFF_SERVICE = 0,
|
||||
OFF_OPCODE = 1,
|
||||
OFF_LENGTH = 2,
|
||||
OFF_PAYLOAD = 4,
|
||||
HEADER_SIZE = OFF_PAYLOAD,
|
||||
MAX_PAYLOAD_LENGTH = 1 << 16
|
||||
PDU_OFF_SERVICE = 0,
|
||||
PDU_OFF_OPCODE = 1,
|
||||
PDU_OFF_LENGTH = 2,
|
||||
PDU_OFF_PAYLOAD = 4,
|
||||
PDU_HEADER_SIZE = PDU_OFF_PAYLOAD,
|
||||
PDU_MAX_PAYLOAD_LENGTH = 1 << 16
|
||||
};
|
||||
|
||||
DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, uint16_t aPayloadSize);
|
||||
|
||||
@@ -349,6 +349,42 @@ PackPDU(const PackReversed<PackArray<U>>& aIn, DaemonSocketPDU& aPDU)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* |PackArray<PackReversed<U>>| is a helper for packing data of each element in
|
||||
* the reversed order. Pass an instance of this structure as the first argument
|
||||
* to |PackPDU| to pack data of each array element in the reversed order.
|
||||
*
|
||||
* Unlike |PackReversed<PackArray<U>>| which packed array elements in the
|
||||
* reversed order, here we use |PackReversed<U>| to pack data of each element
|
||||
* of |PackArray| in the reversed order.
|
||||
*/
|
||||
template<typename U>
|
||||
struct PackArray<PackReversed<U>>
|
||||
{
|
||||
PackArray(const U* aData, size_t aLength)
|
||||
: mData(aData)
|
||||
, mLength(aLength)
|
||||
{ }
|
||||
|
||||
const U* mData;
|
||||
size_t mLength;
|
||||
};
|
||||
|
||||
/* This implementation of |PackPDU| packs data of each element in |PackArray|
|
||||
* in the reversed order. (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template<typename U>
|
||||
inline nsresult
|
||||
PackPDU(const PackArray<PackReversed<U>>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
for (size_t i = 0; i < aIn.mLength; ++i) {
|
||||
nsresult rv = PackPDU(PackReversed<U>(aIn.mData[i]), aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, DaemonSocketPDU& aPDU)
|
||||
@@ -1106,6 +1142,136 @@ public:
|
||||
WarnAboutTrailingData();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
|
||||
T5& aArg5, T6& aArg6, T7& aArg7) const
|
||||
{
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg2);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg3);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg4);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg5);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg6);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg7);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
WarnAboutTrailingData();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
|
||||
T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8) const
|
||||
{
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg2);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg3);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg4);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg5);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg6);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg7);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg8);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
WarnAboutTrailingData();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
|
||||
T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8,
|
||||
T9& aArg9) const
|
||||
{
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg2);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg3);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg4);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg5);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg6);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg7);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg8);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = UnpackPDU(pdu, aArg9);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
WarnAboutTrailingData();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace DaemonSocketPDUHelpers
|
||||
|
||||
@@ -9,6 +9,12 @@ function jitTogglesMatch(opts) {
|
||||
if (k.indexOf(".enable") > 0 && opts[k] != currentOpts[k])
|
||||
return false;
|
||||
}
|
||||
|
||||
// ARM64 does not yet have an Ion code generator, so return false if
|
||||
// ion.enable is requested.
|
||||
if (getBuildConfiguration()['arm64-simulator'] && opts['ion.enable'])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,6 @@ class CodeGeneratorShared : public LElementVisitor
|
||||
inline Operand ToOperand(const LDefinition* def);
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
void resetOsiPointRegs(LSafepoint* safepoint);
|
||||
bool shouldVerifyOsiPointRegs(LSafepoint* safepoint);
|
||||
|
||||
@@ -75,3 +75,6 @@ include values3/reftest.list
|
||||
|
||||
# Variables Level 1
|
||||
include variables/reftest.list
|
||||
|
||||
# CSS will-change Level 1
|
||||
include will-change/reftest.list
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change reference</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
@@ -0,0 +1,12 @@
|
||||
== will-change-stacking-context-clip-path-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-filter-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-height-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-isolation-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-mask-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-mix-blend-mode-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-opacity-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-perspective-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-position-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-transform-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-transform-style-1.html green-square-100-by-100-ref.html
|
||||
== will-change-stacking-context-z-index-1.html green-square-100-by-100-ref.html
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: clip-path' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-masking/#the-clip-path">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: clip-path; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: filter' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/filter-effects/#FilterProperty">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: filter; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: height' does not create a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: height; background: green }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: red }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: isolation' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/compositing-1/#isolation">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: isolation; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: mask' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-masking/#the-mask-image">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: mask; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: mix-blend-mode' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/compositing-1/#mix-blend-mode">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: mix-blend-mode; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: opacity' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-color-3/#transparency">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: opacity; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: perspective' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-transforms/#perspective-property">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: perspective; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: position' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-positioning/#sticky-pos">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: position; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: transform' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-transforms/#transform-property">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: transform; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: transform-style' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-transforms/#transform-style-property">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: transform-style; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS will-change: 'will-change: z-index' creates a stacking context</title>
|
||||
<link rel="author" title="L. David Baron" href="http://dbaron.org/">
|
||||
<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-will-change-1/#will-change">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-positioning/#layered-presentation">
|
||||
<link rel="match" href="green-square-100-by-100-ref.html">
|
||||
<meta name="assert" content="If any non-initial value of a property would create a stacking context on the element, specifying that property in will-change must create a stacking context on the element.">
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
div { width: 100px; height: 100px }
|
||||
#wc { will-change: z-index; background: red }
|
||||
#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
|
||||
</style>
|
||||
<body>
|
||||
<div id="wc">
|
||||
<div id="child">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -355,6 +355,20 @@ FontFace::SetFeatureSettings(const nsAString& aValue, ErrorResult& aRv)
|
||||
SetDescriptor(eCSSFontDesc_FontFeatureSettings, aValue, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
FontFace::GetDisplay(nsString& aResult)
|
||||
{
|
||||
mFontFaceSet->FlushUserFontSet();
|
||||
GetDesc(eCSSFontDesc_Display, eCSSProperty_UNKNOWN, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
FontFace::SetDisplay(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
mFontFaceSet->FlushUserFontSet();
|
||||
SetDescriptor(eCSSFontDesc_Display, aValue, aRv);
|
||||
}
|
||||
|
||||
FontFaceLoadStatus
|
||||
FontFace::Status()
|
||||
{
|
||||
@@ -548,7 +562,10 @@ FontFace::SetDescriptors(const nsAString& aFamily,
|
||||
mDescriptors->mUnicodeRange) ||
|
||||
!ParseDescriptor(eCSSFontDesc_FontFeatureSettings,
|
||||
aDescriptors.mFeatureSettings,
|
||||
mDescriptors->mFontFeatureSettings)) {
|
||||
mDescriptors->mFontFeatureSettings) ||
|
||||
!ParseDescriptor(eCSSFontDesc_Display,
|
||||
aDescriptors.mDisplay,
|
||||
mDescriptors->mDisplay)) {
|
||||
// XXX Handle font-variant once we support it (bug 1055385).
|
||||
|
||||
// If any of the descriptors failed to parse, none of them should be set
|
||||
@@ -584,6 +601,7 @@ FontFace::GetDesc(nsCSSFontDesc aDescID,
|
||||
nsString& aResult) const
|
||||
{
|
||||
MOZ_ASSERT(aDescID == eCSSFontDesc_UnicodeRange ||
|
||||
aDescID == eCSSFontDesc_Display ||
|
||||
aPropID != eCSSProperty_UNKNOWN,
|
||||
"only pass eCSSProperty_UNKNOWN for eCSSFontDesc_UnicodeRange");
|
||||
|
||||
@@ -596,6 +614,8 @@ FontFace::GetDesc(nsCSSFontDesc aDescID,
|
||||
if (value.GetUnit() == eCSSUnit_Null) {
|
||||
if (aDescID == eCSSFontDesc_UnicodeRange) {
|
||||
aResult.AssignLiteral("U+0-10FFFF");
|
||||
} else if (aDescID == eCSSFontDesc_Display) {
|
||||
aResult.AssignLiteral("auto");
|
||||
} else if (aDescID != eCSSFontDesc_Family &&
|
||||
aDescID != eCSSFontDesc_Src) {
|
||||
aResult.AssignLiteral("normal");
|
||||
@@ -607,6 +627,10 @@ FontFace::GetDesc(nsCSSFontDesc aDescID,
|
||||
// Since there's no unicode-range property, we can't use
|
||||
// nsCSSValue::AppendToString to serialize this descriptor.
|
||||
nsStyleUtil::AppendUnicodeRange(value, aResult);
|
||||
} else if (aDescID == eCSSFontDesc_Display) {
|
||||
AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(value.GetIntValue(),
|
||||
nsCSSProps::kFontDisplayKTable),
|
||||
aResult);
|
||||
} else {
|
||||
value.AppendToString(aPropID, aResult, nsCSSValue::eNormalized);
|
||||
}
|
||||
|
||||
@@ -47,10 +47,11 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
: gfxUserFontEntry(aFontSet, aFontFaceSrcList, aWeight, aStretch,
|
||||
aStyle, aFeatureSettings, aLanguageOverride,
|
||||
aUnicodeRanges) {}
|
||||
aUnicodeRanges, aFontDisplay) {}
|
||||
|
||||
virtual void SetLoadState(UserFontLoadState aLoadState) override;
|
||||
virtual void GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult) override;
|
||||
@@ -150,6 +151,8 @@ public:
|
||||
void SetVariant(const nsAString& aValue, mozilla::ErrorResult& aRv);
|
||||
void GetFeatureSettings(nsString& aResult);
|
||||
void SetFeatureSettings(const nsAString& aValue, mozilla::ErrorResult& aRv);
|
||||
void GetDisplay(nsString& aResult);
|
||||
void SetDisplay(const nsAString& aValue, mozilla::ErrorResult& aRv);
|
||||
|
||||
mozilla::dom::FontFaceLoadStatus Status();
|
||||
mozilla::dom::Promise* Load(mozilla::ErrorResult& aRv);
|
||||
|
||||
@@ -789,14 +789,17 @@ FontFaceSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
|
||||
CheckLoadingFinished();
|
||||
}
|
||||
|
||||
// local rules have been rebuilt, so clear the flag
|
||||
mUserFontSet->mLocalRulesUsed = false;
|
||||
// if local rules needed to be rebuilt, they have been rebuilt at this point
|
||||
if (mUserFontSet->mRebuildLocalRules) {
|
||||
mUserFontSet->mLocalRulesUsed = false;
|
||||
mUserFontSet->mRebuildLocalRules = false;
|
||||
}
|
||||
|
||||
if (LOG_ENABLED() && !mRuleFaces.IsEmpty()) {
|
||||
LOG(("userfonts (%p) userfont rules update (%s) rule count: %" PRIuSIZE,
|
||||
LOG(("userfonts (%p) userfont rules update (%s) rule count: %d",
|
||||
mUserFontSet.get(),
|
||||
(modified ? "modified" : "not modified"),
|
||||
mRuleFaces.Length()));
|
||||
(int)(mRuleFaces.Length())));
|
||||
}
|
||||
|
||||
return modified;
|
||||
@@ -875,7 +878,8 @@ FontFaceSet::InsertRuleFontFace(FontFace* aFontFace, SheetType aSheetType,
|
||||
|
||||
// if local rules were used, don't use the old font entry
|
||||
// for rules containing src local usage
|
||||
if (mUserFontSet->mLocalRulesUsed) {
|
||||
if (mUserFontSet->mLocalRulesUsed &&
|
||||
mUserFontSet->mRebuildLocalRules) {
|
||||
nsCSSValue val;
|
||||
aFontFace->GetDesc(eCSSFontDesc_Src, val);
|
||||
nsCSSUnit unit = val.GetUnit();
|
||||
@@ -978,6 +982,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName,
|
||||
int32_t stretch = NS_STYLE_FONT_STRETCH_NORMAL;
|
||||
uint8_t italicStyle = NS_STYLE_FONT_STYLE_NORMAL;
|
||||
uint32_t languageOverride = NO_FONT_LANGUAGE_OVERRIDE;
|
||||
uint8_t fontDisplay = NS_FONT_DISPLAY_AUTO;
|
||||
|
||||
// set up weight
|
||||
aFontFace->GetDesc(eCSSFontDesc_Weight, val);
|
||||
@@ -1018,6 +1023,16 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName,
|
||||
"@font-face style has unexpected unit");
|
||||
}
|
||||
|
||||
// set up font display
|
||||
aFontFace->GetDesc(eCSSFontDesc_Display, val);
|
||||
unit = val.GetUnit();
|
||||
if (unit == eCSSUnit_Enumerated) {
|
||||
fontDisplay = val.GetIntValue();
|
||||
} else {
|
||||
NS_ASSERTION(unit == eCSSUnit_Null,
|
||||
"@font-face style has unexpected unit");
|
||||
}
|
||||
|
||||
// set up font features
|
||||
nsTArray<gfxFontFeature> featureSettings;
|
||||
aFontFace->GetDesc(eCSSFontDesc_FontFeatureSettings, val);
|
||||
@@ -1163,7 +1178,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName,
|
||||
stretch, italicStyle,
|
||||
featureSettings,
|
||||
languageOverride,
|
||||
unicodeRanges);
|
||||
unicodeRanges, fontDisplay);
|
||||
return entry.forget();
|
||||
}
|
||||
|
||||
@@ -1807,11 +1822,13 @@ FontFaceSet::UserFontSet::CreateUserFontEntry(
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges)
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay)
|
||||
{
|
||||
RefPtr<gfxUserFontEntry> entry =
|
||||
new FontFace::Entry(this, aFontFaceSrcList, aWeight, aStretch, aStyle,
|
||||
aFeatureSettings, aLanguageOverride, aUnicodeRanges);
|
||||
aFeatureSettings, aLanguageOverride, aUnicodeRanges,
|
||||
aFontDisplay);
|
||||
return entry.forget();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,8 @@ public:
|
||||
uint8_t aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFeatureSettings,
|
||||
uint32_t aLanguageOverride,
|
||||
gfxSparseBitSet* aUnicodeRanges) override;
|
||||
gfxSparseBitSet* aUnicodeRanges,
|
||||
uint8_t aFontDisplay) override;
|
||||
|
||||
private:
|
||||
RefPtr<FontFaceSet> mFontFaceSet;
|
||||
|
||||
@@ -220,6 +220,10 @@ CSS_PROP_ALIAS(-webkit-animation-timing-function,
|
||||
WebkitAnimationTimingFunction,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
|
||||
CSS_PROP_ALIAS(-webkit-filter,
|
||||
filter,
|
||||
WebkitFilter,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-text-size-adjust,
|
||||
text_size_adjust,
|
||||
WebkitTextSizeAdjust,
|
||||
@@ -313,26 +317,6 @@ CSS_PROP_ALIAS(-webkit-border-image,
|
||||
border_image,
|
||||
WebkitBorderImage,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-border-image-outset,
|
||||
border_image_outset,
|
||||
WebkitBorderImageOutset,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-border-image-repeat,
|
||||
border_image_repeat,
|
||||
WebkitBorderImageRepeat,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-border-image-slice,
|
||||
border_image_slice,
|
||||
WebkitBorderImageSlice,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-border-image-source,
|
||||
border_image_source,
|
||||
WebkitBorderImageSource,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-border-image-width,
|
||||
border_image_width,
|
||||
WebkitBorderImageWidth,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
|
||||
CSS_PROP_ALIAS(-webkit-box-shadow,
|
||||
box_shadow,
|
||||
|
||||
@@ -1589,8 +1589,8 @@ CSS_PROP_POSITION(
|
||||
AlignContent,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
kAutoCompletionAlignJustifyContent,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
@@ -1599,8 +1599,8 @@ CSS_PROP_POSITION(
|
||||
AlignItems,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
kAutoCompletionAlignItems,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
@@ -1609,8 +1609,8 @@ CSS_PROP_POSITION(
|
||||
AlignSelf,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
kAutoCompletionAlignJustifySelf,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_SHORTHAND(
|
||||
@@ -1720,8 +1720,8 @@ CSS_PROP_POSITION(
|
||||
JustifyContent,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
kAutoCompletionAlignJustifyContent,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
@@ -1730,8 +1730,9 @@ CSS_PROP_POSITION(
|
||||
JustifyItems,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
// for auto-completion we use same values as justify-self:
|
||||
kAutoCompletionAlignJustifySelf,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
@@ -1740,8 +1741,8 @@ CSS_PROP_POSITION(
|
||||
JustifySelf,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
nullptr,
|
||||
VARIANT_HK,
|
||||
kAutoCompletionAlignJustifySelf,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_DISPLAY(
|
||||
@@ -2724,7 +2725,8 @@ CSS_PROP_DISPLAY(
|
||||
Opacity,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
|
||||
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR,
|
||||
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR |
|
||||
CSS_PROPERTY_CREATES_STACKING_CONTEXT,
|
||||
"",
|
||||
VARIANT_HN,
|
||||
nullptr,
|
||||
@@ -3959,8 +3961,7 @@ CSS_PROP_SVG(
|
||||
fill,
|
||||
fill,
|
||||
Fill,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
kContextPatternKTable,
|
||||
@@ -4217,8 +4218,7 @@ CSS_PROP_SVG(
|
||||
stroke,
|
||||
stroke,
|
||||
Stroke,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"",
|
||||
0,
|
||||
kContextPatternKTable,
|
||||
|
||||
@@ -1383,6 +1383,63 @@ const KTableEntry nsCSSProps::kAlignContentPosition[] = {
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
// <NOTE> these are only used for auto-completion, not parsing:
|
||||
const KTableEntry nsCSSProps::kAutoCompletionAlignJustifySelf[] = {
|
||||
{ eCSSKeyword_auto, NS_STYLE_ALIGN_AUTO },
|
||||
{ eCSSKeyword_normal, NS_STYLE_ALIGN_NORMAL },
|
||||
{ eCSSKeyword_stretch, NS_STYLE_ALIGN_STRETCH },
|
||||
{ eCSSKeyword_baseline, NS_STYLE_ALIGN_BASELINE },
|
||||
{ eCSSKeyword_last_baseline, NS_STYLE_ALIGN_LAST_BASELINE },
|
||||
{ eCSSKeyword_start, NS_STYLE_ALIGN_START },
|
||||
{ eCSSKeyword_end, NS_STYLE_ALIGN_END },
|
||||
{ eCSSKeyword_flex_start, NS_STYLE_ALIGN_FLEX_START },
|
||||
{ eCSSKeyword_flex_end, NS_STYLE_ALIGN_FLEX_END },
|
||||
{ eCSSKeyword_center, NS_STYLE_ALIGN_CENTER },
|
||||
{ eCSSKeyword_left, NS_STYLE_ALIGN_LEFT },
|
||||
{ eCSSKeyword_right, NS_STYLE_ALIGN_RIGHT },
|
||||
{ eCSSKeyword_self_start, NS_STYLE_ALIGN_SELF_START },
|
||||
{ eCSSKeyword_self_end, NS_STYLE_ALIGN_SELF_END },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
const KTableEntry nsCSSProps::kAutoCompletionAlignItems[] = {
|
||||
// Intentionally no 'auto' here.
|
||||
{ eCSSKeyword_normal, NS_STYLE_ALIGN_NORMAL },
|
||||
{ eCSSKeyword_stretch, NS_STYLE_ALIGN_STRETCH },
|
||||
{ eCSSKeyword_baseline, NS_STYLE_ALIGN_BASELINE },
|
||||
{ eCSSKeyword_last_baseline, NS_STYLE_ALIGN_LAST_BASELINE },
|
||||
{ eCSSKeyword_start, NS_STYLE_ALIGN_START },
|
||||
{ eCSSKeyword_end, NS_STYLE_ALIGN_END },
|
||||
{ eCSSKeyword_flex_start, NS_STYLE_ALIGN_FLEX_START },
|
||||
{ eCSSKeyword_flex_end, NS_STYLE_ALIGN_FLEX_END },
|
||||
{ eCSSKeyword_center, NS_STYLE_ALIGN_CENTER },
|
||||
{ eCSSKeyword_left, NS_STYLE_ALIGN_LEFT },
|
||||
{ eCSSKeyword_right, NS_STYLE_ALIGN_RIGHT },
|
||||
{ eCSSKeyword_self_start, NS_STYLE_ALIGN_SELF_START },
|
||||
{ eCSSKeyword_self_end, NS_STYLE_ALIGN_SELF_END },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
|
||||
const KTableEntry nsCSSProps::kAutoCompletionAlignJustifyContent[] = {
|
||||
// Intentionally no 'auto' here.
|
||||
{ eCSSKeyword_normal, NS_STYLE_ALIGN_NORMAL },
|
||||
{ eCSSKeyword_baseline, NS_STYLE_ALIGN_BASELINE },
|
||||
{ eCSSKeyword_last_baseline, NS_STYLE_ALIGN_LAST_BASELINE },
|
||||
{ eCSSKeyword_stretch, NS_STYLE_ALIGN_STRETCH },
|
||||
{ eCSSKeyword_space_between, NS_STYLE_ALIGN_SPACE_BETWEEN },
|
||||
{ eCSSKeyword_space_around, NS_STYLE_ALIGN_SPACE_AROUND },
|
||||
{ eCSSKeyword_space_evenly, NS_STYLE_ALIGN_SPACE_EVENLY },
|
||||
{ eCSSKeyword_start, NS_STYLE_ALIGN_START },
|
||||
{ eCSSKeyword_end, NS_STYLE_ALIGN_END },
|
||||
{ eCSSKeyword_flex_start, NS_STYLE_ALIGN_FLEX_START },
|
||||
{ eCSSKeyword_flex_end, NS_STYLE_ALIGN_FLEX_END },
|
||||
{ eCSSKeyword_center, NS_STYLE_ALIGN_CENTER },
|
||||
{ eCSSKeyword_left, NS_STYLE_ALIGN_LEFT },
|
||||
{ eCSSKeyword_right, NS_STYLE_ALIGN_RIGHT },
|
||||
{ eCSSKeyword_UNKNOWN, -1 }
|
||||
};
|
||||
// </NOTE>
|
||||
|
||||
const KTableEntry nsCSSProps::kFlexDirectionKTable[] = {
|
||||
{ eCSSKeyword_row, NS_STYLE_FLEX_DIRECTION_ROW },
|
||||
{ eCSSKeyword_row_reverse, NS_STYLE_FLEX_DIRECTION_ROW_REVERSE },
|
||||
|
||||
@@ -726,7 +726,7 @@ public:
|
||||
static KTableEntry kDisplayKTable[];
|
||||
static const KTableEntry kElevationKTable[];
|
||||
static const KTableEntry kEmptyCellsKTable[];
|
||||
// -- tables for the align-/justify-content/items/self properties --
|
||||
// -- tables for parsing the {align,justify}-{content,items,self} properties --
|
||||
static const KTableEntry kAlignAllKeywords[];
|
||||
static const KTableEntry kAlignOverflowPosition[]; // <overflow-position>
|
||||
static const KTableEntry kAlignSelfPosition[]; // <self-position>
|
||||
@@ -737,8 +737,10 @@ public:
|
||||
static const KTableEntry kAlignNormalBaseline[]; // 'normal/baseline/last-baseline'
|
||||
static const KTableEntry kAlignContentDistribution[]; // <content-distribution>
|
||||
static const KTableEntry kAlignContentPosition[]; // <content-position>
|
||||
static const KTableEntry kAlignSelfKTable[];
|
||||
static const KTableEntry kJustifyContentKTable[];
|
||||
// -- tables for auto-completion of the {align,justify}-{content,items,self} properties --
|
||||
static const KTableEntry kAutoCompletionAlignJustifySelf[];
|
||||
static const KTableEntry kAutoCompletionAlignItems[];
|
||||
static const KTableEntry kAutoCompletionAlignJustifyContent[];
|
||||
// ------------------------------------------------------------------
|
||||
static const KTableEntry kFlexDirectionKTable[];
|
||||
static const KTableEntry kFlexWrapKTable[];
|
||||
|
||||
@@ -31,6 +31,18 @@ using namespace mozilla::dom;
|
||||
#define LOG_ENABLED() MOZ_LOG_TEST(gfxUserFontSet::GetUserFontsLog(), \
|
||||
LogLevel::Debug)
|
||||
|
||||
static uint32_t
|
||||
GetFallbackDelay()
|
||||
{
|
||||
return Preferences::GetInt("gfx.downloadable_fonts.fallback_delay", 3000);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
GetShortFallbackDelay()
|
||||
{
|
||||
return Preferences::GetInt("gfx.downloadable_fonts.fallback_delay_short", 100);
|
||||
}
|
||||
|
||||
nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry,
|
||||
nsIURI* aFontURI,
|
||||
FontFaceSet* aFontFaceSet,
|
||||
@@ -60,8 +72,15 @@ nsFontFaceLoader::~nsFontFaceLoader()
|
||||
void
|
||||
nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader)
|
||||
{
|
||||
int32_t loadTimeout =
|
||||
Preferences::GetInt("gfx.downloadable_fonts.fallback_delay", 3000);
|
||||
int32_t loadTimeout;
|
||||
uint8_t fontDisplay = GetFontDisplay();
|
||||
if (fontDisplay == NS_FONT_DISPLAY_AUTO ||
|
||||
fontDisplay == NS_FONT_DISPLAY_BLOCK) {
|
||||
loadTimeout = GetFallbackDelay();
|
||||
} else {
|
||||
loadTimeout = GetShortFallbackDelay();
|
||||
}
|
||||
|
||||
if (loadTimeout > 0) {
|
||||
mLoadTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mLoadTimer) {
|
||||
@@ -87,39 +106,72 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
}
|
||||
|
||||
gfxUserFontEntry* ufe = loader->mUserFontEntry.get();
|
||||
bool updateUserFontSet = true;
|
||||
uint8_t fontDisplay = loader->GetFontDisplay();
|
||||
|
||||
// If the entry is loading, check whether it's >75% done; if so,
|
||||
// we allow another timeout period before showing a fallback font.
|
||||
if (ufe->mFontDataLoadingState == gfxUserFontEntry::LOADING_STARTED) {
|
||||
int64_t contentLength;
|
||||
uint32_t numBytesRead;
|
||||
if (NS_SUCCEEDED(loader->mChannel->GetContentLength(&contentLength)) &&
|
||||
contentLength > 0 &&
|
||||
contentLength < UINT32_MAX &&
|
||||
NS_SUCCEEDED(loader->mStreamLoader->GetNumBytesRead(&numBytesRead)) &&
|
||||
numBytesRead > 3 * (uint32_t(contentLength) >> 2))
|
||||
{
|
||||
// More than 3/4 the data has been downloaded, so allow 50% extra
|
||||
// time and hope the remainder will arrive before the additional
|
||||
// time expires.
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE;
|
||||
uint32_t delay;
|
||||
loader->mLoadTimer->GetDelay(&delay);
|
||||
loader->mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
|
||||
static_cast<void*>(loader),
|
||||
delay >> 1,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
updateUserFontSet = false;
|
||||
LOG(("userfonts (%p) 75%% done, resetting timer\n", loader));
|
||||
// Depending upon the value of the font-display descriptor for the font,
|
||||
// their may be one or two timeouts associated with each font. The LOADING_SLOWLY
|
||||
// state indicates that the fallback font is shown. The LOADING_TIMED_OUT
|
||||
// state indicates that the fallback font is shown *and* the downloaded font
|
||||
// resource will not replace the fallback font when the load completes.
|
||||
|
||||
bool updateUserFontSet = true;
|
||||
switch (fontDisplay) {
|
||||
case NS_FONT_DISPLAY_AUTO:
|
||||
case NS_FONT_DISPLAY_BLOCK:
|
||||
// If the entry is loading, check whether it's >75% done; if so,
|
||||
// we allow another timeout period before showing a fallback font.
|
||||
if (ufe->mFontDataLoadingState == gfxUserFontEntry::LOADING_STARTED) {
|
||||
int64_t contentLength;
|
||||
uint32_t numBytesRead;
|
||||
if (NS_SUCCEEDED(loader->mChannel->GetContentLength(&contentLength)) &&
|
||||
contentLength > 0 &&
|
||||
contentLength < UINT32_MAX &&
|
||||
NS_SUCCEEDED(loader->mStreamLoader->GetNumBytesRead(&numBytesRead)) &&
|
||||
numBytesRead > 3 * (uint32_t(contentLength) >> 2))
|
||||
{
|
||||
// More than 3/4 the data has been downloaded, so allow 50% extra
|
||||
// time and hope the remainder will arrive before the additional
|
||||
// time expires.
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE;
|
||||
uint32_t delay;
|
||||
loader->mLoadTimer->GetDelay(&delay);
|
||||
loader->mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
|
||||
static_cast<void*>(loader),
|
||||
delay >> 1,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
updateUserFontSet = false;
|
||||
LOG(("userfonts (%p) 75%% done, resetting timer\n", loader));
|
||||
}
|
||||
}
|
||||
if (updateUserFontSet) {
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
}
|
||||
break;
|
||||
case NS_FONT_DISPLAY_SWAP:
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
break;
|
||||
case NS_FONT_DISPLAY_FALLBACK: {
|
||||
if (ufe->mFontDataLoadingState == gfxUserFontEntry::LOADING_STARTED) {
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
} else {
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_TIMED_OUT;
|
||||
updateUserFontSet = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NS_FONT_DISPLAY_OPTIONAL:
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_TIMED_OUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("strange font-display value");
|
||||
break;
|
||||
}
|
||||
|
||||
// If the font is not 75% loaded, or if we've already timed out once
|
||||
// before, we mark this entry as "loading slowly", so the fallback
|
||||
// font will be used in the meantime, and tell the context to refresh.
|
||||
if (updateUserFontSet) {
|
||||
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
ufe->GetUserFontSets(fontSets);
|
||||
for (gfxUserFontSet* fontSet : fontSets) {
|
||||
@@ -127,8 +179,8 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
if (ctx) {
|
||||
fontSet->IncrementGeneration();
|
||||
ctx->UserFontSetUpdated(ufe);
|
||||
LOG(("userfonts (%p) timeout reflow for pres context %p\n",
|
||||
loader, ctx));
|
||||
LOG(("userfonts (%p) timeout reflow for pres context %p display %d\n",
|
||||
loader, ctx, fontDisplay));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,6 +207,16 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
uint32_t downloadTimeMS = uint32_t(downloadTime.ToMilliseconds());
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_DOWNLOAD_TIME, downloadTimeMS);
|
||||
|
||||
if (GetFontDisplay() == NS_FONT_DISPLAY_FALLBACK) {
|
||||
uint32_t loadTimeout = GetFallbackDelay();
|
||||
if (downloadTimeMS > loadTimeout &&
|
||||
(mUserFontEntry->mFontDataLoadingState ==
|
||||
gfxUserFontEntry::LOADING_SLOWLY)) {
|
||||
mUserFontEntry->mFontDataLoadingState =
|
||||
gfxUserFontEntry::LOADING_TIMED_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString fontURI;
|
||||
mFontURI->GetSpec(fontURI);
|
||||
@@ -271,3 +333,13 @@ nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
nsFontFaceLoader::GetFontDisplay()
|
||||
{
|
||||
uint8_t fontDisplay = NS_FONT_DISPLAY_AUTO;
|
||||
if (Preferences::GetBool("layout.css.font-display.enabled")) {
|
||||
fontDisplay = mUserFontEntry->GetFontDisplay();
|
||||
}
|
||||
return fontDisplay;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
protected:
|
||||
virtual ~nsFontFaceLoader();
|
||||
|
||||
// helper method for determining the font-display value
|
||||
uint8_t GetFontDisplay();
|
||||
|
||||
private:
|
||||
RefPtr<gfxUserFontEntry> mUserFontEntry;
|
||||
nsCOMPtr<nsIURI> mFontURI;
|
||||
|
||||
@@ -2456,7 +2456,8 @@ struct nsStylePosition
|
||||
const nsStyleVisibility* aOldStyleVisibility) const;
|
||||
static nsChangeHint MaxDifference() {
|
||||
return NS_CombineHint(NS_STYLE_HINT_REFLOW,
|
||||
nsChangeHint(nsChangeHint_RecomputePosition |
|
||||
nsChangeHint(nsChangeHint_NeutralChange |
|
||||
nsChangeHint_RecomputePosition |
|
||||
nsChangeHint_UpdateParentOverflow |
|
||||
nsChangeHint_UpdateComputedBSize));
|
||||
}
|
||||
|
||||
@@ -63,5 +63,10 @@ var gCSSFontFaceDescriptors = {
|
||||
domProp: null,
|
||||
values: [ "U+0-10FFFF", "U+3-7B3", "U+3??", "U+6A", "U+3????", "U+???", "U+302-302", "U+0-7,U+A-C", "U+100-17F,U+200-17F", "U+3??, U+500-513 ,U+612 , U+4????", "U+1FFF,U+200-27F" ],
|
||||
invalid_values: [ "U+1????-2????", "U+0-7,A-C", "U+100-17F,200-17F", "U+6A!important", "U+6A)" ]
|
||||
},
|
||||
"font-display": {
|
||||
domProp: null,
|
||||
values: [ "auto", "block", "swap", "fallback", "optional" ],
|
||||
invalid_values: [ "normal", "initial" ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7006,6 +7006,13 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
alias_for: "animation-timing-function",
|
||||
subproperties: [ "animation-timing-function" ],
|
||||
};
|
||||
gCSSProperties["-webkit-filter"] = {
|
||||
domProp: "webkitFilter",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "filter",
|
||||
subproperties: [ "filter" ],
|
||||
};
|
||||
gCSSProperties["-webkit-text-size-adjust"] = {
|
||||
domProp: "webkitTextSizeAdjust",
|
||||
inherited: true,
|
||||
@@ -7160,41 +7167,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
alias_for: "border-image",
|
||||
subproperties: [ "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat" ],
|
||||
};
|
||||
gCSSProperties["-webkit-border-image-outset"] = {
|
||||
domProp: "webkitBorderImageOutset",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "border-image-outset",
|
||||
subproperties: [ "border-image-outset" ],
|
||||
};
|
||||
gCSSProperties["-webkit-border-image-repeat"] = {
|
||||
domProp: "webkitBorderImageRepeat",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "border-image-repeat",
|
||||
subproperties: [ "border-image-repeat" ],
|
||||
};
|
||||
gCSSProperties["-webkit-border-image-slice"] = {
|
||||
domProp: "webkitBorderImageSlice",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "border-image-slice",
|
||||
subproperties: [ "border-image-slice" ],
|
||||
};
|
||||
gCSSProperties["-webkit-border-image-source"] = {
|
||||
domProp: "webkitBorderImageSource",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "border-image-source",
|
||||
subproperties: [ "border-image-source" ],
|
||||
};
|
||||
gCSSProperties["-webkit-border-image-width"] = {
|
||||
domProp: "webkitBorderImageWidth",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "border-image-width",
|
||||
subproperties: [ "border-image-width" ],
|
||||
};
|
||||
gCSSProperties["-webkit-box-shadow"] = {
|
||||
domProp: "webkitBoxShadow",
|
||||
inherited: false,
|
||||
|
||||
@@ -91,19 +91,27 @@ function test_descriptor(descriptor)
|
||||
// To avoid triggering the slow script dialog, we have to test one
|
||||
// descriptor at a time.
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var descs = [];
|
||||
for (var desc in gCSSFontFaceDescriptors)
|
||||
descs.push(desc);
|
||||
descs = descs.reverse();
|
||||
function do_one() {
|
||||
if (descs.length == 0) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
function runTest() {
|
||||
var descs = [];
|
||||
for (var desc in gCSSFontFaceDescriptors)
|
||||
descs.push(desc);
|
||||
descs = descs.reverse();
|
||||
function do_one() {
|
||||
if (descs.length == 0) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
test_descriptor(descs.pop());
|
||||
SimpleTest.executeSoon(do_one);
|
||||
}
|
||||
test_descriptor(descs.pop());
|
||||
SimpleTest.executeSoon(do_one);
|
||||
}
|
||||
SimpleTest.executeSoon(do_one);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestLongerTimeout(5);
|
||||
|
||||
SpecialPowers.pushPrefEnv({ set: [["layout.css.font-display.enabled", true]] },
|
||||
runTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
@@ -19,7 +19,8 @@ var descriptorNames = {
|
||||
stretch: "font-stretch",
|
||||
unicodeRange: "unicode-range",
|
||||
variant: "font-variant",
|
||||
featureSettings: "font-feature-settings"
|
||||
featureSettings: "font-feature-settings",
|
||||
display: "font-display"
|
||||
};
|
||||
|
||||
// Default values for the FontFace descriptor attributes other than family, as
|
||||
@@ -30,7 +31,8 @@ var defaultValues = {
|
||||
stretch: "normal",
|
||||
unicodeRange: "U+0-10FFFF",
|
||||
variant: "normal",
|
||||
featureSettings: "normal"
|
||||
featureSettings: "normal",
|
||||
display: "auto"
|
||||
};
|
||||
|
||||
// Non-default values for the FontFace descriptor attributes other than family
|
||||
@@ -42,7 +44,8 @@ var nonDefaultValues = {
|
||||
stretch: ["Ultra-Condensed", "ultra-condensed"],
|
||||
unicodeRange: ["U+3??", "U+300-3FF"],
|
||||
variant: ["Small-Caps", "small-caps"],
|
||||
featureSettings: ["'dlig' on", "\"dlig\""]
|
||||
featureSettings: ["'dlig' on", "\"dlig\""],
|
||||
display: ["Block", "block"]
|
||||
};
|
||||
|
||||
// Invalid values for the FontFace descriptor attributes other than family.
|
||||
@@ -52,7 +55,8 @@ var invalidValues = {
|
||||
stretch: "wider",
|
||||
unicodeRange: "U+1????-2????",
|
||||
variant: "inherit",
|
||||
featureSettings: "dlig"
|
||||
featureSettings: "dlig",
|
||||
display: "normal"
|
||||
};
|
||||
|
||||
// Invalid font family names.
|
||||
@@ -159,8 +163,6 @@ function awaitRefresh() {
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Document and window from inside the display:none iframe.
|
||||
var nframe = document.getElementById("n");
|
||||
var ndocument = nframe.contentDocument;
|
||||
@@ -1859,11 +1861,16 @@ function runTest() {
|
||||
|
||||
function start() {
|
||||
if (SpecialPowers.getBoolPref("layout.css.font-loading-api.enabled")) {
|
||||
runTest();
|
||||
SpecialPowers.pushPrefEnv({ set: [["layout.css.font-display.enabled", true]] },
|
||||
runTest);
|
||||
} else {
|
||||
ok(true, "CSS Font Loading API is not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestLongerTimeout(5);
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
||||
@@ -13,6 +13,10 @@ using namespace mozilla;
|
||||
|
||||
namespace mp4_demuxer {
|
||||
|
||||
// Limit reads to 32MiB max.
|
||||
// static
|
||||
const uint64_t Box::kMAX_BOX_READ = 32 * 1024 * 1024;
|
||||
|
||||
// Returns the offset from the start of the body of a box of type |aType|
|
||||
// to the start of its first child.
|
||||
static uint32_t
|
||||
@@ -149,8 +153,8 @@ Box::Read(nsTArray<uint8_t>* aDest, const MediaByteRange& aRange)
|
||||
int64_t length;
|
||||
if (!mContext->mSource->Length(&length)) {
|
||||
// The HTTP server didn't give us a length to work with.
|
||||
// Limit the read to 32MiB max.
|
||||
length = std::min(aRange.mEnd - mChildOffset, uint64_t(32 * 1024 * 1024));
|
||||
// Limit the read to kMAX_BOX_READ max.
|
||||
length = std::min(aRange.mEnd - mChildOffset, kMAX_BOX_READ);
|
||||
} else {
|
||||
length = aRange.mEnd - mChildOffset;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ Index::Index(const nsTArray<Indice>& aIndex,
|
||||
int64_t lastOffset = 0;
|
||||
for (size_t i = 0; i < aIndex.Length(); i++) {
|
||||
const Indice& indice = aIndex[i];
|
||||
if (indice.sync) {
|
||||
if (indice.sync || mIsAudio) {
|
||||
haveSync = true;
|
||||
}
|
||||
if (!haveSync) {
|
||||
@@ -267,7 +267,7 @@ Index::Index(const nsTArray<Indice>& aIndex,
|
||||
sample.mCompositionRange = Interval<Microseconds>(indice.start_composition,
|
||||
indice.end_composition);
|
||||
sample.mDecodeTime = indice.start_decode;
|
||||
sample.mSync = indice.sync;
|
||||
sample.mSync = indice.sync || mIsAudio;
|
||||
// FIXME: Make this infallible after bug 968520 is done.
|
||||
MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample, fallible));
|
||||
if (indice.start_offset < lastOffset) {
|
||||
|
||||
@@ -112,7 +112,7 @@ MP4Metadata::~MP4Metadata()
|
||||
|
||||
#ifdef MOZ_RUST_MP4PARSE
|
||||
// Helper to test the rust parser on a data source.
|
||||
static bool try_rust(const UniquePtr<mp4parse_state, FreeMP4ParseState>& aRustState, RefPtr<Stream> aSource, int32_t* aCount)
|
||||
static bool try_rust(const UniquePtr<mp4parse_state, FreeMP4ParseState>& aRustState, RefPtr<Stream> aSource)
|
||||
{
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
int64_t length;
|
||||
@@ -129,9 +129,7 @@ static bool try_rust(const UniquePtr<mp4parse_state, FreeMP4ParseState>& aRustSt
|
||||
MOZ_LOG(sLog, LogLevel::Warning, ("Error copying mp4 data"));
|
||||
return false;
|
||||
}
|
||||
*aCount = mp4parse_read(aRustState.get(), buffer.data(), bytes_read);
|
||||
MOZ_LOG(sLog, LogLevel::Info, ("rust parser found %d tracks", int(*aCount)));
|
||||
return true;
|
||||
return mp4parse_read(aRustState.get(), buffer.data(), bytes_read);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -139,12 +137,18 @@ uint32_t
|
||||
MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
|
||||
{
|
||||
#ifdef MOZ_RUST_MP4PARSE
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
// Try in rust first.
|
||||
mRustState.reset(mp4parse_new());
|
||||
int32_t rust_tracks = 0;
|
||||
bool rust_mp4parse_success = try_rust(mRustState, mSource, &rust_tracks);
|
||||
int32_t rust_mp4parse_success = try_rust(mRustState, mSource);
|
||||
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_SUCCESS,
|
||||
rust_mp4parse_success);
|
||||
rust_mp4parse_success == 0);
|
||||
if (rust_mp4parse_success < 0) {
|
||||
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_ERROR_CODE,
|
||||
-rust_mp4parse_success);
|
||||
}
|
||||
uint32_t rust_tracks = mp4parse_get_track_count(mRustState.get());
|
||||
MOZ_LOG(sLog, LogLevel::Info, ("rust parser found %u tracks", rust_tracks));
|
||||
#endif
|
||||
size_t tracks = mPrivate->mMetadataExtractor->countTracks();
|
||||
uint32_t total = 0;
|
||||
@@ -176,7 +180,7 @@ MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
|
||||
uint32_t rust_total = 0;
|
||||
const char* rust_track_type = nullptr;
|
||||
if (rust_mp4parse_success && rust_tracks > 0) {
|
||||
for (int32_t i = 0; i < rust_tracks; ++i) {
|
||||
for (uint32_t i = 0; i < rust_tracks; ++i) {
|
||||
mp4parse_track_info track_info;
|
||||
int32_t r = mp4parse_get_track_info(mRustState.get(), i, &track_info);
|
||||
switch (aType) {
|
||||
@@ -197,9 +201,20 @@ MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
|
||||
}
|
||||
}
|
||||
}
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
MOZ_LOG(sLog, LogLevel::Info, ("%s tracks found: stagefright=%u rust=%u",
|
||||
rust_track_type, total, rust_total));
|
||||
switch (aType) {
|
||||
case mozilla::TrackInfo::kAudioTrack:
|
||||
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_AUDIO,
|
||||
rust_total == total);
|
||||
break;
|
||||
case mozilla::TrackInfo::kVideoTrack:
|
||||
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_TRACK_MATCH_VIDEO,
|
||||
rust_total == total);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,9 @@ MoofParser::Metadata()
|
||||
MediaByteRange ftyp;
|
||||
MediaByteRange moov;
|
||||
ScanForMetadata(ftyp, moov);
|
||||
if (!ftyp.Length() || !moov.Length()) {
|
||||
if (!ftyp.Length() || !moov.Length() ||
|
||||
ftyp.Length() > Box::kMAX_BOX_READ || moov.Length() > Box::kMAX_BOX_READ) {
|
||||
// No ftyp or moov, or trying to read bigger-that-readable box (32MB).
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaByteBuffer> metadata = new MediaByteBuffer();
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
diff --git a/media/libstagefright/binding/byteorder/mod.rs b/media/libstagefright/binding/byteorder/mod.rs
|
||||
index 59ba692..9d2d1d5 100644
|
||||
--- a/media/libstagefright/binding/byteorder/mod.rs
|
||||
+++ b/media/libstagefright/binding/byteorder/mod.rs
|
||||
@@ -36,16 +36,16 @@ assert_eq!(wtr, vec![5, 2, 0, 3]);
|
||||
```
|
||||
*/
|
||||
|
||||
-#![crate_name = "byteorder"]
|
||||
#![doc(html_root_url = "http://burntsushi.net/rustdoc/byteorder")]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use std::mem::transmute;
|
||||
|
||||
-pub use new::{ReadBytesExt, WriteBytesExt, Error, Result};
|
||||
+pub use byteorder::new::{ReadBytesExt, WriteBytesExt, Error, Result};
|
||||
|
||||
-mod new;
|
||||
+// Re-export new so gecko can build us as a mod intead of a crate.
|
||||
+pub mod new;
|
||||
|
||||
#[inline]
|
||||
fn extend_sign(val: u64, nbytes: usize) -> i64 {
|
||||
diff --git a/media/libstagefright/binding/byteorder/new.rs b/media/libstagefright/binding/byteorder/new.rs
|
||||
index bbef0cd..a2e5393 100644
|
||||
--- a/media/libstagefright/binding/byteorder/new.rs
|
||||
+++ b/media/libstagefright/binding/byteorder/new.rs
|
||||
@@ -3,7 +3,7 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::result;
|
||||
|
||||
-use ByteOrder;
|
||||
+use byteorder::ByteOrder;
|
||||
|
||||
/// A short-hand for `result::Result<T, byteorder::Error>`.
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
bool Read(nsTArray<uint8_t>* aDest);
|
||||
bool Read(nsTArray<uint8_t>* aDest, const MediaByteRange& aRange);
|
||||
|
||||
static const uint64_t kMAX_BOX_READ;
|
||||
|
||||
private:
|
||||
bool Contains(MediaByteRange aRange) const;
|
||||
BoxContext* mContext;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/media/libstagefright/binding/MP4Metadata.rs b/media/libstagefright/binding/MP4Metadata.rs
|
||||
index 2f1b873..d2ad827 100644
|
||||
--- a/media/libstagefright/binding/MP4Metadata.rs
|
||||
+++ b/media/libstagefright/binding/MP4Metadata.rs
|
||||
@@ -4,7 +4,7 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
-extern crate byteorder;
|
||||
+mod byteorder; // 'extern crate' upstream.
|
||||
use byteorder::ReadBytesExt;
|
||||
use std::error::Error as ErrorTrait; // For Err(e) => e.description().
|
||||
use std::io::{Read, BufRead, Take};
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
# Script to update mp4parse-rust sources to latest upstream
|
||||
|
||||
# Default version.
|
||||
VER=v0.1.3
|
||||
|
||||
# Accept version or commit from the command line.
|
||||
if test -n "$1"; then
|
||||
VER=$1
|
||||
fi
|
||||
|
||||
echo "Fetching sources..."
|
||||
rm -rf _upstream
|
||||
git clone https://github.com/mozilla/mp4parse-rust _upstream/mp4parse
|
||||
pushd _upstream/mp4parse
|
||||
git checkout ${VER}
|
||||
popd
|
||||
cp _upstream/mp4parse/src/lib.rs MP4Metadata.rs
|
||||
cp _upstream/mp4parse/src/capi.rs .
|
||||
|
||||
# TODO: download deps from crates.io.
|
||||
|
||||
git clone https://github.com/BurntSushi/byteorder _upstream/byteorder
|
||||
pushd _upstream/byteorder
|
||||
git checkout 0.3.13
|
||||
popd
|
||||
cp _upstream/byteorder/src/lib.rs byteorder/mod.rs
|
||||
cp _upstream/byteorder/src/new.rs byteorder/new.rs
|
||||
|
||||
echo "Applying patches..."
|
||||
patch -p4 < byteorder-mod.patch
|
||||
patch -p4 < mp4parse-mod.patch
|
||||
|
||||
echo "Cleaning up..."
|
||||
rm -rf _upstream
|
||||
|
||||
echo "Updated to ${VER}."
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user