import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1187056 - Dispatch the meta tag mutation events sooner so that any meta-viewport changes can be processed before scripts continue running. r=smaug (2e6f76079f)
- Bug 1238804. Make <base> actually work in a srcdoc document. r=smaug (a421e7c598)
- Bug 1239585 - Remove eSupportSVG from nsObjectLoadingContent capabilities; r=bz (68a79ef21b)
- Bug 1170572 - MQ CSS change not observed by picture source elements r=jdm (efc0be616e)
- Bug 1206720 - Remove invalid assertions during response image loading. r=jdm (0b6485de95)
- Bug 1229032 - don't copy arrays in PerformanceObserver::Observe; r=baku (f1b70e0bd2)
- Bug 1241840 - Set table cell colspan=0 to 1 instead per the HTML spec. r=bz (1900962d4c)
- Bug 812899 part 1. Split the "image is overflow" concept in ImageDocument into two separate booleans for vertical and horizontal overflow. r=khuey (8735b610f3)
- Bug 812899 part 2. Change the centering code in nsImageDocument to only try vertically centering via auto margins when we're not overflowing in the vertical direction, because if we _are_ overflowing that should cut off part of the image per spec. r=khuey (c3b84a8048)
- Bug 812899 part 3 - Make vertical 'auto' margins on absolutely positioned elements always center, even when the margins are negative. r=dbaron (e345fb9383)
- Bug 1238427 - Avoid a strong reference from the timeout timer to nsGeolocationRequest. r=jdm (2ad4dd3955)
- Bug 1240906 - Shut down geolocation service at xpcom-shutdown instead of quit-application. r=dougt (1e7fc9e624)
- Bug 1129633 - part1. Use win8 geolocation with a fallback to MLS - r=m_kato (3323b4a120)
- Bug 1145111: ensure the pos. cache isn't reset when nsGeolocationService shuts down provider. r=jdm (e69cab889a)
- Bug 1240664 - Only enable bug 1216148's behavior when there is a wakelock support. r=kanru (543a3a55b4)
- Bug 1240766 - Fix startup crash in Geolocation::Init() when principal URI is null r=jdm (1ece684418)
- Bug 1238873 - Handle the bug that if we take cached data, we might not get any update later. r=kchen. r=jdm. (ca186e89b3)
- Bug 1240666 - Follow-up to bug 1216148. r=kchen. (3f650b5f72)
- Bug 1227119 - Set a default value for variable ret. r=dougt (5b68dd1a22)
- Bug 1027734 - Convert mozPay to WebIDL. r=bzbarsky. (a4fd10d539)
- Bug 1214488 - Allow native callers in GetEntryGlobal. r=me (ca68cc8896)
- Bug 1248719. Fix things so that taking ownership of error reporting on an AutoJSAPI on a worker is OK even if that AutoJSAPI was initialized without an explicit global. r=bholley (b8e59eebc6)
- Bug 1156065 - Send cloneable messages from SiteSpecificUserAgent.js to fix UA overrides r=billm (e5cdbe96f6)
- Bug 1210099 - Fix structured clone of expanded principal (r=bholley) (01a5fd4e47)
- Bug 1230351: Replace ThirdPartyUtil::IsThirdPartyInternal's warning-spammy NS_ENSURE_ARG with an equivalent check that lacks the warning. r=mrbkap (037c39472c)
- Bug 1184293 - Don't call ThirdPartyUtil::GetBaseDomain if aUri is null. r=jduell (4853c0e9e0)
- Bug 862147 - instrument usage of window.sidebar.addSearchEngine, r=froydnj,smaug. (ef52ded1c0)
- Bug 1214764 - Convert NS_ENSURE to a plain return in nsDocument::IsScriptEnabled. r=bholley (0f3b6d63b4)
- Bug 1245950: Privately inherit from legacy interfaces nsIDOMWindow/nsIDOMWindowInternal. r=smaug (ff1d431d0d)
- Bug 1245950: Followup to null check before asserting. r=me CLOSED TREE (6e93af4a4a)
- Bug 1236607, pointerlock code should null check inner window before using it, r=xidorn (896d9723d5)
- Bug 1245245 - Fix typo in error string URL. r=botond (58c9548f15)
- Bug 1220604 - Remove dead code from nsGlobalWindow::SetNewDocument. r=baku (fc875db5e4)
- Bug 1247049 - Optimize GetScreenXY by using the new nsDeviceContext method to get desktop scale factor. r=emk (de66d59631)
- missing bit of  Bug 962249 part 3 (0b15f8b670)
- Bug 1240978 - Shorten timeout for black screen in fullscreen transition. r=smaug (2554a8e5a7)
- Bug 1246346 - patch 1 - Expose a DesktopToDevice scale factor on nsDeviceContext. r=emk (03856ec7b4)
- Bug 1246346 - patch 2 - Correct the origin of the DOM screen coordinates (screen.left, screen.top) for secondary display on a mixed-DPI configuration. r=emk (15ac2d3be6)
- Bug 1196159 - Set nsGlobalWindow::mIsClosed properly after window.close(). r=billm (27334e4b61)
- Bug 1240241 - Don't recurse infinitely in FilterCachedColorModels::ForColorModel if the original filter node was null. r=roc (1730db5ca7)
- Bug 1247706 - "Please don't disable WebGL if crashed on WebGL context". r=dvander (e25621753e)
- Bug 1244742. Use the default copy constructor and assignment operators. (0dac3bcbfb)
- Bug 1230929 - modified the logic in order to prvent null pointer dereference. r=jmuizelaar (1d5761abc9)
- Bug 1247979. Optimize ScaleToOutsidePixels. r=kats (2b9ef41111)
- Bug 1249368 - use UniquePtr instead of nsAutoArrayPtr in gfxAlphaBoxBlur; r=jrmuizel (e60419d49d)
- Bug 1082598 - Part 4: Workaround for naming conflict in unified sources for Skia and thebes DWrite fonts. r=jrmuizel (84a9e11ded)
- Bug 1172817 - Remove PL_DHashTableEnumerate() use from FontNameCache. r=jtd. (b0632cd825)
- Bug 1197717 - Load fonts from profile-agnostic writable location. r=jfkthame (c9227268ff)
- Bug 1246889 - Correctly check whether hb_blob_create failed in ShareTableAndGetBlob. r=jfkthame (f8c62776be)
- Bug 1246834 - Fix memory reporting of nsFontFamily{List,Name}. r=jfkthame. (0535b8c110)
- Bug 1238134 P1 Provide a Response.cloneUnfiltered() method for chrome code to access internal Response state. r=ehsan (3dc25b1501)
- Bug 1238134 P2 Test chrome-only Response.cloneUnfiltered(). r=ehsan (3c307c4ec0)
- Bug 1100949 - wrap font info reads with structured exception handler. r=bas (2c2cacb05e)
- Bug 1241931 - On shutdown stop any ongoing loading of fonts; GDI in particular. r=jdaggett (057aae8cab)
- Bug 1154182 - enable native keybindings for graphene. r=billm (33e706a020)
- Bug 1167081 - Call PuppetWidget::Destroy() in its destructor. r=roc (58115c3029)
- Bug 1222662 - Disable cursor caching in the content process on Windows. r=aklotz (e760794ee2)
- Bug 1240891 - Silence warning from calling GetNativeData(NS_NATIVE_WINDOW). r=roc (d766a47f66)
- Bug 1248981 - Fix spelling error in nsMenuUtilsX.mm, a=tomcat (b93c16b961)
- Bug 1197925 - Use channel->Open2() in intl/hyphenation/hnjstdio.cpp (r=sicking) (2bf5dd3cd3)
- Bug 1248339 - fix header sort order of hal. r=gsvelto (01b61a2f5d)
- Bug 1232687: Add system-service interface to HAL, r=gsvelto (ab692e1508)
- Bug 1236762 - Simplify locking APIs for SharedSurface. - r=jrmuizel (901ae94a85)
This commit is contained in:
2024-01-09 11:57:12 +08:00
parent 18db03a181
commit ee05861206
118 changed files with 1458 additions and 933 deletions
@@ -110,7 +110,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
[ 0, 1, 2, -1, -1],
[-1, -1, -1, -1, -1],
[ 3, 4, 5, -1, -1],
[ 6, 7, 7, 7, 7],
[ 6, 7, -1, -1, -1],
[ 6, 8, 9, -1, -1],
[ 6, 10, 9, 11, 12]
];
+92 -35
View File
@@ -114,7 +114,8 @@ nsJSPrincipals::ReadPrincipals(JSContext* aCx, JSStructuredCloneReader* aReader,
if (!(tag == SCTAG_DOM_NULL_PRINCIPAL ||
tag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
tag == SCTAG_DOM_CONTENT_PRINCIPAL)) {
tag == SCTAG_DOM_CONTENT_PRINCIPAL ||
tag == SCTAG_DOM_EXPANDED_PRINCIPAL)) {
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
return false;
}
@@ -122,27 +123,38 @@ nsJSPrincipals::ReadPrincipals(JSContext* aCx, JSStructuredCloneReader* aReader,
return ReadKnownPrincipalType(aCx, aReader, tag, aOutPrincipals);
}
/* static */ bool
nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
JSStructuredCloneReader* aReader,
uint32_t aTag,
JSPrincipals** aOutPrincipals)
static bool
ReadPrincipalInfo(JSStructuredCloneReader* aReader,
uint32_t aTag,
PrincipalInfo& aInfo)
{
MOZ_ASSERT(aTag == SCTAG_DOM_NULL_PRINCIPAL ||
aTag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
aTag == SCTAG_DOM_CONTENT_PRINCIPAL);
if (NS_WARN_IF(!NS_IsMainThread())) {
xpc::Throw(aCx, NS_ERROR_UNCATCHABLE_EXCEPTION);
return false;
}
PrincipalInfo info;
if (aTag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
info = SystemPrincipalInfo();
aInfo = SystemPrincipalInfo();
} else if (aTag == SCTAG_DOM_NULL_PRINCIPAL) {
info = NullPrincipalInfo();
} else {
aInfo = NullPrincipalInfo();
} else if (aTag == SCTAG_DOM_EXPANDED_PRINCIPAL) {
uint32_t length, unused;
if (!JS_ReadUint32Pair(aReader, &length, &unused)) {
return false;
}
ExpandedPrincipalInfo expanded;
for (uint32_t i = 0; i < length; i++) {
uint32_t tag;
if (!JS_ReadUint32Pair(aReader, &tag, &unused)) {
return false;
}
PrincipalInfo sub;
if (!ReadPrincipalInfo(aReader, tag, sub)) {
return false;
}
expanded.whitelist().AppendElement(sub);
}
aInfo = expanded;
} else if (aTag == SCTAG_DOM_CONTENT_PRINCIPAL) {
uint32_t suffixLength, specLength;
if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
return false;
@@ -162,7 +174,32 @@ nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
OriginAttributes attrs;
attrs.PopulateFromSuffix(suffix);
info = ContentPrincipalInfo(attrs, spec);
aInfo = ContentPrincipalInfo(attrs, spec);
} else {
MOZ_CRASH("unexpected principal structured clone tag");
}
return true;
}
/* static */ bool
nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
JSStructuredCloneReader* aReader,
uint32_t aTag,
JSPrincipals** aOutPrincipals)
{
MOZ_ASSERT(aTag == SCTAG_DOM_NULL_PRINCIPAL ||
aTag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
aTag == SCTAG_DOM_CONTENT_PRINCIPAL ||
aTag == SCTAG_DOM_EXPANDED_PRINCIPAL);
if (NS_WARN_IF(!NS_IsMainThread())) {
xpc::Throw(aCx, NS_ERROR_UNCATCHABLE_EXCEPTION);
return false;
}
PrincipalInfo info;
if (!ReadPrincipalInfo(aReader, aTag, info)) {
return false;
}
nsresult rv;
@@ -176,6 +213,40 @@ nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
return true;
}
static bool
WritePrincipalInfo(JSStructuredCloneWriter* aWriter, const PrincipalInfo& aInfo)
{
if (aInfo.type() == PrincipalInfo::TNullPrincipalInfo) {
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_NULL_PRINCIPAL, 0);
}
if (aInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_SYSTEM_PRINCIPAL, 0);
}
if (aInfo.type() == PrincipalInfo::TExpandedPrincipalInfo) {
const ExpandedPrincipalInfo& expanded = aInfo;
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_EXPANDED_PRINCIPAL, 0) ||
!JS_WriteUint32Pair(aWriter, expanded.whitelist().Length(), 0)) {
return false;
}
for (uint32_t i = 0; i < expanded.whitelist().Length(); i++) {
if (!WritePrincipalInfo(aWriter, expanded.whitelist()[i])) {
return false;
}
}
return true;
}
MOZ_ASSERT(aInfo.type() == PrincipalInfo::TContentPrincipalInfo);
const ContentPrincipalInfo& cInfo = aInfo;
nsAutoCString suffix;
cInfo.attrs().CreateSuffix(suffix);
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
JS_WriteUint32Pair(aWriter, suffix.Length(), cInfo.spec().Length()) &&
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
JS_WriteBytes(aWriter, cInfo.spec().get(), cInfo.spec().Length());
}
bool
nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter)
{
@@ -185,19 +256,5 @@ nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter)
return false;
}
if (info.type() == PrincipalInfo::TNullPrincipalInfo) {
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_NULL_PRINCIPAL, 0);
}
if (info.type() == PrincipalInfo::TSystemPrincipalInfo) {
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_SYSTEM_PRINCIPAL, 0);
}
MOZ_ASSERT(info.type() == PrincipalInfo::TContentPrincipalInfo);
const ContentPrincipalInfo& cInfo = info;
nsAutoCString suffix;
cInfo.attrs().CreateSuffix(suffix);
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
JS_WriteUint32Pair(aWriter, suffix.Length(), cInfo.spec().Length()) &&
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
JS_WriteBytes(aWriter, cInfo.spec().get(), cInfo.spec().Length());
return WritePrincipalInfo(aWriter, info);
}
+35
View File
@@ -122,6 +122,11 @@
#include <cutils/properties.h>
#endif
#ifdef MOZ_PAY
#include "nsIPaymentContentHelperService.h"
#include "mozilla/dom/DOMRequest.h"
#endif
namespace mozilla {
namespace dom {
@@ -2602,6 +2607,36 @@ Navigator::MozE10sEnabled()
return true;
}
#ifdef MOZ_PAY
already_AddRefed<DOMRequest>
Navigator::MozPay(JSContext* aCx,
JS::Handle<JS::Value> aJwts,
ErrorResult& aRv)
{
if (!mWindow || !mWindow->GetDocShell()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsresult rv;
nsCOMPtr<nsIPaymentContentHelperService> service =
do_GetService("@mozilla.org/payment/content-helper-service;1", &rv);
if (!service) {
aRv.Throw(rv);
return nullptr;
}
RefPtr<nsIDOMDOMRequest> request;
rv = service->Pay(mWindow, aJwts, getter_AddRefs(request));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
}
#endif // MOZ_PAY
/* static */
already_AddRefed<nsPIDOMWindow>
Navigator::GetWindowFromGlobal(JSObject* aGlobal)
+7
View File
@@ -39,6 +39,7 @@ class WakeLock;
class ArrayBufferViewOrBlobOrStringOrFormData;
struct MobileIdOptions;
class ServiceWorkerContainer;
class DOMRequest;
} // namespace dom
} // namespace mozilla
@@ -312,6 +313,12 @@ public:
bool MozE10sEnabled();
#ifdef MOZ_PAY
already_AddRefed<DOMRequest> MozPay(JSContext* aCx,
JS::Handle<JS::Value> aJwts,
ErrorResult& aRv);
#endif // MOZ_PAY
static void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
// WebIDL helper methods
+1 -1
View File
@@ -168,7 +168,7 @@ PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
return;
}
mEntryTypes = validEntryTypes;
mEntryTypes.SwapElements(validEntryTypes);
mPerformance->AddObserver(this);
mConnected = true;
-1
View File
@@ -293,7 +293,6 @@ ResponsiveImageSelector::SelectImage(bool aReselect)
nsCOMPtr<nsIURI> baseURI = mOwnerNode ? mOwnerNode->GetBaseURI() : nullptr;
if (!pctx || !doc || !baseURI) {
MOZ_ASSERT(false, "Unable to find document prescontext and base URI");
return oldBest != -1;
}
+8 -3
View File
@@ -175,7 +175,7 @@ ClampToSubject(nsIGlobalObject* aGlobalOrNull)
nsIPrincipal* globalPrin = aGlobalOrNull->PrincipalOrNull();
NS_ENSURE_TRUE(globalPrin, GetCurrentGlobal());
if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(globalPrin)) {
if (!nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller()->SubsumesConsideringDomain(globalPrin)) {
return GetCurrentGlobal();
}
@@ -505,8 +505,13 @@ AutoJSAPI::ReportException()
// In this case, we enter the privileged junk scope and don't dispatch any
// error events.
JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
if (!errorGlobal)
errorGlobal = xpc::PrivilegedJunkScope();
if (!errorGlobal) {
if (mIsMainThread) {
errorGlobal = xpc::PrivilegedJunkScope();
} else {
errorGlobal = workers::GetCurrentThreadWorkerGlobal();
}
}
JSAutoCompartment ac(cx(), errorGlobal);
JS::Rooted<JS::Value> exn(cx());
js::ErrorReport jsReport(cx());
+1 -1
View File
@@ -46,7 +46,7 @@ SiteSpecificUserAgent.prototype = {
return cachedResult;
}
let data = { uri: aURI };
let data = { uri: aURI.spec };
let result = cpmm.sendRpcMessage("Useragent:GetOverride", data)[0] || HTTP_PROTO_HANDLER.userAgent;
if (this.userAgentCache.size >= MAX_CACHE_SIZE) {
+2 -1
View File
@@ -417,7 +417,8 @@ StructuredCloneHolder::ReadFullySerializableObjects(JSContext* aCx,
if (aTag == SCTAG_DOM_NULL_PRINCIPAL ||
aTag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
aTag == SCTAG_DOM_CONTENT_PRINCIPAL) {
aTag == SCTAG_DOM_CONTENT_PRINCIPAL ||
aTag == SCTAG_DOM_EXPANDED_PRINCIPAL) {
JSPrincipals* prin;
if (!nsJSPrincipals::ReadKnownPrincipalType(aCx, aReader, aTag, &prin)) {
return nullptr;
+2
View File
@@ -51,6 +51,8 @@ enum StructuredCloneTags {
// This tag is for OffscreenCanvas.
SCTAG_DOM_CANVAS,
SCTAG_DOM_EXPANDED_PRINCIPAL,
SCTAG_DOM_MAX
};
+7 -1
View File
@@ -46,7 +46,9 @@ ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain,
nsIURI* aSecondURI,
bool* aResult)
{
NS_ENSURE_ARG(aSecondURI);
if (!aSecondURI) {
return NS_ERROR_INVALID_ARG;
}
// Get the base domain for aSecondURI.
nsCString secondDomain;
@@ -282,6 +284,10 @@ NS_IMETHODIMP
ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
nsACString& aBaseDomain)
{
if (!aHostURI) {
return NS_ERROR_INVALID_ARG;
}
// Get the base domain. this will fail if the host contains a leading dot,
// more than one trailing dot, or is otherwise malformed.
nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
+4
View File
@@ -44,3 +44,7 @@ property FillOpacity
// Push API
method PushManager.subscribe
method PushSubscription.unsubscribe
// window.sidebar.addSearchEngine
attribute Window.sidebar
method External.addSearchEngine
+7 -4
View File
@@ -8313,7 +8313,9 @@ nsDocument::IsScriptEnabled()
if (!globalObject && mMasterDocument) {
globalObject = do_QueryInterface(mMasterDocument->GetInnerWindow());
}
NS_ENSURE_TRUE(globalObject && globalObject->GetGlobalJSObject(), false);
if (!globalObject || !globalObject->GetGlobalJSObject()) {
return false;
}
return sm->ScriptAllowed(globalObject->GetGlobalJSObject());
}
@@ -10628,7 +10630,7 @@ nsDocument::SetImagesNeedAnimating(bool aAnimating)
}
already_AddRefed<Touch>
nsIDocument::CreateTouch(nsIDOMWindow* aView,
nsIDocument::CreateTouch(nsGlobalWindow* aView,
EventTarget* aTarget,
int32_t aIdentifier,
int32_t aPageX, int32_t aPageY,
@@ -10638,6 +10640,7 @@ nsIDocument::CreateTouch(nsIDOMWindow* aView,
float aRotationAngle,
float aForce)
{
MOZ_ASSERT_IF(aView, aView->IsInnerWindow());
RefPtr<Touch> touch = new Touch(aTarget,
aIdentifier,
aPageX, aPageY,
@@ -12110,7 +12113,7 @@ public:
mUserInputOrChromeCaller(aUserInputOrChromeCaller)
{
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
if (doc) {
if (doc && doc->GetInnerWindow()) {
mRequester = new nsContentPermissionRequester(doc->GetInnerWindow());
}
}
@@ -13395,7 +13398,7 @@ nsIDocument::ReportHasScrollLinkedEffect()
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Async Pan/Zoom"),
this, nsContentUtils::eLAYOUT_PROPERTIES,
"ScrollLinkedEffectFound");
"ScrollLinkedEffectFound2");
}
Selection*
+10 -10
View File
@@ -2449,13 +2449,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsresult rv = NS_OK;
// Set mDoc even if this is an outer window to avoid
// We set mDoc even though this is an outer window to avoid
// having to *always* reach into the inner window to find the
// document.
mDoc = aDocument;
if (IsInnerWindow()) {
ClearDocumentDependentSlots(cx);
}
// Take this opportunity to clear mSuspendedDoc. Our old inner window is now
// responsible for unsuspending it.
@@ -5383,9 +5380,7 @@ nsGlobalWindow::GetScreenXY(ErrorResult& aError)
LayoutDeviceRect screenRectDev =
LayoutDevicePixel::FromAppUnits(screenRect, dc->AppUnitsPerDevPixel());
nsCOMPtr<nsIWidget> widget = GetMainWidget();
DesktopToLayoutDeviceScale scale = widget ? widget->GetDesktopToDeviceScale()
: DesktopToLayoutDeviceScale(1.0);
DesktopToLayoutDeviceScale scale = dc->GetDesktopToDeviceScale();
DesktopRect screenRectDesk = screenRectDev / scale;
CSSPoint cssPt =
@@ -6008,9 +6003,7 @@ int32_t
nsGlobalWindow::GetScrollMinX(ErrorResult& aError)
{
MOZ_ASSERT(IsInnerWindow());
int32_t scrollMinX = 0;
FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, scrollMinX);
return scrollMinX;
FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideLeft), aError, 0);
}
NS_IMETHODIMP
@@ -8710,6 +8703,7 @@ void
nsGlobalWindow::ForceClose()
{
MOZ_ASSERT(IsOuterWindow());
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (IsFrame() || !mDocShell) {
// This may be a frame in a frameset, or a window that's already closed.
@@ -8738,6 +8732,12 @@ nsGlobalWindow::FinalClose()
// Flag that we were closed.
mIsClosed = true;
// If we get here from CloseOuter then it means that the parent process is
// going to close our window for us. It's just important to set mIsClosed.
if (XRE_GetProcessType() == GeckoProcessType_Content) {
return;
}
// This stuff is non-sensical but incredibly fragile. The reasons for the
// behavior here don't make sense today and may not have ever made sense,
// but various bits of frontend code break when you change them. If you need
+23 -7
View File
@@ -45,6 +45,7 @@ class nsIDocShell;
class nsDocShell;
class nsDOMNavigationTiming;
class nsFrameLoader;
class nsGlobalWindow;
class nsHTMLCSSStyleSheet;
class nsHTMLDocument;
class nsHTMLStyleSheet;
@@ -354,17 +355,32 @@ public:
}
/**
* Return the base URI for relative URIs in the document (the document uri
* unless it's overridden by SetBaseURI, HTML <base> tags, etc.). The
* returned URI could be null if there is no document URI. If the document
* is a srcdoc document, return the parent document's base URL.
* Return the fallback base URL for this document, as defined in the HTML
* specification. Note that this can return null if there is no document URI.
*
* XXXbz: This doesn't implement the bits for about:blank yet.
*/
nsIURI* GetDocBaseURI() const
nsIURI* GetFallbackBaseURI() const
{
if (mIsSrcdocDocument && mParentDocument) {
return mParentDocument->GetDocBaseURI();
}
return mDocumentBaseURI ? mDocumentBaseURI : mDocumentURI;
return mDocumentURI;
}
/**
* Return the base URI for relative URIs in the document (the document uri
* unless it's overridden by SetBaseURI, HTML <base> tags, etc.). The
* returned URI could be null if there is no document URI. If the document is
* a srcdoc document and has no explicit base URL, return the parent
* document's base URL.
*/
nsIURI* GetDocBaseURI() const
{
if (mDocumentBaseURI) {
return mDocumentBaseURI;
}
return GetFallbackBaseURI();
}
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
@@ -2597,7 +2613,7 @@ public:
JS::Handle<JSObject*> aResult, mozilla::ErrorResult& rv);
// Touch event handlers already on nsINode
already_AddRefed<mozilla::dom::Touch>
CreateTouch(nsIDOMWindow* aView, mozilla::dom::EventTarget* aTarget,
CreateTouch(nsGlobalWindow* aView, mozilla::dom::EventTarget* aTarget,
int32_t aIdentifier, int32_t aPageX, int32_t aPageY,
int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY,
+2 -6
View File
@@ -2542,8 +2542,7 @@ nsObjectLoadingContent::GetCapabilities() const
{
return eSupportImages |
eSupportPlugins |
eSupportDocuments |
eSupportSVG;
eSupportDocuments;
}
void
@@ -2691,10 +2690,7 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
return eType_Document;
}
// SVGs load as documents, but are their own capability
bool isSVG = aMIMEType.LowerCaseEqualsLiteral("image/svg+xml");
Capabilities supportType = isSVG ? eSupportSVG : eSupportDocuments;
if ((caps & supportType) && IsSupportedDocument(aMIMEType)) {
if ((caps & eSupportDocuments) && IsSupportedDocument(aMIMEType)) {
return eType_Document;
}
+2 -3
View File
@@ -287,15 +287,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent
eSupportDocuments = 1u << 2, // Documents are supported
// (nsIDocumentLoaderFactory)
// This flag always includes SVG
eSupportSVG = 1u << 3, // SVG is supported (image/svg+xml)
eSupportClassID = 1u << 4, // The classid attribute is supported
eSupportClassID = 1u << 3, // The classid attribute is supported
// If possible to get a *plugin* type from the type attribute *or* file
// extension, we can use that type and begin loading the plugin before
// opening a channel.
// A side effect of this is if the channel fails, the plugin is still
// running.
eAllowPluginSkipChannel = 1u << 5
eAllowPluginSkipChannel = 1u << 4
};
/**
+21 -4
View File
@@ -124,9 +124,15 @@ nsScreen::GetRect(nsRect& aRect)
}
context->GetRect(aRect);
LayoutDevicePoint screenTopLeftDev =
LayoutDevicePixel::FromAppUnits(aRect.TopLeft(),
context->AppUnitsPerDevPixel());
DesktopPoint screenTopLeftDesk =
screenTopLeftDev / context->GetDesktopToDeviceScale();
aRect.x = NSToIntRound(screenTopLeftDesk.x);
aRect.y = NSToIntRound(screenTopLeftDesk.y);
aRect.x = nsPresContext::AppUnitsToIntCSSPixels(aRect.x);
aRect.y = nsPresContext::AppUnitsToIntCSSPixels(aRect.y);
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height);
aRect.width = nsPresContext::AppUnitsToIntCSSPixels(aRect.width);
@@ -147,10 +153,21 @@ nsScreen::GetAvailRect(nsRect& aRect)
return NS_ERROR_FAILURE;
}
nsRect r;
context->GetRect(r);
LayoutDevicePoint screenTopLeftDev =
LayoutDevicePixel::FromAppUnits(r.TopLeft(),
context->AppUnitsPerDevPixel());
DesktopPoint screenTopLeftDesk =
screenTopLeftDev / context->GetDesktopToDeviceScale();
context->GetClientRect(aRect);
aRect.x = nsPresContext::AppUnitsToIntCSSPixels(aRect.x);
aRect.y = nsPresContext::AppUnitsToIntCSSPixels(aRect.y);
aRect.x = NSToIntRound(screenTopLeftDesk.x) +
nsPresContext::AppUnitsToIntCSSPixels(aRect.x - r.x);
aRect.y = NSToIntRound(screenTopLeftDesk.y) +
nsPresContext::AppUnitsToIntCSSPixels(aRect.y - r.y);
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height);
aRect.width = nsPresContext::AppUnitsToIntCSSPixels(aRect.width);
@@ -47,6 +47,13 @@
(secMan.isSystemPrincipal(message.data) ? "OK" : "KO"));
});
addMessageListener("test:ep", function(message) {
sendAsyncMessage("test:result", "expanded principal: " +
(message.data.isExpandedPrincipal ? "OK" : "KO"));
sendAsyncMessage("test:result", "correct origin: " +
(message.data.origin == "[Expanded Principal [http://bar.example.com, http://foo.example.com]]" ? "OK" : "KO"));
});
addMessageListener("test:null", function(message) {
sendAsyncMessage("test:result", "is nsIPrincipal: " +
(message.data instanceof Ci.nsIPrincipal ? "OK" : "KO"));
@@ -65,6 +72,9 @@
iframe.id = "iframe";
iframe.src = childFrameURL;
let sb = new Cu.Sandbox(['http://foo.example.com', 'http://bar.example.com']);
let ep = Components.utils.getObjectPrincipal(sb);
iframe.addEventListener("mozbrowserloadend", function() {
ok(true, "Got iframe load event.");
@@ -92,6 +102,8 @@
createInstance(Ci.nsIPrincipal);
mm.sendAsyncMessage("test:system", system);
mm.sendAsyncMessage("test:ep", ep);
let nullP = Cc["@mozilla.org/nullprincipal;1"].
createInstance(Ci.nsIPrincipal);
mm.sendAsyncMessage("test:null", nullP);
+1 -2
View File
@@ -3239,8 +3239,7 @@ UnprivilegedJunkScopeOrWorkerGlobal()
return xpc::UnprivilegedJunkScope();
}
return workers::GetCurrentThreadWorkerPrivate()->
GlobalScope()->GetGlobalJSObject();
return workers::GetCurrentThreadWorkerGlobal();
}
} // namespace binding_detail
+10
View File
@@ -131,6 +131,16 @@ InternalResponse::GetTainting() const
}
}
already_AddRefed<InternalResponse>
InternalResponse::Unfiltered()
{
RefPtr<InternalResponse> ref = mWrappedResponse;
if (!ref) {
ref = this;
}
return ref.forget();
}
already_AddRefed<InternalResponse>
InternalResponse::OpaqueResponse()
{
+3
View File
@@ -221,6 +221,9 @@ public:
LoadTainting
GetTainting() const;
already_AddRefed<InternalResponse>
Unfiltered();
private:
~InternalResponse();
+14
View File
@@ -238,6 +238,20 @@ Response::Clone(ErrorResult& aRv) const
return response.forget();
}
already_AddRefed<Response>
Response::CloneUnfiltered(ErrorResult& aRv) const
{
if (BodyUsed()) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
return nullptr;
}
RefPtr<InternalResponse> clone = mInternalResponse->Clone();
RefPtr<InternalResponse> ir = clone->Unfiltered();
RefPtr<Response> ref = new Response(mOwner, ir);
return ref.forget();
}
void
Response::SetBody(nsIInputStream* aBody)
{
+3
View File
@@ -124,6 +124,9 @@ public:
already_AddRefed<Response>
Clone(ErrorResult& aRv) const;
already_AddRefed<Response>
CloneUnfiltered(ErrorResult& aRv) const;
void
SetBody(nsIInputStream* aBody);
+91 -37
View File
@@ -31,6 +31,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/Event.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/SettingChangeNotificationBinding.h"
#include "mozilla/dom/WakeLock.h"
@@ -58,6 +59,7 @@ class nsIPrincipal;
#ifdef XP_WIN
#include "WindowsLocationProvider.h"
#include "mozilla/WindowsVersion.h"
#endif
// Some limit to the number of get or watch geolocation requests
@@ -74,13 +76,12 @@ using namespace mozilla::hal;
class nsGeolocationRequest final
: public nsIContentPermissionRequest
, public nsITimerCallback
, public nsIGeolocationUpdate
, public SupportsWeakPtr<nsGeolocationRequest>
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIGEOLOCATIONUPDATE
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGeolocationRequest, nsIContentPermissionRequest)
@@ -92,6 +93,9 @@ class nsGeolocationRequest final
uint8_t aProtocolType,
bool aWatchPositionRequest = false,
int32_t aWatchId = 0);
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsGeolocationRequest)
void Shutdown();
void SendLocation(nsIDOMGeoPosition* aLocation);
@@ -106,6 +110,23 @@ class nsGeolocationRequest final
private:
virtual ~nsGeolocationRequest();
class TimerCallbackHolder final : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
explicit TimerCallbackHolder(nsGeolocationRequest* aRequest)
: mRequest(aRequest)
{}
private:
~TimerCallbackHolder() {}
WeakPtr<nsGeolocationRequest> mRequest;
};
void Notify();
already_AddRefed<nsIDOMGeoPosition> AdjustedLocation(nsIDOMGeoPosition*);
bool mIsWatchPositionRequest;
@@ -378,12 +399,12 @@ nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
nsGeolocationRequest::~nsGeolocationRequest()
{
StopTimeoutTimer();
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGeolocationRequest)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequest)
NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIGeolocationUpdate)
NS_INTERFACE_MAP_END
@@ -392,12 +413,11 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGeolocationRequest)
NS_IMPL_CYCLE_COLLECTION(nsGeolocationRequest, mCallback, mErrorCallback, mLocator)
NS_IMETHODIMP
nsGeolocationRequest::Notify(nsITimer* aTimer)
void
nsGeolocationRequest::Notify()
{
StopTimeoutTimer();
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
return NS_OK;
}
void
@@ -509,6 +529,12 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
// getCurrentPosition requests serviced by the cache
// will now be owned by the RequestSendLocationEvent
Update(lastPosition.position);
// After Update is called, getCurrentPosition finishes it's job.
if (!mIsWatchPositionRequest) {
return NS_OK;
}
} else {
// if it is not a watch request and timeout is 0,
// invoke the errorCallback (if present) with TIMEOUT code
@@ -517,14 +543,15 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
return NS_OK;
}
// Kick off the geo device, if it isn't already running
nsresult rv = gs->StartDevice(GetPrincipal());
}
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
// Kick off the geo device, if it isn't already running
nsresult rv = gs->StartDevice(GetPrincipal());
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
if (mLocator->ContainsRequest(this)) {
@@ -567,7 +594,8 @@ nsGeolocationRequest::SetTimeoutTimer()
}
mTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1");
mTimeoutTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
RefPtr<TimerCallbackHolder> holder = new TimerCallbackHolder(this);
mTimeoutTimer->InitWithCallback(holder, timeout, nsITimer::TYPE_ONE_SHOT);
}
}
@@ -747,10 +775,7 @@ nsGeolocationRequest::Shutdown()
MOZ_ASSERT(!mShutdown, "request shutdown twice");
mShutdown = true;
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
StopTimeoutTimer();
// If there are no other high accuracy requests, the geolocation service will
// notify the provider to switch to the default accuracy.
@@ -762,6 +787,23 @@ nsGeolocationRequest::Shutdown()
}
}
////////////////////////////////////////////////////
// nsGeolocationRequest::TimerCallbackHolder
////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS(nsGeolocationRequest::TimerCallbackHolder, nsISupports, nsITimerCallback)
NS_IMETHODIMP
nsGeolocationRequest::TimerCallbackHolder::Notify(nsITimer*)
{
if (mRequest) {
mRequest->Notify();
}
return NS_OK;
}
////////////////////////////////////////////////////
// nsGeolocationService
////////////////////////////////////////////////////
@@ -840,7 +882,7 @@ nsresult nsGeolocationService::Init()
return NS_ERROR_FAILURE;
}
obs->AddObserver(this, "quit-application", false);
obs->AddObserver(this, "xpcom-shutdown", false);
obs->AddObserver(this, "mozsettings-changed", false);
#ifdef MOZ_ENABLE_QT5GEOPOSITION
@@ -867,7 +909,8 @@ nsresult nsGeolocationService::Init()
#endif
#ifdef XP_WIN
if (Preferences::GetBool("geo.provider.ms-windows-location", false)) {
if (Preferences::GetBool("geo.provider.ms-windows-location", false) &&
IsWin8OrLater()) {
mProvider = new WindowsLocationProvider();
}
#endif
@@ -947,10 +990,10 @@ nsGeolocationService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp("quit-application", aTopic)) {
if (!strcmp("xpcom-shutdown", aTopic)) {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, "quit-application");
obs->RemoveObserver(this, "xpcom-shutdown");
obs->RemoveObserver(this, "mozsettings-changed");
}
@@ -987,7 +1030,9 @@ nsGeolocationService::Observe(nsISupports* aSubject,
NS_IMETHODIMP
nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
{
SetCachedPosition(aSomewhere);
if (aSomewhere) {
SetCachedPosition(aSomewhere);
}
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
mGeolocators[i]->Update(aSomewhere);
@@ -1247,7 +1292,8 @@ Geolocation::Init(nsIDOMWindow* aContentDom)
mPrincipal = doc->NodePrincipal();
if (XRE_IsContentProcess()) {
if (Preferences::GetBool("dom.wakelock.enabled") &&
XRE_IsContentProcess()) {
doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
/* listener */ this,
/* use capture */ true,
@@ -1258,19 +1304,21 @@ Geolocation::Init(nsIDOMWindow* aContentDom)
nsresult rv = mPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
bool isHttp;
rv = uri->SchemeIs("http", &isHttp);
NS_ENSURE_SUCCESS(rv, rv);
if (uri) {
bool isHttp;
rv = uri->SchemeIs("http", &isHttp);
NS_ENSURE_SUCCESS(rv, rv);
bool isHttps;
rv = uri->SchemeIs("https", &isHttps);
NS_ENSURE_SUCCESS(rv, rv);
bool isHttps;
rv = uri->SchemeIs("https", &isHttps);
NS_ENSURE_SUCCESS(rv, rv);
// Store the protocol to send via telemetry later.
if (isHttp) {
mProtocolType = ProtocolType::HTTP;
} else if (isHttps) {
mProtocolType = ProtocolType::HTTPS;
// Store the protocol to send via telemetry later.
if (isHttp) {
mProtocolType = ProtocolType::HTTP;
} else if (isHttps) {
mProtocolType = ProtocolType::HTTPS;
}
}
}
@@ -1325,6 +1373,11 @@ Geolocation::HandleEvent(nsIDOMEvent* aEvent)
}
} else {
mService->SetDisconnectTimer();
// We will unconditionally allow all the requests in the callbacks
// because if a request is put into either of these two callbacks,
// it means that it has been allowed before.
// That's why when we resume them, we unconditionally allow them again.
for (uint32_t i = 0, length = mWatchingCallbacks.Length(); i < length; ++i) {
mWatchingCallbacks[i]->Allow(JS::UndefinedHandleValue);
}
@@ -1343,7 +1396,8 @@ Geolocation::Shutdown()
mPendingCallbacks.Clear();
mWatchingCallbacks.Clear();
if (XRE_IsContentProcess()) {
if (Preferences::GetBool("dom.wakelock.enabled") &&
XRE_IsContentProcess()) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
if (window) {
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
@@ -1585,7 +1639,7 @@ Geolocation::WatchPosition(PositionCallback& aCallback,
const PositionOptions& aOptions,
ErrorResult& aRv)
{
int32_t ret;
int32_t ret = 0;
GeoPositionCallback successCallback(&aCallback);
GeoPositionErrorCallback errorCallback(aErrorCallback);
+1 -1
View File
@@ -172,7 +172,7 @@ HTMLMetaElement::CreateAndDispatchEvent(nsIDocument* aDoc,
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, aEventName, true, true);
asyncDispatcher->PostDOMEvent();
asyncDispatcher->RunDOMEventWhenSafe();
}
JSObject*
+3 -2
View File
@@ -164,14 +164,15 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
return;
}
// Resolve the <base> element's href relative to our document URI
// Resolve the <base> element's href relative to our document's
// fallback base URI.
nsAutoString href;
child->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
nsCOMPtr<nsIURI> newBaseURI;
nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(newBaseURI), href, aDocument,
aDocument->GetDocumentURI());
aDocument->GetFallbackBaseURI());
// Try to set our base URI. If that fails, try to set base URI to null
nsresult rv = aDocument->SetBaseURI(newBaseURI);
+1 -1
View File
@@ -343,7 +343,7 @@ HTMLSharedObjectElement::GetCapabilities() const
{
uint32_t capabilities = eSupportPlugins | eAllowPluginSkipChannel;
if (mNodeInfo->Equals(nsGkAtoms::embed)) {
capabilities |= eSupportSVG | eSupportImages | eSupportDocuments;
capabilities |= eSupportImages | eSupportDocuments;
}
return capabilities;
+19 -12
View File
@@ -74,7 +74,6 @@ HTMLSourceElement::WouldMatchMediaForDocument(const nsAString& aMedia,
nsIPresShell* presShell = aDocument->GetShell();
nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
MOZ_ASSERT(pctx, "Called for document with no prescontext");
nsCSSParser cssParser;
RefPtr<nsMediaList> mediaList = new nsMediaList();
@@ -83,6 +82,20 @@ HTMLSourceElement::WouldMatchMediaForDocument(const nsAString& aMedia,
return pctx && mediaList->Matches(pctx, nullptr);
}
void
HTMLSourceElement::UpdateMediaList(const nsAttrValue* aValue)
{
mMediaList = nullptr;
nsString mediaStr;
if (!aValue || (mediaStr = aValue->GetStringValue()).IsEmpty()) {
return;
}
nsCSSParser cssParser;
mMediaList = new nsMediaList();
cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false);
}
nsresult
HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
@@ -106,23 +119,17 @@ HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
img->PictureSourceSrcsetChanged(AsContent(), strVal, aNotify);
} else if (aName == nsGkAtoms::sizes) {
img->PictureSourceSizesChanged(AsContent(), strVal, aNotify);
} else if (aName == nsGkAtoms::media ||
aName == nsGkAtoms::type) {
} else if (aName == nsGkAtoms::media) {
UpdateMediaList(aValue);
img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify);
} else if (aName == nsGkAtoms::type) {
img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify);
}
}
}
} else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::media) {
mMediaList = nullptr;
if (aValue) {
nsString mediaStr = aValue->GetStringValue();
if (!mediaStr.IsEmpty()) {
nsCSSParser cssParser;
mMediaList = new nsMediaList();
cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false);
}
}
UpdateMediaList(aValue);
} else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
mSrcMediaSource = nullptr;
if (aValue) {
+4
View File
@@ -13,6 +13,7 @@
#include "mozilla/dom/HTMLMediaElement.h"
class nsMediaList;
class nsAttrValue;
namespace mozilla {
namespace dom {
@@ -118,6 +119,9 @@ protected:
private:
RefPtr<nsMediaList> mMediaList;
RefPtr<MediaSource> mSrcMediaSource;
// Generates a new nsMediaList using the given input
void UpdateMediaList(const nsAttrValue* aValue);
};
} // namespace dom
+1 -3
View File
@@ -388,9 +388,7 @@ HTMLTableCellElement::ParseAttribute(int32_t aNamespaceID,
if (res) {
int32_t val = aResult.GetIntegerValue();
// reset large colspan values as IE and opera do
// quirks mode does not honor the special html 4 value of 0
if (val > MAX_COLSPAN || val < 0 ||
(0 == val && InNavQuirksMode(OwnerDoc()))) {
if (val > MAX_COLSPAN || val <= 0) {
aResult.SetTo(1, &aValue);
}
}
+32 -13
View File
@@ -416,8 +416,12 @@ ImageDocument::RestoreImage()
imageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::width, true);
imageContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::height, true);
if (mImageIsOverflowing) {
SetModeClass(eOverflowing);
if (ImageIsOverflowing()) {
if (!mImageIsOverflowingVertically) {
SetModeClass(eOverflowingHorizontalOnly);
} else {
SetModeClass(eOverflowingVertical);
}
}
else {
SetModeClass(eNone);
@@ -444,7 +448,7 @@ ImageDocument::ToggleImageSize()
ResetZoomLevel();
RestoreImage();
}
else if (mImageIsOverflowing) {
else if (ImageIsOverflowing()) {
ResetZoomLevel();
ShrinkToFit();
}
@@ -509,10 +513,16 @@ ImageDocument::SetModeClass(eModeClasses mode)
classList->Remove(NS_LITERAL_STRING("shrinkToFit"), rv);
}
if (mode == eOverflowing) {
classList->Add(NS_LITERAL_STRING("overflowing"), rv);
if (mode == eOverflowingVertical) {
classList->Add(NS_LITERAL_STRING("overflowingVertical"), rv);
} else {
classList->Remove(NS_LITERAL_STRING("overflowing"), rv);
classList->Remove(NS_LITERAL_STRING("overflowingVertical"), rv);
}
if (mode == eOverflowingHorizontalOnly) {
classList->Add(NS_LITERAL_STRING("overflowingHorizontalOnly"), rv);
} else {
classList->Remove(NS_LITERAL_STRING("overflowingHorizontalOnly"), rv);
}
}
@@ -582,7 +592,7 @@ ImageDocument::HandleEvent(nsIDOMEvent* aEvent)
mShouldResize = false;
RestoreImageTo(x, y);
}
else if (mImageIsOverflowing) {
else if (ImageIsOverflowing()) {
ShrinkToFit();
}
} else if (eventType.EqualsLiteral("load")) {
@@ -703,18 +713,27 @@ ImageDocument::CheckOverflowing(bool changeState)
mVisibleHeight = nsPresContext::AppUnitsToFloatCSSPixels(visibleArea.height);
}
bool imageWasOverflowing = mImageIsOverflowing;
mImageIsOverflowing =
mImageWidth > mVisibleWidth || mImageHeight > mVisibleHeight;
bool windowBecameBigEnough = imageWasOverflowing && !mImageIsOverflowing;
bool imageWasOverflowing = ImageIsOverflowing();
bool imageWasOverflowingVertically = mImageIsOverflowingVertically;
mImageIsOverflowingHorizontally = mImageWidth > mVisibleWidth;
mImageIsOverflowingVertically = mImageHeight > mVisibleHeight;
bool windowBecameBigEnough = imageWasOverflowing && !ImageIsOverflowing();
bool verticalOverflowChanged =
mImageIsOverflowingVertically != imageWasOverflowingVertically;
if (changeState || mShouldResize || mFirstResize ||
windowBecameBigEnough) {
if (mImageIsOverflowing && (changeState || mShouldResize)) {
windowBecameBigEnough || verticalOverflowChanged) {
if (ImageIsOverflowing() && (changeState || mShouldResize)) {
ShrinkToFit();
}
else if (mImageIsResized || mFirstResize || windowBecameBigEnough) {
RestoreImage();
} else if (!mImageIsResized && verticalOverflowChanged) {
if (mImageIsOverflowingVertically) {
SetModeClass(eOverflowingVertical);
} else {
SetModeClass(eOverflowingHorizontalOnly);
}
}
}
mFirstResize = false;
+5 -3
View File
@@ -62,7 +62,7 @@ public:
}
bool ImageIsOverflowing() const
{
return mImageIsOverflowing;
return mImageIsOverflowingHorizontally || mImageIsOverflowingVertically;
}
bool ImageIsResized() const
{
@@ -101,7 +101,8 @@ protected:
enum eModeClasses {
eNone,
eShrinkToFit,
eOverflowing
eOverflowingVertical, // And maybe horizontal too.
eOverflowingHorizontalOnly
};
void SetModeClass(eModeClasses mode);
@@ -121,7 +122,8 @@ protected:
bool mResizeImageByDefault;
bool mClickResizingEnabled;
bool mImageIsOverflowing;
bool mImageIsOverflowingHorizontally;
bool mImageIsOverflowingVertically;
// mImageIsResized is true if the image is currently resized
bool mImageIsResized;
// mShouldResize is true if the image should be resized when it doesn't fit
+47 -2
View File
@@ -88,8 +88,53 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=369370
is(kidDoc.body.scrollLeft, 0, "Checking scrollLeft");
is(kidDoc.body.scrollTop, 0, "Checking scrollTop");
kidWin.close();
SimpleTest.finish();
// ========== test 5 ==========
// Click in the upper left to zoom in again
event = makeClickFor(25, 25);
img.dispatchEvent(event);
ok(true, "----- click 5 -----");
is(img.width, 800, "image width");
is(img.height, 600, "image height");
is(kidDoc.body.scrollLeft, 0, "Checking scrollLeft");
is(kidDoc.body.scrollTop, 0, "Checking scrollTop");
is(img.getBoundingClientRect().top, 0, "Image is in view vertically");
// ========== test 6 ==========
// Now try resizing the window so the image fits vertically.
function test6() {
kidWin.addEventListener("resize", function resizeListener() {
kidWin.removeEventListener("resize", resizeListener);
// Give the image document time to respond
SimpleTest.executeSoon(function() {
is(img.height, 600, "image height");
is(img.getBoundingClientRect().top, 25, "Image is vertically centered");
test7();
});
});
var decorationSize = kidWin.outerHeight - kidWin.innerHeight;
kidWin.resizeTo(400, 600 + 50 + decorationSize);
}
// ========== test 7 ==========
// Now try resizing the window so the image no longer fits vertically.
function test7() {
kidWin.addEventListener("resize", function resizeListener() {
kidWin.removeEventListener("resize", resizeListener);
// Give the image document time to respond
SimpleTest.executeSoon(function() {
is(img.height, 600, "image height");
is(img.getBoundingClientRect().top, 0, "Image is at top again");
kidWin.close();
SimpleTest.finish();
});
});
var decorationSize = kidWin.outerHeight - kidWin.innerHeight;
kidWin.resizeTo(400, 300 + decorationSize);
}
test6();
}
var kidWin;
var kidDoc;
@@ -9,4 +9,4 @@ ImageMapPolyWrongNumberOfCoords=The "coords" attribute of the <area shape="poly"
ImageMapPolyOddNumberOfCoords=The "coords" attribute of the <area shape="poly"> tag is missing the last "y" coordinate (the correct format is "x1,y1,x2,y2 …").
TablePartRelPosWarning=Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature having no effect.
ScrollLinkedEffectFound=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developers.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!
ScrollLinkedEffectFound2=This site appears to use a scroll-linked positioning effect. This may not work well with asynchronous panning; see https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects for further details and to join the discussion on related tools and features!
+65 -80
View File
@@ -10,9 +10,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
const PAYMENTCONTENTHELPER_CID =
Components.ID("{a920adc0-c36e-4fd0-8de0-aac1ac6ebbd0}");
const PAYMENT_IPC_MSG_NAMES = ["Payment:Success",
"Payment:Failed"];
@@ -22,39 +19,82 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
function PaymentContentHelper() {
var _debug;
try {
_debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
_debug = false;
}
function LOG(s) {
if (!_debug) {
return;
}
dump("-*- PaymentContentHelper: " + s + "\n");
}
function PaymentContentHelper(aWindow) {
this.initDOMRequestHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
};
PaymentContentHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavigatorPayment,
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
classID: PAYMENTCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({
classID: PAYMENTCONTENTHELPER_CID,
contractID: "@mozilla.org/payment/content-helper;1",
classDescription: "Payment Content Helper",
flags: Ci.nsIClassInfo.DOM_OBJECT,
interfaces: [Ci.nsINavigatorPayment]
}),
receiveMessage: function receiveMessage(aMessage) {
let name = aMessage.name;
let msg = aMessage.json;
if (_debug) {
LOG("Received message '" + name + "': " + JSON.stringify(msg));
}
let requestId = msg.requestId;
let request = this.takeRequest(requestId);
if (!request) {
return;
}
switch (name) {
case "Payment:Success":
Services.DOMRequest.fireSuccess(request, msg.result);
break;
case "Payment:Failed":
Services.DOMRequest.fireError(request, msg.errorMsg);
break;
}
},
};
function PaymentContentHelperService() {
};
PaymentContentHelperService.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentContentHelperService]),
classID: Components.ID("{80035846-6732-4fcc-961b-f336b65218f4}"),
contractID: "@mozilla.org/payment/content-helper-service;1",
_xpcom_factory: XPCOMUtils.generateSingletonFactory(PaymentContentHelperService),
// keys are windows and values are PaymentContentHelpers
helpers: new WeakMap(),
// nsINavigatorPayment
pay: function pay(aWindow, aJwts) {
let requestHelper = this.helpers.get(aWindow);
if (!requestHelper) {
requestHelper = new PaymentContentHelper(aWindow);
this.helpers.set(aWindow, requestHelper);
}
let request = requestHelper.createRequest();
let requestId = requestHelper.getRequestId(request);
pay: function pay(aJwts) {
let request = this.createRequest();
let requestId = this.getRequestId(request);
let docShell = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isActive) {
if (this._debug) {
this.LOG("The caller application is a background app. No request " +
"will be sent");
if (_debug) {
LOG("The caller application is a background app. No request will be " +
"sent");
}
let runnable = {
run: function run() {
Services.DOMRequest.fireError(request, "BACKGROUND_APP");
@@ -75,61 +115,6 @@ PaymentContentHelper.prototype = {
});
return request;
},
// nsIDOMGlobalPropertyInitializer
init: function(aWindow) {
try {
if (!Services.prefs.getBoolPref("dom.mozPay.enabled")) {
return null;
}
} catch (e) {
return null;
}
this._window = aWindow;
this.initDOMRequestHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
try {
this._debug =
Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
&& Services.prefs.getBoolPref(PREF_DEBUG);
} catch(e) {
this._debug = false;
}
return Cu.exportFunction(this.pay.bind(this), aWindow);
},
// nsIFrameMessageListener
receiveMessage: function receiveMessage(aMessage) {
let name = aMessage.name;
let msg = aMessage.json;
if (this._debug) {
this.LOG("Received message '" + name + "': " + JSON.stringify(msg));
}
let requestId = msg.requestId;
let request = this.takeRequest(requestId);
if (!request) {
return;
}
switch (name) {
case "Payment:Success":
Services.DOMRequest.fireSuccess(request, msg.result);
break;
case "Payment:Failed":
Services.DOMRequest.fireError(request, msg.errorMsg);
break;
}
},
LOG: function LOG(s) {
if (!this._debug) {
return;
}
dump("-*- PaymentContentHelper: " + s + "\n");
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentContentHelper]);
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentContentHelperService]);
+2 -3
View File
@@ -1,6 +1,5 @@
component {a920adc0-c36e-4fd0-8de0-aac1ac6ebbd0} Payment.js
contract @mozilla.org/payment/content-helper;1 {a920adc0-c36e-4fd0-8de0-aac1ac6ebbd0}
category JavaScript-navigator-property mozPay @mozilla.org/payment/content-helper;1
component {80035846-6732-4fcc-961b-f336b65218f4} Payment.js
contract @mozilla.org/payment/content-helper-service;1 {80035846-6732-4fcc-961b-f336b65218f4}
component {b8bce4e7-fbf0-4719-a634-b1bf9018657c} PaymentFlowInfo.js
contract @mozilla.org/payment/flow-info;1 {b8bce4e7-fbf0-4719-a634-b1bf9018657c}
+1 -1
View File
@@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsINavigatorPayment.idl',
'nsIPaymentContentHelperService.idl',
'nsIPaymentFlowInfo.idl',
'nsIPaymentProviderStrategy.idl',
'nsIPaymentUIGlue.idl',
@@ -5,13 +5,14 @@
#include "domstubs.idl"
interface nsIDOMDOMRequest;
interface mozIDOMWindow;
[scriptable, uuid(44fb7308-7d7b-4975-8a27-e01fe9623bdb)]
interface nsINavigatorPayment : nsISupports
[scriptable, uuid(80035846-6732-4fcc-961b-f336b65218f4)]
interface nsIPaymentContentHelperService : nsISupports
{
// The 'jwts' parameter can be either a single DOMString or an array of
// DOMStrings. In both cases, it represents the base64url encoded and
// digitally signed payment information. Each payment provider should
// define its supported JWT format.
nsIDOMDOMRequest pay(in jsval jwts);
nsIDOMDOMRequest pay(in mozIDOMWindow window, in jsval jwts);
};
@@ -0,0 +1,91 @@
/* 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/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cm = Components.manager;
const Cu = Components.utils;
const CONTRACT_ID = "@mozilla.org/payment/ui-glue;1";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
var oldClassID, oldFactory;
var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
var newFactory = {
createInstance: function(aOuter, aIID) {
if (aOuter) {
throw Components.results.NS_ERROR_NO_AGGREGATION;
}
return new MockPaymentsUIGlueInstance().QueryInterface(aIID);
},
lockFactory: function(aLock) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
};
addMessageListener("MockPaymentsUIGlue.init", function (message) {
try {
oldClassID = registrar.contractIDToCID(CONTRACT_ID);
oldFactory = Cm.getClassObject(oldClassID, Ci.nsIFactory);
} catch (ex) {
oldClassID = "";
oldFactory = null;
dump("TEST-INFO | can't get payments ui glue registered component, " +
"assuming there is none\n");
}
if (oldFactory) {
registrar.unregisterFactory(oldClassID, oldFactory);
}
registrar.registerFactory(newClassID, "", CONTRACT_ID, newFactory);});
addMessageListener("MockPaymentsUIGlue.cleanup", function (message) {
if (oldClassID) {
registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
}
});
var payments = new Map();
function MockPaymentsUIGlueInstance() {
};
MockPaymentsUIGlueInstance.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue]),
confirmPaymentRequest: function(aRequestId,
aRequests,
aSuccessCb,
aErrorCb) {
aSuccessCb.onresult(aRequestId, aRequests[0].type);
},
showPaymentFlow: function(aRequestId,
aPaymentFlowInfo,
aErrorCb) {
let win = Services.ww.openWindow(null,
null,
"_blank",
"chrome,dialog=no,resizable,scrollbars,centerscreen",
null);
payments.set(aRequestId, win);
let docshell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
docshell.paymentRequestId = aRequestId;
win.document.location = aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt;
},
closePaymentFlow: function(aRequestId) {
payments.get(aRequestId).close();
payments.delete(aRequestId);
return Promise.resolve();
},
};
+2 -3
View File
@@ -1,12 +1,11 @@
[DEFAULT]
skip-if=true # This test uses MockPaymentsUIGlue which uses __exposedProps__
# we need to move this to a chrome test, but these are not
# available in b2g or android for now.
skip-if=buildapp != 'b2g' && toolkit != 'android'
support-files=
file_mozpayproviderchecker.html
file_payprovidersuccess.html
file_payproviderfailure.html
MockPaymentsUIChromeScript.js
[test_mozpaymentprovider.html]
[test_mozpay_callbacks.html]
@@ -79,7 +79,11 @@ function runTest() {
tests.shift()();
}
SpecialPowers.MockPaymentsUIGlue.init(window);
const uiGlue = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('MockPaymentsUIChromeScript.js'));
SimpleTest.registerCleanupFunction(() => {
uiGlue.sendAsyncMessage("MockPaymentsUIGlue.cleanup", {});
});
uiGlue.sendAsyncMessage("MockPaymentsUIGlue.init", {});
SpecialPowers.pushPrefEnv({
"set": [
@@ -88,13 +92,13 @@ SpecialPowers.pushPrefEnv({
["dom.payment.provider.1.name", "SuccessProvider"],
["dom.payment.provider.1.description", ""],
["dom.payment.provider.1.uri",
"http://mochi.test:8888/tests/dom/payment/tests/mochitest/file_payprovidersuccess.html?req="],
"https://example.com:443/tests/dom/payment/tests/mochitest/file_payprovidersuccess.html?req="],
["dom.payment.provider.1.type", "mozilla/payments/test/success"],
["dom.payment.provider.1.requestMethod", "GET"],
["dom.payment.provider.2.name", "FailureProvider"],
["dom.payment.provider.2.description", ""],
["dom.payment.provider.2.uri",
"http://mochi.test:8888/tests/dom/payment/tests/mochitest/file_payproviderfailure.html?req="],
"https://example.com:443/tests/dom/payment/tests/mochitest/file_payproviderfailure.html?req="],
["dom.payment.provider.2.type", "mozilla/payments/test/failure"],
["dom.payment.provider.2.requestMethod", "GET"],
]
+108 -10
View File
@@ -7,16 +7,59 @@
#include "WindowsLocationProvider.h"
#include "nsGeoPosition.h"
#include "nsIDOMGeoPositionError.h"
#include "nsComponentManagerUtils.h"
#include "prtime.h"
#include "MLSFallback.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(WindowsLocationProvider::MLSUpdate, nsIGeolocationUpdate);
WindowsLocationProvider::MLSUpdate::MLSUpdate(nsIGeolocationUpdate* aCallback)
: mCallback(aCallback)
{
}
NS_IMETHODIMP
WindowsLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *aPosition)
{
if (!mCallback) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
aPosition->GetCoords(getter_AddRefs(coords));
if (!coords) {
return NS_ERROR_FAILURE;
}
// TODO add telemetry here to track volume of MLS vs native geo responses
return mCallback->Update(aPosition);
}
NS_IMETHODIMP
WindowsLocationProvider::MLSUpdate::LocationUpdatePending()
{
return NS_OK;
}
NS_IMETHODIMP
WindowsLocationProvider::MLSUpdate::NotifyError(uint16_t aError)
{
if (!mCallback) {
return NS_ERROR_FAILURE;
}
return mCallback->NotifyError(aError);
}
class LocationEvent final : public ILocationEvents
{
public:
LocationEvent(nsIGeolocationUpdate* aCallback)
: mCallback(aCallback), mCount(0) {
LocationEvent(nsIGeolocationUpdate* aCallback, WindowsLocationProvider *aProvider)
: mCallback(aCallback), mProvider(aProvider), mCount(0) {
}
// IUnknown interface
@@ -32,6 +75,7 @@ public:
private:
nsCOMPtr<nsIGeolocationUpdate> mCallback;
RefPtr<WindowsLocationProvider> mProvider;
ULONG mCount;
};
@@ -75,18 +119,34 @@ LocationEvent::OnStatusChanged(REFIID aReportType,
return S_OK;
}
// When registering event, REPORT_INITIALIZING is fired at first.
// Then, when the location is found, REPORT_RUNNING is fired.
if (aStatus == REPORT_RUNNING) {
// location is found by Windows Location provider, we use it.
mProvider->CancelMLSProvider();
return S_OK;
}
// Cannot get current location at this time. We use MLS instead until
// Location API returns RUNNING status.
if (NS_SUCCEEDED(mProvider->CreateAndWatchMLSProvider(mCallback))) {
return S_OK;
}
// Cannot watch location by MLS provider. We must return error by
// Location API.
uint16_t err;
switch (aStatus) {
case REPORT_ACCESS_DENIED:
err = nsIDOMGeoPositionError::PERMISSION_DENIED;
break;
case REPORT_NOT_SUPPORTED:
case REPORT_ERROR:
err = nsIDOMGeoPositionError::POSITION_UNAVAILABLE;
break;
default:
return S_OK;
}
mCallback->NotifyError(err);
return S_OK;
}
@@ -134,6 +194,10 @@ WindowsLocationProvider::WindowsLocationProvider()
{
}
WindowsLocationProvider::~WindowsLocationProvider()
{
}
NS_IMETHODIMP
WindowsLocationProvider::Startup()
{
@@ -141,12 +205,14 @@ WindowsLocationProvider::Startup()
if (FAILED(::CoCreateInstance(CLSID_Location, nullptr, CLSCTX_INPROC_SERVER,
IID_ILocation,
getter_AddRefs(location)))) {
return NS_ERROR_FAILURE;
// We will use MLS provider
return NS_OK;
}
IID reportTypes[] = { IID_ILatLongReport };
if (FAILED(location->RequestPermissions(nullptr, reportTypes, 1, FALSE))) {
return NS_ERROR_FAILURE;
// We will use MLS provider
return NS_OK;
}
mLocation = location;
@@ -156,11 +222,17 @@ WindowsLocationProvider::Startup()
NS_IMETHODIMP
WindowsLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
RefPtr<LocationEvent> event = new LocationEvent(aCallback);
if (FAILED(mLocation->RegisterForReport(event, IID_ILatLongReport, 0))) {
return NS_ERROR_FAILURE;
if (mLocation) {
RefPtr<LocationEvent> event = new LocationEvent(aCallback, this);
if (SUCCEEDED(mLocation->RegisterForReport(event, IID_ILatLongReport, 0))) {
return NS_OK;
}
}
return NS_OK;
// Cannot use Location API. We will use MLS instead.
mLocation = nullptr;
return CreateAndWatchMLSProvider(aCallback);
}
NS_IMETHODIMP
@@ -171,6 +243,8 @@ WindowsLocationProvider::Shutdown()
mLocation = nullptr;
}
CancelMLSProvider();
return NS_OK;
}
@@ -178,7 +252,8 @@ NS_IMETHODIMP
WindowsLocationProvider::SetHighAccuracy(bool enable)
{
if (!mLocation) {
return NS_ERROR_FAILURE;
// MLS provider doesn't support HighAccuracy
return NS_OK;
}
LOCATION_DESIRED_ACCURACY desiredAccuracy;
@@ -194,5 +269,28 @@ WindowsLocationProvider::SetHighAccuracy(bool enable)
return NS_OK;
}
nsresult
WindowsLocationProvider::CreateAndWatchMLSProvider(
nsIGeolocationUpdate* aCallback)
{
if (mMLSProvider) {
return NS_OK;
}
mMLSProvider = new MLSFallback();
return mMLSProvider->Startup(new MLSUpdate(aCallback));
}
void
WindowsLocationProvider::CancelMLSProvider()
{
if (!mMLSProvider) {
return;
}
mMLSProvider->Shutdown();
mMLSProvider = nullptr;
}
} // namespace dom
} // namespace mozilla
+18 -1
View File
@@ -12,6 +12,8 @@
#include <locationapi.h>
class MLSFallback;
namespace mozilla {
namespace dom {
@@ -23,10 +25,25 @@ public:
WindowsLocationProvider();
nsresult CreateAndWatchMLSProvider(nsIGeolocationUpdate* aCallback);
void CancelMLSProvider();
class MLSUpdate : public nsIGeolocationUpdate
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
explicit MLSUpdate(nsIGeolocationUpdate* aCallback);
private:
nsCOMPtr<nsIGeolocationUpdate> mCallback;
virtual ~MLSUpdate() {}
};
private:
~WindowsLocationProvider() {}
~WindowsLocationProvider();
RefPtr<ILocation> mLocation;
RefPtr<MLSFallback> mMLSProvider;
};
} // namespace dom
+4
View File
@@ -9,6 +9,10 @@ SOURCES += [
'WindowsLocationProvider.cpp'
]
LOCAL_INCLUDES += [
'/dom/geolocation'
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
+2
View File
@@ -7,6 +7,7 @@ support-files =
test-console-api.html
test_bug1004814.html
worker_bug1004814.js
geo_leak_test.html
[browser_bug1008941_dismissGeolocationHanger.js]
skip-if = buildapp == 'mulet'
@@ -17,6 +18,7 @@ skip-if = buildapp == 'mulet'
[browser_autofocus_background.js]
skip-if= buildapp == 'mulet'
[browser_autofocus_preference.js]
[browser_bug1238427.js]
[browser_bug396843.js]
[browser_focus_steal_from_chrome.js]
[browser_focus_steal_from_chrome_during_mousedown.js]
+31
View File
@@ -0,0 +1,31 @@
/* 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/.
*/
"use strict";
const TEST_URI = "http://example.com/" +
"browser/dom/tests/browser/geo_leak_test.html";
const BASE_GEO_URL = "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs";
add_task(function* () {
Services.prefs.setBoolPref("geo.prompt.testing", true);
Services.prefs.setBoolPref("geo.prompt.testing.allow", true);
// Make the geolocation provider responder very slowly to ensure that
// it does not reply before we close the tab.
Services.prefs.setCharPref("geo.wifi.uri", BASE_GEO_URL + "?delay=100000");
// Open the test URI and close it. The test harness will make sure that the
// page is cleaned up after some GCs. If geolocation is not shut down properly,
// it will show up as a non-shutdown leak.
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_URI
}, function* (browser) { /* ... */ });
ok(true, "Need to do something in this test");
});
+17
View File
@@ -0,0 +1,17 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Geolocation incomplete position leak test</title>
<script type="text/javascript">
function successCallback(position) {}
function errorCallback() {}
function init() {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
</script>
</head>
<body onload="init()">
</body>
</html>
@@ -67,6 +67,30 @@ function testClone() {
});
}
function testCloneUnfiltered() {
var url = 'http://example.com/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?status=200';
return fetch(url, { mode: 'no-cors' }).then(function(response) {
// By default the chrome-only function should not be available.
is(response.type, 'opaque', 'response should be opaque');
is(response.cloneUnfiltered, undefined,
'response.cloneUnfiltered should be undefined');
// When the test is run in a worker context we can't actually try to use
// the chrome-only function. SpecialPowers is not defined.
if (typeof SpecialPowers !== 'object') {
return;
}
// With a chrome code, however, should be able to get an unfiltered response.
var chromeResponse = SpecialPowers.wrap(response);
is(typeof chromeResponse.cloneUnfiltered, 'function',
'chromeResponse.cloneFiltered should be a function');
var unfiltered = chromeResponse.cloneUnfiltered();
is(unfiltered.type, 'default', 'unfiltered response should be default');
is(unfiltered.status, 200, 'unfiltered response should have 200 status');
});
}
function testError() {
var res = Response.error();
is(res.status, 0, "Error response status should be 0");
@@ -234,5 +258,10 @@ function runTest() {
.then(testBodyUsed)
.then(testBodyExtraction)
.then(testClone)
.then(testCloneUnfiltered)
// Put more promise based tests here.
.catch(function(e) {
dump('### ### ' + e + '\n');
ok(false, 'got unexpected error!');
});
}
@@ -165,7 +165,6 @@
expectEvents(1, 0, function() {
is(img.currentSrc, testPNG50, "Should have switched to testPNG50");
Math.sin(90);
// Now add a source *also* wanting that DPI *just before* the
// selected source. Properly re-running the algorithm should
@@ -231,7 +230,7 @@ Math.sin(90);
is(img.currentSrc, testPNG100, "Should still have testPNG100");
// And a valid MQ
source1.media = "(min-resolution: 3dppx)";
source1.media = "(min-resolution: 1dppx)";
expectEvents(1, 0, function() {
// And a valid type...
source1.type = "image/png";
@@ -18,7 +18,7 @@ function parseQueryString(str)
}
function getPosition(action)
{
{
var response = {
status: "OK",
location: {
@@ -27,7 +27,7 @@ function getPosition(action)
},
accuracy: (action == "worse-accuracy") ? 100 : 42,
};
return JSON.stringify(response);
}
+3 -2
View File
@@ -13,6 +13,7 @@ interface External
// Mozilla extension
partial interface External {
[UnsafeInPrerendering] void addSearchEngine(DOMString engineURL, DOMString iconURL,
DOMString suggestedTitle, DOMString suggestedCategory);
[UnsafeInPrerendering, UseCounter]
void addSearchEngine(DOMString engineURL, DOMString iconURL,
DOMString suggestedTitle, DOMString suggestedCategory);
};
+11
View File
@@ -454,3 +454,14 @@ partial interface Navigator {
readonly attribute boolean mozE10sEnabled;
};
#endif
#ifdef MOZ_PAY
partial interface Navigator {
[Throws, NewObject, Pref="dom.mozPay.enabled"]
// The 'jwts' parameter can be either a single DOMString or an array of
// DOMStrings. In both cases, it represents the base64url encoded and
// digitally signed payment information. Each payment provider should
// define its supported JWT format.
DOMRequest mozPay(any jwts);
};
#endif
+2
View File
@@ -24,6 +24,8 @@ interface Response {
[Throws,
NewObject] Response clone();
[ChromeOnly, NewObject, Throws] Response cloneUnfiltered();
};
Response implements Body;
+1 -1
View File
@@ -421,7 +421,7 @@ partial interface Window {
#ifdef HAVE_SIDEBAR
// Mozilla extension
partial interface Window {
[Replaceable, Throws]
[Replaceable, Throws, UseCounter]
readonly attribute (External or WindowProxy) sidebar;
};
#endif
+6
View File
@@ -1369,6 +1369,12 @@ GetCurrentThreadJSContext()
return GetCurrentThreadWorkerPrivate()->GetJSContext();
}
JSObject*
GetCurrentThreadWorkerGlobal()
{
return GetCurrentThreadWorkerPrivate()->GlobalScope()->GetGlobalJSObject();
}
END_WORKERS_NAMESPACE
struct RuntimeService::IdleThreadInfo
+3
View File
@@ -1445,6 +1445,9 @@ IsCurrentThreadRunningChromeWorker();
JSContext*
GetCurrentThreadJSContext();
JSObject*
GetCurrentThreadWorkerGlobal();
class AutoSyncLoopHolder
{
WorkerPrivate* mWorkerPrivate;
-6
View File
@@ -30,7 +30,6 @@
#include "TextureGarbageBin.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "DriverCrashGuard.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "OGLShaderProgram.h" // for ShaderProgramType
@@ -461,11 +460,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return true;
}
GLContextCrashGuard crashGuard;
if (crashGuard.Crashed()) {
return false;
}
mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs();
SymLoadStruct symbols[] = {
-21
View File
@@ -249,27 +249,6 @@ SharedSurface::UnlockProd()
mIsLocked = false;
}
void
SharedSurface::Fence_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
Fence_ContentThread_Impl();
}
bool
SharedSurface::WaitSync_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
return WaitSync_ContentThread_Impl();
}
bool
SharedSurface::PollSync_ContentThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
return PollSync_ContentThread_Impl();
}
////////////////////////////////////////////////////////////////////////
// SurfaceFactory
+4 -42
View File
@@ -100,16 +100,10 @@ protected:
virtual void LockProdImpl() = 0;
virtual void UnlockProdImpl() = 0;
virtual void ProducerAcquireImpl() {}
virtual void ProducerReleaseImpl() {
Fence();
}
virtual void ProducerReadAcquireImpl() {}
virtual void ProducerReadReleaseImpl() {}
virtual void ConsumerAcquireImpl() {
WaitSync();
}
virtual void ConsumerReleaseImpl() {}
virtual void ProducerAcquireImpl() = 0;
virtual void ProducerReleaseImpl() = 0;
virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
public:
void ProducerAcquire() {
@@ -132,39 +126,7 @@ public:
ProducerReadReleaseImpl();
mIsProducerAcquired = false;
}
void ConsumerAcquire() {
MOZ_ASSERT(!mIsConsumerAcquired);
ConsumerAcquireImpl();
mIsConsumerAcquired = true;
}
void ConsumerRelease() {
MOZ_ASSERT(mIsConsumerAcquired);
ConsumerReleaseImpl();
mIsConsumerAcquired = false;
}
virtual void Fence() = 0;
virtual bool WaitSync() = 0;
virtual bool PollSync() = 0;
// Use these if you can. They can only be called from the Content
// thread, though!
void Fence_ContentThread();
bool WaitSync_ContentThread();
bool PollSync_ContentThread();
protected:
virtual void Fence_ContentThread_Impl() {
Fence();
}
virtual bool WaitSync_ContentThread_Impl() {
return WaitSync();
}
virtual bool PollSync_ContentThread_Impl() {
return PollSync();
}
public:
// This function waits until the buffer is no longer being used.
// To optimize the performance, some implementaions recycle SharedSurfaces
// even when its buffer is still being used.
+1 -90
View File
@@ -134,24 +134,6 @@ SharedSurface_ANGLEShareHandle::UnlockProdImpl()
{
}
void
SharedSurface_ANGLEShareHandle::Fence()
{
mGL->fFinish();
}
bool
SharedSurface_ANGLEShareHandle::WaitSync()
{
return true;
}
bool
SharedSurface_ANGLEShareHandle::PollSync()
{
return true;
}
void
SharedSurface_ANGLEShareHandle::ProducerAcquireImpl()
{
@@ -174,7 +156,7 @@ SharedSurface_ANGLEShareHandle::ProducerReleaseImpl()
mKeyedMutex->ReleaseSync(0);
return;
}
Fence();
mGL->fFinish();
}
void
@@ -192,77 +174,6 @@ SharedSurface_ANGLEShareHandle::ProducerReadReleaseImpl()
}
}
void
SharedSurface_ANGLEShareHandle::ConsumerAcquireImpl()
{
if (!mConsumerTexture) {
RefPtr<ID3D11Texture2D> tex;
HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetD3D11Device()->OpenSharedResource(mShareHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**)getter_AddRefs(tex));
if (SUCCEEDED(hr)) {
mConsumerTexture = tex;
RefPtr<IDXGIKeyedMutex> mutex;
hr = tex->QueryInterface((IDXGIKeyedMutex**)getter_AddRefs(mutex));
if (SUCCEEDED(hr)) {
mConsumerKeyedMutex = mutex;
}
}
}
if (mConsumerKeyedMutex) {
HRESULT hr = mConsumerKeyedMutex->AcquireSync(0, 10000);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH("GFX: ANGLE consumer mutex timeout");
}
}
}
void
SharedSurface_ANGLEShareHandle::ConsumerReleaseImpl()
{
if (mConsumerKeyedMutex) {
mConsumerKeyedMutex->ReleaseSync(0);
}
}
void
SharedSurface_ANGLEShareHandle::Fence_ContentThread_Impl()
{
if (mFence) {
MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::NV_fence));
mGL->fSetFence(mFence, LOCAL_GL_ALL_COMPLETED_NV);
mGL->fFlush();
return;
}
Fence();
}
bool
SharedSurface_ANGLEShareHandle::WaitSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
mGL->fFinishFence(mFence);
return true;
}
return WaitSync();
}
bool
SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
return mGL->fTestFence(mFence);
}
return PollSync();
}
bool
SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{
-9
View File
@@ -62,19 +62,10 @@ public:
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual void Fence() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual void ProducerReadAcquireImpl() override;
virtual void ProducerReadReleaseImpl() override;
virtual void ConsumerAcquireImpl() override;
virtual void ConsumerReleaseImpl() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void Fence_ContentThread_Impl() override;
virtual bool WaitSync_ContentThread_Impl() override;
virtual bool PollSync_ContentThread_Impl() override;
const RefPtr<ID3D11Texture2D>& GetConsumerTexture() const {
return mConsumerTexture;
+2 -93
View File
@@ -328,25 +328,6 @@ void
SharedSurface_D3D11Interop::UnlockProdImpl()
{ }
void
SharedSurface_D3D11Interop::Fence()
{
// TODO fence properly. This kills performance.
mGL->fFinish();
}
bool
SharedSurface_D3D11Interop::WaitSync()
{
return true;
}
bool
SharedSurface_D3D11Interop::PollSync()
{
return true;
}
void
SharedSurface_D3D11Interop::ProducerAcquireImpl()
{
@@ -382,81 +363,9 @@ SharedSurface_D3D11Interop::ProducerReleaseImpl()
if (mKeyedMutex) {
mKeyedMutex->ReleaseSync(0);
}
Fence();
}
void
SharedSurface_D3D11Interop::ConsumerAcquireImpl()
{
if (!mConsumerTexture) {
RefPtr<ID3D11Texture2D> tex;
RefPtr<ID3D11Device> device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
HRESULT hr = device->OpenSharedResource(mSharedHandle,
__uuidof(ID3D11Texture2D),
(void**)(ID3D11Texture2D**) getter_AddRefs(tex));
if (SUCCEEDED(hr)) {
mConsumerTexture = tex;
RefPtr<IDXGIKeyedMutex> mutex;
hr = tex->QueryInterface((IDXGIKeyedMutex**) getter_AddRefs(mutex));
if (SUCCEEDED(hr)) {
mConsumerKeyedMutex = mutex;
}
}
}
if (mConsumerKeyedMutex) {
const uint64_t keyValue = 0;
const DWORD timeoutMs = 10000;
HRESULT hr = mConsumerKeyedMutex->AcquireSync(keyValue, timeoutMs);
if (hr == WAIT_TIMEOUT) {
MOZ_CRASH();
}
}
}
void
SharedSurface_D3D11Interop::ConsumerReleaseImpl()
{
if (mConsumerKeyedMutex) {
mConsumerKeyedMutex->ReleaseSync(0);
}
}
void
SharedSurface_D3D11Interop::Fence_ContentThread_Impl()
{
if (mFence) {
MOZ_ASSERT(mGL->IsExtensionSupported(GLContext::NV_fence));
mGL->fSetFence(mFence, LOCAL_GL_ALL_COMPLETED_NV);
mGL->fFlush();
return;
}
Fence();
}
bool
SharedSurface_D3D11Interop::WaitSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
mGL->fFinishFence(mFence);
return true;
}
return WaitSync();
}
bool
SharedSurface_D3D11Interop::PollSync_ContentThread_Impl()
{
if (mFence) {
mGL->MakeCurrent();
return mGL->fTestFence(mFence);
}
return PollSync();
// TODO fence properly. This kills performance.
mGL->fFinish();
}
bool
-9
View File
@@ -65,17 +65,8 @@ public:
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
virtual void Fence() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual void ConsumerAcquireImpl() override;
virtual void ConsumerReleaseImpl() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void Fence_ContentThread_Impl() override;
virtual bool WaitSync_ContentThread_Impl() override;
virtual bool PollSync_ContentThread_Impl() override;
virtual GLuint ProdRenderbuffer() override {
return mProdRB;
+1 -43
View File
@@ -113,7 +113,7 @@ SharedSurface_EGLImage::GetTextureFlags() const
}
void
SharedSurface_EGLImage::Fence()
SharedSurface_EGLImage::ProducerReleaseImpl()
{
MutexAutoLock lock(mMutex);
mGL->MakeCurrent();
@@ -140,48 +140,6 @@ SharedSurface_EGLImage::Fence()
mGL->fFinish();
}
bool
SharedSurface_EGLImage::WaitSync()
{
MutexAutoLock lock(mMutex);
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
// Wait FOREVER, primarily because some NVIDIA (at least Tegra) drivers
// have ClientWaitSync returning immediately if the timeout delay is anything
// else than FOREVER.
//
// FIXME: should we try to use a finite timeout delay where possible?
EGLint status = mEGL->fClientWaitSync(Display(),
mSync,
0,
LOCAL_EGL_FOREVER);
return status == LOCAL_EGL_CONDITION_SATISFIED;
}
bool
SharedSurface_EGLImage::PollSync()
{
MutexAutoLock lock(mMutex);
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = 0;
MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
mSync,
LOCAL_EGL_SYNC_STATUS_KHR,
&status) );
return status == LOCAL_EGL_SIGNALED_KHR;
}
EGLDisplay
SharedSurface_EGLImage::Display() const
{
+2 -3
View File
@@ -68,9 +68,8 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void Fence() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual GLuint ProdTexture() override {
return mProdTex;
+3 -7
View File
@@ -66,9 +66,8 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void Fence() override {}
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override {}
virtual GLuint ProdTexture() override {
return mTex;
@@ -134,12 +133,9 @@ public:
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void Fence() override {}
virtual bool WaitSync() override { MOZ_CRASH("should not be called"); }
virtual bool PollSync() override { MOZ_CRASH("should not be called"); }
virtual GLuint ProdTexture() override {
return mTex;
}
+1 -1
View File
@@ -55,7 +55,7 @@ SharedSurface_GLXDrawable::SharedSurface_GLXDrawable(GLContext* gl,
{}
void
SharedSurface_GLXDrawable::Fence()
SharedSurface_GLXDrawable::ProducerReleaseImpl()
{
mGL->MakeCurrent();
mGL->fFlush();
+2 -3
View File
@@ -24,9 +24,8 @@ public:
bool deallocateClient,
bool inSameProcess);
virtual void Fence() override;
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void LockProdImpl() override;
virtual void UnlockProdImpl() override;
+1 -49
View File
@@ -158,7 +158,7 @@ SharedSurface_Gralloc::~SharedSurface_Gralloc()
}
void
SharedSurface_Gralloc::Fence()
SharedSurface_Gralloc::ProducerReleaseImpl()
{
if (mSync) {
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
@@ -222,54 +222,6 @@ SharedSurface_Gralloc::Fence()
}
}
bool
SharedSurface_Gralloc::WaitSync()
{
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = mEGL->fClientWaitSync(mEGL->Display(),
mSync,
0,
LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
mSync = 0;
return true;
}
bool
SharedSurface_Gralloc::PollSync()
{
if (!mSync) {
// We must not be needed.
return true;
}
MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
EGLint status = 0;
MOZ_ALWAYS_TRUE( mEGL->fGetSyncAttrib(mEGL->Display(),
mSync,
LOCAL_EGL_SYNC_STATUS_KHR,
&status) );
if (status != LOCAL_EGL_SIGNALED_KHR) {
return false;
}
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
mSync = 0;
return true;
}
void
SharedSurface_Gralloc::WaitForBufferOwnership()
{
+2 -3
View File
@@ -57,9 +57,8 @@ protected:
public:
virtual ~SharedSurface_Gralloc();
virtual void Fence() override;
virtual bool WaitSync() override;
virtual bool PollSync() override;
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual void WaitForBufferOwnership() override;
+1 -1
View File
@@ -30,7 +30,7 @@ SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
}
void
SharedSurface_IOSurface::Fence()
SharedSurface_IOSurface::ProducerReleaseImpl()
{
mGL->MakeCurrent();
mGL->fFlush();
+2 -3
View File
@@ -36,9 +36,8 @@ public:
virtual void LockProdImpl() override { }
virtual void UnlockProdImpl() override { }
virtual void Fence() override;
virtual bool WaitSync() override { return true; }
virtual bool PollSync() override { return true; }
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height,
+6 -1
View File
@@ -337,8 +337,13 @@ CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
if (!dest) {
return nullptr;
}
gl::SharedSurface* destSurf = dest->Surf();
destSurf->ProducerAcquire();
SharedSurface::ProdCopy(src, dest->Surf(), factory);
dest->Surf()->Fence();
destSurf->ProducerRelease();
return dest.forget();
}
+2 -2
View File
@@ -525,13 +525,13 @@ GLContextCrashGuard::UpdateEnvironment()
void
GLContextCrashGuard::LogCrashRecovery()
{
gfxCriticalNote << "GLContext just crashed and is now disabled.";
gfxCriticalNote << "GLContext just crashed.";
}
void
GLContextCrashGuard::LogFeatureDisabled()
{
gfxCriticalNote << "GLContext is disabled due to a previous crash.";
gfxCriticalNote << "GLContext remains enabled despite a previous crash.";
}
} // namespace gfx
+7
View File
@@ -310,6 +310,13 @@ FilterCachedColorModels::FilterCachedColorModels(DrawTarget* aDT,
already_AddRefed<FilterNode>
FilterCachedColorModels::ForColorModel(ColorModel aColorModel)
{
if (aColorModel == mOriginalColorModel) {
// Make sure to not call WrapForColorModel if our original filter node was
// null, because then we'd get an infinite recursion.
RefPtr<FilterNode> filter = mFilterForColorModel[mOriginalColorModel.ToIndex()];
return filter.forget();
}
if (!mFilterForColorModel[aColorModel.ToIndex()]) {
mFilterForColorModel[aColorModel.ToIndex()] = WrapForColorModel(aColorModel);
}
+15
View File
@@ -722,3 +722,18 @@ nsDeviceContext::UpdateAppUnitsForFullZoom()
// adjust mFullZoom to reflect appunit rounding
mFullZoom = float(mAppUnitsPerDevPixelAtUnitFullZoom) / mAppUnitsPerDevPixel;
}
DesktopToLayoutDeviceScale
nsDeviceContext::GetDesktopToDeviceScale()
{
nsCOMPtr<nsIScreen> screen;
FindScreen(getter_AddRefs(screen));
if (screen) {
double scale;
screen->GetContentsScaleFactor(&scale);
return DesktopToLayoutDeviceScale(scale);
}
return DesktopToLayoutDeviceScale(1.0);
}
+2
View File
@@ -251,6 +251,8 @@ public:
*/
bool IsPrinterSurface();
mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale();
private:
// Private destructor, to discourage deletion outside of Release():
~nsDeviceContext();
+2 -47
View File
@@ -52,29 +52,7 @@ nsFont::Init()
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
}
nsFont::nsFont(const nsFont& aOther)
: fontlist(aOther.fontlist)
{
style = aOther.style;
systemFont = aOther.systemFont;
weight = aOther.weight;
stretch = aOther.stretch;
smoothing = aOther.smoothing;
size = aOther.size;
sizeAdjust = aOther.sizeAdjust;
kerning = aOther.kerning;
synthesis = aOther.synthesis;
fontFeatureSettings = aOther.fontFeatureSettings;
languageOverride = aOther.languageOverride;
variantAlternates = aOther.variantAlternates;
variantCaps = aOther.variantCaps;
variantEastAsian = aOther.variantEastAsian;
variantLigatures = aOther.variantLigatures;
variantNumeric = aOther.variantNumeric;
variantPosition = aOther.variantPosition;
alternateValues = aOther.alternateValues;
featureValueLookup = aOther.featureValueLookup;
}
nsFont::nsFont(const nsFont& aOther) = default;
nsFont::nsFont()
{
@@ -111,30 +89,7 @@ bool nsFont::Equals(const nsFont& aOther) const
return false;
}
nsFont& nsFont::operator=(const nsFont& aOther)
{
fontlist = aOther.fontlist;
style = aOther.style;
systemFont = aOther.systemFont;
weight = aOther.weight;
stretch = aOther.stretch;
smoothing = aOther.smoothing;
size = aOther.size;
sizeAdjust = aOther.sizeAdjust;
kerning = aOther.kerning;
synthesis = aOther.synthesis;
fontFeatureSettings = aOther.fontFeatureSettings;
languageOverride = aOther.languageOverride;
variantAlternates = aOther.variantAlternates;
variantCaps = aOther.variantCaps;
variantEastAsian = aOther.variantEastAsian;
variantLigatures = aOther.variantLigatures;
variantNumeric = aOther.variantNumeric;
variantPosition = aOther.variantPosition;
alternateValues = aOther.alternateValues;
featureValueLookup = aOther.featureValueLookup;
return *this;
}
nsFont& nsFont::operator=(const nsFont& aOther) = default;
void
nsFont::CopyAlternates(const nsFont& aOther)
+17 -11
View File
@@ -738,13 +738,24 @@ nsIntRegion nsRegion::ScaleToNearestPixels (float aScaleX, float aScaleY,
nsIntRegion nsRegion::ScaleToOutsidePixels (float aScaleX, float aScaleY,
nscoord aAppUnitsPerPixel) const
{
nsIntRegion result;
for (auto iter = RectIter(); !iter.Done(); iter.Next()) {
mozilla::gfx::IntRect deviceRect =
iter.Get().ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel);
result.Or(result, deviceRect);
// make a copy of the region so that we can mutate it inplace
nsRegion region = *this;
int n;
pixman_box32_t *boxes = pixman_region32_rectangles(&region.mImpl, &n);
boxes = pixman_region32_rectangles(&region.mImpl, &n);
for (int i=0; i<n; i++) {
nsRect rect = BoxToRect(boxes[i]);
mozilla::gfx::IntRect irect = rect.ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel);
boxes[i] = RectToBox(irect);
}
return result;
nsIntRegion iRegion;
// clear out the initial pixman_region so that we can replace it below
pixman_region32_fini(&iRegion.mImpl.mImpl);
// This will union all of the rectangles and runs in about O(n lg(n))
pixman_region32_init_rects(&iRegion.mImpl.mImpl, boxes, n);
return iRegion;
}
nsIntRegion nsRegion::ScaleToInsidePixels (float aScaleX, float aScaleY,
@@ -950,11 +961,6 @@ namespace {
result.mSize = result.mSizeContainingRect = kVeryLargeNegativeNumber;
return result;
}
SizePair& operator=(const SizePair& aOther) {
mSizeContainingRect = aOther.mSizeContainingRect;
mSize = aOther.mSize;
return *this;
}
bool operator<(const SizePair& aOther) const {
if (mSizeContainingRect < aOther.mSizeContainingRect)
return true;
+2 -1
View File
@@ -208,9 +208,10 @@ void
gfxASurface::Init(cairo_surface_t* surface, bool existingSurface)
{
SetSurfaceWrapper(surface, this);
MOZ_ASSERT(surface, "surface should be a valid pointer");
mSurface = surface;
mSurfaceValid = surface && !cairo_surface_status(surface);
mSurfaceValid = !cairo_surface_status(surface);
if (!mSurfaceValid) {
gfxWarning() << "ASurface Init failed with Cairo status " << cairo_surface_status(surface) << " on " << hexa(surface);
}
+6 -5
View File
@@ -12,6 +12,7 @@
#include "mozilla/gfx/Blur.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "gfxUtils.h"
@@ -63,14 +64,14 @@ gfxAlphaBoxBlur::Init(const gfxRect& aRect,
// Make an alpha-only surface to draw on. We will play with the data after
// everything is drawn to create a blur effect.
mData = new (std::nothrow) unsigned char[blurDataSize];
mData = MakeUniqueFallible<unsigned char[]>(blurDataSize);
if (!mData) {
return nullptr;
}
memset(mData, 0, blurDataSize);
memset(mData.get(), 0, blurDataSize);
RefPtr<DrawTarget> dt =
gfxPlatform::GetPlatform()->CreateDrawTargetForData(mData, size,
gfxPlatform::GetPlatform()->CreateDrawTargetForData(mData.get(), size,
mBlur->GetStride(),
SurfaceFormat::A8);
if (!dt) {
@@ -119,11 +120,11 @@ DrawBlur(gfxContext* aDestinationCtx,
already_AddRefed<SourceSurface>
gfxAlphaBoxBlur::DoBlur(DrawTarget* aDT, IntPoint* aTopLeft)
{
mBlur->Blur(mData);
mBlur->Blur(mData.get());
*aTopLeft = mBlur->GetRect().TopLeft();
return aDT->CreateSourceSurfaceFromData(mData,
return aDT->CreateSourceSurfaceFromData(mData.get(),
mBlur->GetSize(),
mBlur->GetStride(),
SurfaceFormat::A8);
+1 -1
View File
@@ -188,7 +188,7 @@ protected:
/**
* The temporary alpha surface.
*/
nsAutoArrayPtr<unsigned char> mData;
mozilla::UniquePtr<unsigned char[]> mData;
/**
* The object that actually does the blurring for us.
+2 -2
View File
@@ -1358,7 +1358,7 @@ static HRESULT GetFamilyName(IDWriteFont *aFont, nsString& aFamilyName)
// used to invoke the DirectWrite layout engine to determine the fallback font
// for a given character.
IFACEMETHODIMP FontFallbackRenderer::DrawGlyphRun(
IFACEMETHODIMP DWriteFontFallbackRenderer::DrawGlyphRun(
void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
@@ -1423,7 +1423,7 @@ gfxDWriteFontList::GlobalFontFallback(const uint32_t aCh,
// initialize fallback renderer
if (!mFallbackRenderer) {
mFallbackRenderer = new FontFallbackRenderer(dwFactory);
mFallbackRenderer = new DWriteFontFallbackRenderer(dwFactory);
}
// initialize text format
+4 -4
View File
@@ -208,10 +208,10 @@ protected:
};
// custom text renderer used to determine the fallback font for a given char
class FontFallbackRenderer final : public IDWriteTextRenderer
class DWriteFontFallbackRenderer final : public IDWriteTextRenderer
{
public:
FontFallbackRenderer(IDWriteFactory *aFactory)
DWriteFontFallbackRenderer(IDWriteFactory *aFactory)
: mRefCount(0)
{
HRESULT hr = S_OK;
@@ -220,7 +220,7 @@ public:
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
}
~FontFallbackRenderer()
~DWriteFontFallbackRenderer()
{}
// IDWriteTextRenderer methods
@@ -432,7 +432,7 @@ private:
bool mGDIFontTableAccess;
RefPtr<IDWriteGdiInterop> mGDIInterop;
RefPtr<FontFallbackRenderer> mFallbackRenderer;
RefPtr<DWriteFontFallbackRenderer> mFallbackRenderer;
RefPtr<IDWriteTextFormat> mFallbackFormat;
RefPtr<IDWriteFontCollection> mSystemFonts;
+32 -24
View File
@@ -544,7 +544,7 @@ FT2FontEntry::GetFontTable(uint32_t aTableTag)
FTUserFontData *userFontData = static_cast<FTUserFontData*>(
cairo_font_face_get_user_data(mFontFace, &sFTUserFontDataKey));
if (userFontData && userFontData->FontData()) {
return gfxFontUtils::GetTableFromFontData(userFontData->FontData(), aTableTag);
return GetTableFromFontData(userFontData->FontData(), aTableTag);
}
}
@@ -643,7 +643,21 @@ public:
}
nsAutoCString buf;
PL_DHashTableEnumerate(&mMap, WriteOutMap, &buf);
for (auto iter = mMap.Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<FNCMapEntry*>(iter.Get());
if (!entry->mFileExists) {
// skip writing entries for files that are no longer present
continue;
}
buf.Append(entry->mFilename);
buf.Append(';');
buf.Append(entry->mFaces);
buf.Append(';');
buf.AppendInt(entry->mTimestamp);
buf.Append(';');
buf.AppendInt(entry->mFilesize);
buf.Append(';');
}
mCache->PutBuffer(CACHE_KEY, buf.get(), buf.Length() + 1);
}
@@ -739,28 +753,6 @@ private:
PLDHashTableOps mOps;
static PLDHashOperator WriteOutMap(PLDHashTable *aTable,
PLDHashEntryHdr *aHdr,
uint32_t aNumber, void *aData)
{
FNCMapEntry* entry = static_cast<FNCMapEntry*>(aHdr);
if (!entry->mFileExists) {
// skip writing entries for files that are no longer present
return PL_DHASH_NEXT;
}
nsAutoCString* buf = reinterpret_cast<nsAutoCString*>(aData);
buf->Append(entry->mFilename);
buf->Append(';');
buf->Append(entry->mFaces);
buf->Append(';');
buf->AppendInt(entry->mTimestamp);
buf->Append(';');
buf->AppendInt(entry->mFilesize);
buf->Append(';');
return PL_DHASH_NEXT;
}
typedef struct : public PLDHashEntryHdr {
public:
nsCString mFilename;
@@ -1213,6 +1205,22 @@ gfxFT2FontList::FindFonts()
FindFontsInOmnijar(&fnc);
}
// Look for downloaded fonts in a profile-agnostic "fonts" directory.
nsCOMPtr<nsIProperties> dirSvc =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
if (dirSvc) {
nsCOMPtr<nsIFile> appDir;
nsresult rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
NS_GET_IID(nsIFile), getter_AddRefs(appDir));
if (NS_SUCCEEDED(rv)) {
appDir->AppendNative(NS_LITERAL_CSTRING("fonts"));
nsCString localPath;
if (NS_SUCCEEDED(appDir->GetNativePath(localPath))) {
FindFontsInDir(localPath, &fnc, FT2FontFamily::kVisible);
}
}
}
// look for locally-added fonts in a "fonts" subdir of the profile
nsCOMPtr<nsIFile> localDir;
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
+2 -1
View File
@@ -590,11 +590,12 @@ ShareTableAndGetBlob(nsTArray<uint8_t>&& aTable,
Clear();
// adopts elements of aTable
mSharedBlobData = new FontTableBlobData(Move(aTable));
mBlob = hb_blob_create(mSharedBlobData->GetTable(),
mSharedBlobData->GetTableLength(),
HB_MEMORY_MODE_READONLY,
mSharedBlobData, DeleteFontTableBlobData);
if (!mSharedBlobData) {
if (mBlob == hb_blob_get_empty() ) {
// The FontTableBlobData was destroyed during hb_blob_create().
// The (empty) blob is still be held in the hashtable with a strong
// reference.
+7 -6
View File
@@ -153,14 +153,10 @@ struct FontFamilyName final {
}
// memory reporting
size_t SizeOfExcludingThis2(mozilla::MallocSizeOf aMallocSizeOf) const {
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
size_t SizeOfIncludingThis2(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis2(aMallocSizeOf);
}
FontFamilyType mType;
nsString mName; // empty if mType != eFamily_named
};
@@ -341,7 +337,12 @@ public:
// memory reporting
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return mFontlist.ShallowSizeOfExcludingThis(aMallocSizeOf);
size_t n = 0;
n += mFontlist.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (size_t i = 0; i < mFontlist.Length(); i++) {
n += mFontlist[i].SizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
+11 -2
View File
@@ -25,8 +25,15 @@ FontInfoData::Load()
uint32_t i, n = mFontFamiliesToLoad.Length();
mLoadStats.families = n;
for (i = 0; i < n; i++) {
LoadFontFamilyData(mFontFamiliesToLoad[i]);
for (i = 0; i < n && !mCanceled; i++) {
// font file memory mapping sometimes causes exceptions - bug 1100949
MOZ_SEH_TRY {
LoadFontFamilyData(mFontFamiliesToLoad[i]);
} MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
gfxCriticalError() <<
"Exception occurred reading font data for " <<
NS_ConvertUTF16toUTF8(mFontFamiliesToLoad[i]).get();
}
}
mLoadTime = TimeStamp::Now() - start;
@@ -217,6 +224,8 @@ gfxFontInfoLoader::CancelLoader()
mTimer->Cancel();
mTimer = nullptr;
}
if (mFontInfo) // null during any initial delay
mFontInfo->mCanceled = true;
if (mFontLoaderThread) {
NS_DispatchToMainThread(new ShutdownThreadEvent(mFontLoaderThread));
mFontLoaderThread = nullptr;
+6
View File
@@ -15,6 +15,7 @@
#include "nsString.h"
#include "gfxFont.h"
#include "nsIRunnable.h"
#include "mozilla/Atomics.h"
#include "mozilla/TimeStamp.h"
#include "nsISupportsImpl.h"
@@ -52,6 +53,7 @@ public:
FontInfoData(bool aLoadOtherNames,
bool aLoadFaceNames,
bool aLoadCmaps) :
mCanceled(false),
mLoadOtherNames(aLoadOtherNames),
mLoadFaceNames(aLoadFaceNames),
mLoadCmaps(aLoadCmaps)
@@ -115,6 +117,10 @@ public:
nsTArray<nsString> mFontFamiliesToLoad;
// currently non-issue but beware,
// this is also set during cleanup after finishing
mozilla::Atomic<bool> mCanceled;
// time spent on the loader thread
mozilla::TimeDuration mLoadTime;
+1 -1
View File
@@ -1109,7 +1109,7 @@ int CALLBACK GDIFontInfo::EnumerateFontsForFamily(
famData->mFontInfo.mFontFaceData.Put(fontName, fontData);
}
return 1;
return famData->mFontInfo.mCanceled ? 0 : 1;
}
void
+39 -20
View File
@@ -5,27 +5,28 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Hal.h"
#include "HalImpl.h"
#include "HalLog.h"
#include "HalSandbox.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIDocShell.h"
#include "nsITabChild.h"
#include "nsIWebNavigation.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "mozilla/Observer.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMWindow.h"
#include "mozilla/Services.h"
#include "nsIWebNavigation.h"
#include "nsITabChild.h"
#include "nsIDocShell.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "WindowIdentifier.h"
#include "nsJSUtils.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Observer.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "WindowIdentifier.h"
#ifdef XP_WIN
#include <process.h>
@@ -148,7 +149,7 @@ Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
*gLastIDToVibrate = id.AsArray();
}
// Don't forward our ID if we are not in the sandbox, because hal_impl
// Don't forward our ID if we are not in the sandbox, because hal_impl
// doesn't need it, and we don't want it to be tempted to read it. The
// empty identifier will assert if it's used.
PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
@@ -183,7 +184,7 @@ CancelVibrate(const WindowIdentifier &id)
// the same window. All other cancellation requests are ignored.
if (InSandbox() || (gLastIDToVibrate && *gLastIDToVibrate == id.AsArray())) {
// Don't forward our ID if we are not in the sandbox, because hal_impl
// Don't forward our ID if we are not in the sandbox, because hal_impl
// doesn't need it, and we don't want it to be tempted to read it. The
// empty identifier will assert if it's used.
PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id : WindowIdentifier()));
@@ -497,14 +498,14 @@ NotifySystemTimezoneChange(const SystemTimezoneChangeInformation& aSystemTimezon
sSystemTimezoneChangeObservers.BroadcastInformation(aSystemTimezoneChangeInfo);
}
void
void
AdjustSystemClock(int64_t aDeltaMilliseconds)
{
AssertMainThread();
PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
}
void
void
SetTimezone(const nsCString& aTimezoneSpec)
{
AssertMainThread();
@@ -543,7 +544,7 @@ static SensorObserverList* gSensorObservers = nullptr;
static SensorObserverList &
GetSensorObservers(SensorType sensor_type) {
MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
if(!gSensorObservers) {
gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
}
@@ -555,7 +556,7 @@ RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
SensorObserverList &observers = GetSensorObservers(aSensor);
AssertMainThread();
observers.AddObserver(aObserver);
if(observers.Length() == 1) {
EnableSensorNotifications(aSensor);
@@ -591,7 +592,7 @@ NotifySensorChange(const SensorData &aSensorData) {
SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
AssertMainThread();
observers.Broadcast(aSensorData);
}
@@ -761,7 +762,7 @@ static SwitchObserverList *sSwitchObserverLists = nullptr;
static SwitchObserverList&
GetSwitchObserverList(SwitchDevice aDevice) {
MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
if (sSwitchObserverLists == nullptr) {
sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
}
@@ -1195,5 +1196,23 @@ bool IsHeadphoneEventFromInputDev()
RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
}
nsresult StartSystemService(const char* aSvcName, const char* aArgs)
{
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(StartSystemService(aSvcName, aArgs), NS_ERROR_FAILURE);
}
void StopSystemService(const char* aSvcName)
{
AssertMainThread();
PROXY_IF_SANDBOXED(StopSystemService(aSvcName));
}
bool SystemServiceIsRunning(const char* aSvcName)
{
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(SystemServiceIsRunning(aSvcName), false);
}
} // namespace hal
} // namespace mozilla
+20 -5
View File
@@ -7,19 +7,19 @@
#ifndef mozilla_Hal_h
#define mozilla_Hal_h
#include "mozilla/hal_sandbox/PHal.h"
#include "mozilla/HalTypes.h"
#include "base/basictypes.h"
#include "base/platform_thread.h"
#include "mozilla/Observer.h"
#include "mozilla/Types.h"
#include "nsTArray.h"
#include "mozilla/dom/MozPowerManagerBinding.h"
#include "mozilla/dom/battery/Types.h"
#include "mozilla/dom/MozPowerManagerBinding.h"
#include "mozilla/dom/network/Types.h"
#include "mozilla/dom/power/Types.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "mozilla/hal_sandbox/PHal.h"
#include "mozilla/HalScreenConfiguration.h"
#include "mozilla/HalTypes.h"
#include "mozilla/Observer.h"
#include "mozilla/Types.h"
/*
* Hal.h contains the public Hal API.
@@ -640,6 +640,21 @@ uint32_t GetTotalSystemMemoryLevel();
*/
bool IsHeadphoneEventFromInputDev();
/**
* Start the system service with the specified name and arguments.
*/
nsresult StartSystemService(const char* aSvcName, const char* aArgs);
/**
* Stop the system service with the specified name.
*/
void StopSystemService(const char* aSvcName);
/**
* Determine whether the system service with the specified name is running.
*/
bool SystemServiceIsRunning(const char* aSvcName);
} // namespace MOZ_HAL_NAMESPACE
} // namespace mozilla
+2 -1
View File
@@ -4,8 +4,9 @@
* 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 "mozilla/dom/ContentChild.h"
#include "WindowIdentifier.h"
#include "mozilla/dom/ContentChild.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
+1 -1
View File
@@ -8,8 +8,8 @@
#define mozilla_hal_WindowIdentifier_h
#include "mozilla/Types.h"
#include "nsTArray.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsIDOMWindow.h"
namespace mozilla {
+35
View File
@@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "Hal.h"
namespace mozilla {
namespace hal_impl {
nsresult
StartSystemService(const char* aSvcName, const char* aArgs)
{
MOZ_ASSERT(NS_IsMainThread());
return NS_ERROR_NOT_IMPLEMENTED;
}
void
StopSystemService(const char* aSvcName)
{
MOZ_ASSERT(NS_IsMainThread());
}
bool
SystemServiceIsRunning(const char* aSvcName)
{
MOZ_ASSERT(NS_IsMainThread());
return false;
}
} // namespace hal_impl
} // namespace mozilla
+131
View File
@@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "Hal.h"
#include <cutils/properties.h>
#include <stdio.h>
#include <string.h>
#include "HalLog.h"
#include "nsITimer.h"
#include "mozilla/unused.h"
namespace mozilla {
namespace hal_impl {
static const int sRetryInterval = 100; // ms
bool
SystemServiceIsRunning(const char* aSvcName)
{
MOZ_ASSERT(NS_IsMainThread());
char key[PROPERTY_KEY_MAX];
auto res = snprintf(key, sizeof(key), "init.svc.%s", aSvcName);
if (res < 0) {
HAL_ERR("snprintf: %s", strerror(errno));
return false;
} else if (static_cast<size_t>(res) >= sizeof(key)) {
HAL_ERR("snprintf: trunctated service name %s", aSvcName);
return false;
}
char value[PROPERTY_VALUE_MAX];
NS_WARN_IF(property_get(key, value, "") < 0);
return !strcmp(value, "running");
}
class StartSystemServiceTimerCallback final : public nsITimerCallback
{
NS_DECL_THREADSAFE_ISUPPORTS;
public:
StartSystemServiceTimerCallback(const char* aSvcName, const char* aArgs)
: mSvcName(aSvcName)
, mArgs(aArgs)
{
MOZ_COUNT_CTOR_INHERITED(StartSystemServiceTimerCallback,
nsITimerCallback);
}
NS_IMETHOD Notify(nsITimer* aTimer) override
{
MOZ_ASSERT(NS_IsMainThread());
return StartSystemService(mSvcName.get(), mArgs.get());
}
protected:
~StartSystemServiceTimerCallback()
{
MOZ_COUNT_DTOR_INHERITED(StartSystemServiceTimerCallback,
nsITimerCallback);
}
private:
nsCString mSvcName;
nsCString mArgs;
};
NS_IMPL_ISUPPORTS0(StartSystemServiceTimerCallback);
nsresult
StartSystemService(const char* aSvcName, const char* aArgs)
{
MOZ_ASSERT(NS_IsMainThread());
char value[PROPERTY_VALUE_MAX];
auto res = snprintf(value, sizeof(value), "%s:%s", aSvcName, aArgs);
if (res < 0) {
HAL_ERR("snprintf: %s", strerror(errno));
return NS_ERROR_FAILURE;
} else if (static_cast<size_t>(res) >= sizeof(value)) {
HAL_ERR("snprintf: trunctated service name %s", aSvcName);
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_WARN_IF(property_set("ctl.start", value) < 0)) {
return NS_ERROR_FAILURE;
}
/* If the system service is not running, re-try later to start it.
*
* This condition happens when we restart a service immediately
* after it crashed, as the service state remains 'stopping'
* instead of 'stopped'. Due to the limitation of property service,
* hereby add delay. See Bug 1143925 Comment 41.
*/
if (!SystemServiceIsRunning(aSvcName)) {
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
if (!timer) {
return NS_ERROR_FAILURE;
}
RefPtr<StartSystemServiceTimerCallback> timerCallback =
new StartSystemServiceTimerCallback(aSvcName, aArgs);
timer->InitWithCallback(timerCallback,
sRetryInterval,
nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
void
StopSystemService(const char* aSvcName)
{
MOZ_ASSERT(NS_IsMainThread());
Unused << NS_WARN_IF(property_set("ctl.stop", aSvcName));
}
} // namespace hal_impl
} // namespace mozilla
+2
View File
@@ -50,6 +50,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
'gonk/GonkSensor.cpp',
'gonk/GonkSensorsHelpers.cpp',
'gonk/GonkSwitch.cpp',
'gonk/SystemService.cpp',
'gonk/UeventPoller.cpp',
'linux/LinuxMemory.cpp',
'linux/LinuxPower.cpp',
@@ -134,6 +135,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
'fallback/FallbackProcessPriority.cpp',
'fallback/FallbackScreenPower.cpp',
'fallback/FallbackSwitch.cpp',
'fallback/FallbackSystemService.cpp',
'fallback/FallbackThreadPriority.cpp',
'fallback/FallbackTime.cpp',
'fallback/FallbackWakeLocks.cpp',
+26 -9
View File
@@ -191,7 +191,7 @@ SetScreenBrightness(double aBrightness)
Hal()->SendSetScreenBrightness(aBrightness);
}
void
void
AdjustSystemClock(int64_t aDeltaMilliseconds)
{
Hal()->SendAdjustSystemClock(aDeltaMilliseconds);
@@ -201,7 +201,7 @@ void
SetTimezone(const nsCString& aTimezoneSpec)
{
Hal()->SendSetTimezone(nsCString(aTimezoneSpec));
}
}
nsCString
GetTimezone()
@@ -466,6 +466,23 @@ bool IsHeadphoneEventFromInputDev()
return false;
}
nsresult StartSystemService(const char* aSvcName, const char* aArgs)
{
NS_RUNTIMEABORT("System services cannot be controlled from sandboxed contexts.");
return NS_ERROR_NOT_IMPLEMENTED;
}
void StopSystemService(const char* aSvcName)
{
NS_RUNTIMEABORT("System services cannot be controlled from sandboxed contexts.");
}
bool SystemServiceIsRunning(const char* aSvcName)
{
NS_RUNTIMEABORT("System services cannot be controlled from sandboxed contexts.");
return false;
}
class HalParent : public PHalParent
, public BatteryObserver
, public NetworkObserver
@@ -703,14 +720,14 @@ public:
return true;
}
virtual bool
virtual bool
RecvSetTimezone(const nsCString& aTimezoneSpec) override
{
if (!AssertAppProcessPermission(this, "time")) {
return false;
}
hal::SetTimezone(aTimezoneSpec);
return true;
return true;
}
virtual bool
@@ -768,13 +785,13 @@ public:
hal::RegisterSensorObserver(aSensor, this);
return true;
}
virtual bool
RecvDisableSensorNotifications(const SensorType &aSensor) override {
hal::UnregisterSensorObserver(aSensor, this);
return true;
}
void Notify(const SensorData& aSensorData) override {
Unused << SendNotifySensorChange(aSensorData);
}
@@ -799,7 +816,7 @@ public:
hal::RegisterWakeLockObserver(this);
return true;
}
virtual bool
RecvDisableWakeLockNotifications() override
{
@@ -813,7 +830,7 @@ public:
hal::GetWakeLockInfo(aTopic, aWakeLockInfo);
return true;
}
void Notify(const WakeLockInformation& aWakeLockInfo) override
{
Unused << SendNotifyWakeLockChange(aWakeLockInfo);
@@ -951,7 +968,7 @@ public:
bool
HalChild::RecvNotifySensorChange(const hal::SensorData &aSensorData) {
hal::NotifySensorChange(aSensorData);
return true;
}
+2 -2
View File
@@ -42,14 +42,14 @@ hnjFopen(const char* aURISpec, const char* aMode)
rv = NS_NewChannel(getter_AddRefs(channel),
uri,
nsContentUtils::GetSystemPrincipal(),
nsILoadInfo::SEC_NORMAL,
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nsIContentPolicy::TYPE_OTHER);
if (NS_FAILED(rv)) {
return nullptr;
}
nsCOMPtr<nsIInputStream> instream;
rv = channel->Open(getter_AddRefs(instream));
rv = channel->Open2(getter_AddRefs(instream));
if (NS_FAILED(rv)) {
return nullptr;
}

Some files were not shown because too many files have changed in this diff Show More