Merge autoland to mozilla-central. a=merge

This commit is contained in:
Iulian Moraru 2022-03-02 18:39:51 +02:00
commit 34a08b349e
64 changed files with 670 additions and 472 deletions

2
Cargo.lock generated
View File

@ -5753,8 +5753,6 @@ dependencies = [
"app_units",
"bitflags",
"byteorder",
"core-foundation",
"core-graphics",
"crossbeam-channel",
"derive_more",
"euclid",

View File

@ -43,10 +43,10 @@
color: var(--urlbar-box-hover-text-color);
}
.identity-box-button:not(:active):-moz-focusring,
#tracking-protection-icon-container:not(:active):-moz-focusring {
outline: var(--toolbarbutton-focus-outline);
outline-offset: -2px;
.identity-box-button:not(:active):focus-visible,
#tracking-protection-icon-container:not(:active):focus-visible {
outline: var(--focus-outline);
outline-offset: calc(-1 * var(--focus-outline-width));
}
.identity-box-button {

View File

@ -24,10 +24,10 @@
fill: currentColor;
}
.blocked-permission-icon:-moz-focusring,
.notification-anchor-icon:-moz-focusring {
outline: var(--toolbarbutton-focus-outline);
outline-offset: calc(var(--urlbar-icon-padding) - 2px);
.blocked-permission-icon:focus-visible,
.notification-anchor-icon:focus-visible {
outline: var(--focus-outline);
outline-offset: calc(var(--urlbar-icon-padding) - var(--focus-outline-width));
}
/* This class can be used alone or in combination with the class defining the

View File

@ -20,10 +20,6 @@
--toolbarbutton-height: 0;
}
:root {
--toolbarbutton-focus-outline: var(--focus-outline);
}
:root[uidensity=compact] {
--toolbarbutton-outer-padding: 3px;
--toolbarbutton-inner-padding: 6px;
@ -188,30 +184,25 @@ toolbar .toolbarbutton-1:not([disabled=true]):is([open],[checked],:hover:active)
}
/* Keyboard focus styling */
#PersonalToolbar .toolbarbutton-1:-moz-focusring,
findbar toolbarbutton.tabbable:-moz-focusring,
toolbarbutton.bookmark-item:not(.subviewbutton):-moz-focusring,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-icon,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-text,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-badge-stack {
#PersonalToolbar .toolbarbutton-1:focus-visible,
findbar toolbarbutton.tabbable:focus-visible,
toolbarbutton.bookmark-item:not(.subviewbutton):focus-visible,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-icon,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-text,
toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-badge-stack {
color: inherit;
outline: var(--toolbarbutton-focus-outline);
outline: var(--focus-outline);
outline-offset: calc(var(--focus-outline-width) * -1);
}
:root[uidensity=compact] findbar toolbarbutton.tabbable:-moz-focusring,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-icon,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-text,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:-moz-focusring > .toolbarbutton-badge-stack {
:root[uidensity=compact] findbar toolbarbutton.tabbable:focus-visible,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-icon,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-text,
:root[uidensity=compact] toolbar:not(#PersonalToolbar) .toolbarbutton-1:focus-visible > .toolbarbutton-badge-stack {
outline-offset: calc(var(--focus-outline-width) * -1 - 1px);
}
#PersonalToolbar .toolbarbutton-1:-moz-focusring,
toolbarbutton.bookmark-item:not(.subviewbutton):-moz-focusring {
outline-offset: -2px;
}
toolbar .toolbarbutton-1:-moz-focusring {
toolbar .toolbarbutton-1:focus-visible {
outline: none;
}

View File

@ -410,9 +410,9 @@
color: var(--urlbar-box-hover-text-color);
}
.urlbar-page-action:-moz-focusring {
outline: var(--toolbarbutton-focus-outline);
outline-offset: -2px;
.urlbar-page-action:focus-visible {
outline: var(--focus-outline);
outline-offset: calc(-1 * var(--focus-outline-width));
}
#urlbar-go-button,

View File

@ -15,7 +15,7 @@ const TEST_URI = `
user-modify: read-only;
}
div {
font-variant-alternates: historical-forms;
-moz-context-properties: fill;
}
</style>
<body>
@ -45,10 +45,10 @@ const TEST_DATA_ALL = [
...TEST_DATA_SELECTED,
{
type: COMPATIBILITY_ISSUE_TYPE.CSS_PROPERTY,
property: "font-variant-alternates",
url: "https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates",
deprecated: true,
experimental: false,
property: "-moz-context-properties",
url: "https://developer.mozilla.org/docs/Web/CSS/-moz-context-properties",
deprecated: false,
experimental: true,
},
];

View File

@ -86,16 +86,16 @@ const TEST_DATA = [
},
{
description: "Test for a property having some issues",
declarations: [{ name: "font-variant-alternates" }],
declarations: [{ name: "-moz-context-properties" }],
browsers: [FIREFOX_1],
expectedIssues: [
{
type: COMPATIBILITY_ISSUE_TYPE.CSS_PROPERTY,
property: "font-variant-alternates",
property: "-moz-context-properties",
url:
"https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates",
deprecated: true,
experimental: false,
"https://developer.mozilla.org/docs/Web/CSS/-moz-context-properties",
deprecated: false,
experimental: true,
unsupportedBrowsers: [FIREFOX_1],
},
],

File diff suppressed because one or more lines are too long

View File

@ -152,8 +152,6 @@ ScreenOrientation::LockOrientationTask::LockOrientationTask(
ScreenOrientation::LockOrientationTask::~LockOrientationTask() = default;
using LockOrientationPromise = MozPromise<bool, bool, false>;
bool ScreenOrientation::LockOrientationTask::OrientationLockContains(
OrientationType aOrientationType) {
return bool(mOrientationLock & OrientationTypeToInternal(aOrientationType));
@ -188,37 +186,56 @@ ScreenOrientation::LockOrientationTask::Run() {
return NS_OK;
}
RefPtr<LockOrientationPromise> lockOrientationPromise =
mScreenOrientation->LockDeviceOrientation(mOrientationLock,
mIsFullscreen);
if (NS_WARN_IF(!lockOrientationPromise)) {
mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
mDocument->ClearOrientationPendingPromise();
return NS_OK;
}
lockOrientationPromise->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}](
const LockOrientationPromise::ResolveOrRejectValue& aValue) {
if (aValue.IsResolve()) {
return NS_OK;
}
self->mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
self->mDocument->ClearOrientationPendingPromise();
return NS_OK;
});
BrowsingContext* bc = mDocument->GetBrowsingContext();
if (OrientationLockContains(bc->GetCurrentOrientationType()) ||
(mOrientationLock == hal::ScreenOrientation::Default &&
bc->GetCurrentOrientationAngle() == 0)) {
// Orientation lock will not cause an orientation change.
if (!bc) {
mPromise->MaybeResolveWithUndefined();
mDocument->ClearOrientationPendingPromise();
return NS_OK;
}
OrientationType previousOrientationType = bc->GetCurrentOrientationType();
mScreenOrientation->LockDeviceOrientation(mOrientationLock, mIsFullscreen)
->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}, previousOrientationType](
const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
if (self->mPromise->State() != Promise::PromiseState::Pending) {
// mPromise is already resolved or rejected by
// DispatchChangeEventAndResolvePromise() or
// AbortInProcessOrientationPromises().
return;
}
if (self->mDocument->GetOrientationPendingPromise() !=
self->mPromise) {
// mPromise is old promise now and document has new promise by
// later `orientation.lock` call. Old promise is already rejected
// by AbortInProcessOrientationPromises()
return;
}
if (aValue.IsResolve()) {
// LockDeviceOrientation won't change orientation, so change
// event isn't fired.
if (BrowsingContext* bc = self->mDocument->GetBrowsingContext()) {
OrientationType currentOrientationType =
bc->GetCurrentOrientationType();
if ((previousOrientationType == currentOrientationType &&
self->OrientationLockContains(currentOrientationType)) ||
(self->mOrientationLock ==
hal::ScreenOrientation::Default &&
bc->GetCurrentOrientationAngle() == 0)) {
// Orientation lock will not cause an orientation change, so
// we need to manually resolve the promise here.
self->mPromise->MaybeResolveWithUndefined();
self->mDocument->ClearOrientationPendingPromise();
}
}
return;
}
self->mPromise->MaybeReject(aValue.RejectValue());
self->mDocument->ClearOrientationPendingPromise();
});
return NS_OK;
}
@ -363,10 +380,11 @@ already_AddRefed<Promise> ScreenOrientation::LockInternal(
#endif
}
RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
RefPtr<GenericNonExclusivePromise> ScreenOrientation::LockDeviceOrientation(
hal::ScreenOrientation aOrientation, bool aIsFullscreen) {
if (!GetOwner()) {
return LockOrientationPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
__func__);
}
nsCOMPtr<EventTarget> target = GetOwner()->GetDoc();
@ -375,7 +393,8 @@ RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
// This needs to be done before LockScreenOrientation call to make sure
// the locking can be unlocked.
if (aIsFullscreen && !target) {
return LockOrientationPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
__func__);
}
// We are fullscreen and lock has been accepted.
@ -388,18 +407,13 @@ RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
mFullscreenListener,
/* aUseCapture = */ true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return LockOrientationPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
__func__);
}
}
RefPtr<LockOrientationPromise> halPromise =
hal::LockScreenOrientation(aOrientation);
if (!halPromise) {
return LockOrientationPromise::CreateAndReject(false, __func__);
}
mTriedToLockDeviceOrientation = true;
return halPromise;
return hal::LockScreenOrientation(aOrientation);
}
void ScreenOrientation::Unlock(ErrorResult& aRv) {
@ -569,8 +583,7 @@ void ScreenOrientation::UpdateActiveOrientationLock(
hal::LockScreenOrientation(aOrientation)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[](const mozilla::MozPromise<bool, bool,
false>::ResolveOrRejectValue& aValue) {
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
NS_WARNING_ASSERTION(aValue.IsResolve(),
"hal::LockScreenOrientation failed");
});

View File

@ -74,7 +74,7 @@ class ScreenOrientation final : public DOMEventTargetHelper {
// This method calls into the HAL to lock the device and sets
// up listeners for full screen change.
RefPtr<MozPromise<bool, bool, false>> LockDeviceOrientation(
RefPtr<GenericNonExclusivePromise> LockDeviceOrientation(
hal::ScreenOrientation aOrientation, bool aIsFullscreen);
// This method calls in to the HAL to unlock the device and removes

View File

@ -33,6 +33,8 @@
#if defined(XP_WIN) && defined(ACCESSIBILITY)
# include "mozilla/a11y/AccessibleWrap.h"
# include "mozilla/a11y/Compatibility.h"
# include "mozilla/mscom/ActCtxResource.h"
# include "mozilla/StaticPrefs_accessibility.h"
#endif
#include <map>
#include <utility>
@ -2526,6 +2528,20 @@ bool ContentParent::BeginSubprocessLaunch(ProcessPriority aPriority) {
// processes.
::mozilla::ipc::ExportSharedJSInit(*mSubprocess, extraArgs);
#if defined(XP_WIN) && defined(ACCESSIBILITY)
// Determining the accessibility resource ID causes problems with the sandbox,
// so we pass it on the command line as it is required very early in process
// start up. It is not required when the caching mechanism is being used.
if (!StaticPrefs::accessibility_cache_enabled_AtStartup()) {
// The accessibility resource ID may not be set in some cases, for example
// in xpcshell tests.
auto resourceId = mscom::ActCtxResource::GetAccessibilityResourceId();
if (resourceId) {
geckoargs::sA11yResourceId.Put(resourceId, extraArgs);
}
}
#endif
// Register ContentParent as an observer for changes to any pref
// whose prefix matches the empty string, i.e. all of them. The
// observation starts here in order to capture pref updates that

View File

@ -141,7 +141,7 @@ mozilla::ipc::IPCResult LSObserverChild::RecvObserve(
QM_TRY_INSPECT(const auto& principal,
PrincipalInfoToPrincipal(aPrincipalInfo),
IPC_FAIL_NO_REASON(this));
IPC_FAIL(this, "PrincipalInfoToPrincipal failed!"));
Storage::NotifyChange(/* aStorage */ nullptr, principal, aKey,
aOldValue.AsString(), aNewValue.AsString(),

View File

@ -3221,13 +3221,13 @@ PBackgroundLSDatabaseParent* AllocPBackgroundLSDatabaseParent(
}
if (NS_WARN_IF(!gPreparedDatastores)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
PreparedDatastore* preparedDatastore = gPreparedDatastores->Get(aDatastoreId);
if (NS_WARN_IF(!preparedDatastore)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
@ -3296,13 +3296,13 @@ PBackgroundLSObserverParent* AllocPBackgroundLSObserverParent(
}
if (NS_WARN_IF(!gPreparedObsevers)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
RefPtr<Observer> observer = gPreparedObsevers->Get(aObserverId);
if (NS_WARN_IF(!observer)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
@ -5495,7 +5495,7 @@ mozilla::ipc::IPCResult Database::RecvDeleteMe() {
IProtocol* mgr = Manager();
if (!PBackgroundLSDatabaseParent::Send__delete__(this)) {
return IPC_FAIL_NO_REASON(mgr);
return IPC_FAIL(mgr, "Send__delete__ failed!");
}
return IPC_OK();
}
@ -5504,8 +5504,7 @@ mozilla::ipc::IPCResult Database::RecvAllowToClose() {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(mAllowedToClose)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mAllowedToClose already set!");
}
AllowToClose();
@ -5520,12 +5519,12 @@ PBackgroundLSSnapshotParent* Database::AllocPBackgroundLSSnapshotParent(
AssertIsOnBackgroundThread();
if (NS_WARN_IF(aIncreasePeakUsage && aMinSize < 0)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
if (NS_WARN_IF(mAllowedToClose)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return nullptr;
}
@ -5692,7 +5691,7 @@ mozilla::ipc::IPCResult Snapshot::RecvDeleteMe() {
IProtocol* mgr = Manager();
if (!PBackgroundLSSnapshotParent::Send__delete__(this)) {
return IPC_FAIL_NO_REASON(mgr);
return IPC_FAIL(mgr, "Send__delete__ failed!");
}
return IPC_OK();
}
@ -5705,13 +5704,11 @@ mozilla::ipc::IPCResult Snapshot::RecvAsyncCheckpoint(
MOZ_ASSERT(mPeakUsage >= mUsage);
if (NS_WARN_IF(aWriteInfos.IsEmpty())) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "aWriteInfos is empty!");
}
if (NS_WARN_IF(mHasOtherProcessObservers)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mHasOtherProcessObservers already set!");
}
mDatastore->BeginUpdateBatch(mUsage);
@ -5760,13 +5757,11 @@ mozilla::ipc::IPCResult Snapshot::RecvAsyncCheckpointAndNotify(
MOZ_ASSERT(mPeakUsage >= mUsage);
if (NS_WARN_IF(aWriteAndNotifyInfos.IsEmpty())) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "aWriteAndNotifyInfos is empty!");
}
if (NS_WARN_IF(!mHasOtherProcessObservers)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mHasOtherProcessObservers is not set!");
}
mDatastore->BeginUpdateBatch(mUsage);
@ -5825,7 +5820,7 @@ mozilla::ipc::IPCResult Snapshot::RecvAsyncFinish() {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return IPC_FAIL(this, "Already finished");
}
@ -5838,7 +5833,7 @@ mozilla::ipc::IPCResult Snapshot::RecvSyncFinish() {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
MOZ_ASSERT_UNLESS_FUZZING(false);
return IPC_FAIL(this, "Already finished");
}
@ -5851,23 +5846,19 @@ mozilla::ipc::IPCResult Snapshot::RecvLoaded() {
AssertIsOnBackgroundThread();
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mFinishReceived already set!");
}
if (NS_WARN_IF(mLoadedReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadedReceived already set!");
}
if (NS_WARN_IF(mLoadedAllItems)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadedAllItems already set!");
}
if (NS_WARN_IF(mLoadKeysReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadKeysReceived already set!");
}
mLoadedReceived = true;
@ -5890,23 +5881,23 @@ mozilla::ipc::IPCResult Snapshot::RecvLoadValueAndMoreItems(
MOZ_ASSERT(mDatastore);
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mFinishReceived already set!");
}
if (NS_WARN_IF(mLoadedReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadedReceived already set!");
}
if (NS_WARN_IF(mLoadedAllItems)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadedAllItems already set!");
}
if (mLoadedItems.Contains(aKey) || mUnknownItems.Contains(aKey)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
if (mLoadedItems.Contains(aKey)) {
return IPC_FAIL(this, "mLoadedItems already contains aKey!");
}
if (mUnknownItems.Contains(aKey)) {
return IPC_FAIL(this, "mUnknownItems already contains aKey!");
}
if (auto entry = mValues.Lookup(aKey)) {
@ -6031,18 +6022,15 @@ mozilla::ipc::IPCResult Snapshot::RecvLoadKeys(nsTArray<nsString>* aKeys) {
MOZ_ASSERT(mDatastore);
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mFinishReceived already set!");
}
if (NS_WARN_IF(mLoadedReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadedReceived already set!");
}
if (NS_WARN_IF(mLoadKeysReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mLoadKeysReceived already set!");
}
mLoadKeysReceived = true;
@ -6062,13 +6050,11 @@ mozilla::ipc::IPCResult Snapshot::RecvIncreasePeakUsage(const int64_t& aMinSize,
MOZ_ASSERT(aSize);
if (NS_WARN_IF(aMinSize <= 0)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "aMinSize not valid!");
}
if (NS_WARN_IF(mFinishReceived)) {
MOZ_CRASH_UNLESS_FUZZING();
return IPC_FAIL_NO_REASON(this);
return IPC_FAIL(this, "mFinishReceived already set!");
}
int64_t size =
@ -6136,7 +6122,7 @@ mozilla::ipc::IPCResult Observer::RecvDeleteMe() {
IProtocol* mgr = Manager();
if (!PBackgroundLSObserverParent::Send__delete__(this)) {
return IPC_FAIL_NO_REASON(mgr);
return IPC_FAIL(mgr, "Send__delete__ failed!");
}
return IPC_OK();
}
@ -6510,7 +6496,7 @@ mozilla::ipc::IPCResult LSRequestBase::RecvCancel() {
IProtocol* mgr = Manager();
if (!PBackgroundLSRequestParent::Send__delete__(this, NS_ERROR_FAILURE)) {
return IPC_FAIL_NO_REASON(mgr);
return IPC_FAIL(mgr, "Send__delete__ failed!");
}
return IPC_OK();

View File

@ -4,6 +4,7 @@
* 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/AbortFollower.h"
#include "mozilla/dom/AbortSignal.h"
#include "mozilla/dom/ReadableStream.h"
#include "mozilla/dom/ReadableStreamDefaultReader.h"
@ -13,9 +14,114 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
namespace mozilla::dom {
struct PipeToReadRequest;
class WriteFinishedPromiseHandler;
class ShutdownActionFinishedPromiseHandler;
// https://streams.spec.whatwg.org/#readable-stream-pipe-to (Steps 14-15.)
//
// This class implements everything that is required to read all chunks from
// the reader (source) and write them to writer (destination), while
// following the constraints given in the spec using our implementation-defined
// behavior.
//
// The cycle-collected references look roughly like this:
// clang-format off
//
// Closed promise <-- ReadableStreamDefaultReader <--> ReadableStream
// | ^ |
// |(PromiseHandler) |(mReader) |(ReadRequest)
// | | |
// |-------------> PipeToPump <-------
// ^ | |
// |---------------| | |
// | | |-------(mLastWrite) -------->
// |(PromiseHandler) | |< ---- (PromiseHandler) ---- Promise
// | | ^
// | |(mWriter) |(mWriteRequests)
// | v |
// Closed promise <-- WritableStreamDefaultWriter <--------> WritableStream
//
// clang-format on
class PipeToPump final : public AbortFollower {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(PipeToPump)
friend struct PipeToReadRequest;
friend class WriteFinishedPromiseHandler;
friend class ShutdownActionFinishedPromiseHandler;
PipeToPump(Promise* aPromise, ReadableStreamDefaultReader* aReader,
WritableStreamDefaultWriter* aWriter, bool aPreventClose,
bool aPreventAbort, bool aPreventCancel)
: mPromise(aPromise),
mReader(aReader),
mWriter(aWriter),
mPreventClose(aPreventClose),
mPreventAbort(aPreventAbort),
mPreventCancel(aPreventCancel) {}
MOZ_CAN_RUN_SCRIPT void Start(JSContext* aCx, AbortSignal* aSignal);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void RunAbortAlgorithm() override;
private:
~PipeToPump() override = default;
MOZ_CAN_RUN_SCRIPT void PerformAbortAlgorithm(JSContext* aCx,
AbortSignalImpl* aSignal);
MOZ_CAN_RUN_SCRIPT bool SourceOrDestErroredOrClosed(JSContext* aCx);
using ShutdownAction = already_AddRefed<Promise> (*)(
JSContext*, PipeToPump*, JS::Handle<mozilla::Maybe<JS::Value>>,
ErrorResult&);
MOZ_CAN_RUN_SCRIPT void ShutdownWithAction(
JSContext* aCx, ShutdownAction aAction,
JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void ShutdownWithActionAfterFinishedWrite(
JSContext* aCx, ShutdownAction aAction,
JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void Shutdown(
JSContext* aCx, JS::Handle<mozilla::Maybe<JS::Value>> aError);
void Finalize(JSContext* aCx, JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void OnReadFulfilled(JSContext* aCx,
JS::Handle<JS::Value> aChunk,
ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT void OnWriterReady(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void Read(JSContext* aCx);
MOZ_CAN_RUN_SCRIPT void OnSourceClosed(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void OnSourceErrored(JSContext* aCx,
JS::Handle<JS::Value> aError);
MOZ_CAN_RUN_SCRIPT void OnDestClosed(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void OnDestErrored(JSContext* aCx,
JS::Handle<JS::Value> aError);
RefPtr<Promise> mPromise;
RefPtr<ReadableStreamDefaultReader> mReader;
RefPtr<WritableStreamDefaultWriter> mWriter;
RefPtr<Promise> mLastWritePromise;
const bool mPreventClose;
const bool mPreventAbort;
const bool mPreventCancel;
bool mShuttingDown = false;
#ifdef DEBUG
bool mReadChunk = false;
#endif
};
// This is a helper class for PipeToPump that allows it to attach
// member functions as promise handlers.
class PipeToPumpHandler final : public PromiseNativeHandler {

View File

@ -7,125 +7,26 @@
#ifndef mozilla_dom_ReadableStreamPipeTo_h
#define mozilla_dom_ReadableStreamPipeTo_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/AbortFollower.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
#include "mozilla/Attributes.h"
#include "mozilla/AlreadyAddRefed.h"
namespace mozilla::dom {
namespace mozilla {
struct PipeToReadRequest;
class WriteFinishedPromiseHandler;
class ShutdownActionFinishedPromiseHandler;
class ErrorResult;
namespace dom {
class AbortSignal;
class Promise;
class ReadableStream;
class ReadableStreamDefaultReader;
class WritableStream;
class WritableStreamDefaultWriter;
// https://streams.spec.whatwg.org/#readable-stream-pipe-to (Steps 14-15.)
//
// This class implements everything that is required to read all chunks from
// the reader (source) and write them to writer (destination), while
// following the constraints given in the spec using our implementation-defined
// behavior.
//
// The cycle-collected references look roughly like this:
// clang-format off
//
// Closed promise <-- ReadableStreamDefaultReader <--> ReadableStream
// | ^ |
// |(PromiseHandler) |(mReader) |(ReadRequest)
// | | |
// |-------------> PipeToPump <-------
// ^ | |
// |---------------| | |
// | | |-------(mLastWrite) -------->
// |(PromiseHandler) | |< ---- (PromiseHandler) ---- Promise
// | | ^
// | |(mWriter) |(mWriteRequests)
// | v |
// Closed promise <-- WritableStreamDefaultWriter <--------> WritableStream
//
// clang-format on
class PipeToPump final : public AbortFollower {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(PipeToPump)
friend struct PipeToReadRequest;
friend class WriteFinishedPromiseHandler;
friend class ShutdownActionFinishedPromiseHandler;
PipeToPump(Promise* aPromise, ReadableStreamDefaultReader* aReader,
WritableStreamDefaultWriter* aWriter, bool aPreventClose,
bool aPreventAbort, bool aPreventCancel)
: mPromise(aPromise),
mReader(aReader),
mWriter(aWriter),
mPreventClose(aPreventClose),
mPreventAbort(aPreventAbort),
mPreventCancel(aPreventCancel) {}
MOZ_CAN_RUN_SCRIPT void Start(JSContext* aCx, AbortSignal* aSignal);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void RunAbortAlgorithm() override;
private:
~PipeToPump() override = default;
MOZ_CAN_RUN_SCRIPT void PerformAbortAlgorithm(JSContext* aCx,
AbortSignalImpl* aSignal);
MOZ_CAN_RUN_SCRIPT bool SourceOrDestErroredOrClosed(JSContext* aCx);
using ShutdownAction = already_AddRefed<Promise> (*)(
JSContext*, PipeToPump*, JS::Handle<mozilla::Maybe<JS::Value>>,
ErrorResult&);
MOZ_CAN_RUN_SCRIPT void ShutdownWithAction(
JSContext* aCx, ShutdownAction aAction,
JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void ShutdownWithActionAfterFinishedWrite(
JSContext* aCx, ShutdownAction aAction,
JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void Shutdown(
JSContext* aCx, JS::Handle<mozilla::Maybe<JS::Value>> aError);
void Finalize(JSContext* aCx, JS::Handle<mozilla::Maybe<JS::Value>> aError);
MOZ_CAN_RUN_SCRIPT void OnReadFulfilled(JSContext* aCx,
JS::Handle<JS::Value> aChunk,
ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT void OnWriterReady(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void Read(JSContext* aCx);
MOZ_CAN_RUN_SCRIPT void OnSourceClosed(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void OnSourceErrored(JSContext* aCx,
JS::Handle<JS::Value> aError);
MOZ_CAN_RUN_SCRIPT void OnDestClosed(JSContext* aCx, JS::Handle<JS::Value>);
MOZ_CAN_RUN_SCRIPT void OnDestErrored(JSContext* aCx,
JS::Handle<JS::Value> aError);
RefPtr<Promise> mPromise;
RefPtr<ReadableStreamDefaultReader> mReader;
RefPtr<WritableStreamDefaultWriter> mWriter;
RefPtr<Promise> mLastWritePromise;
const bool mPreventClose;
const bool mPreventAbort;
const bool mPreventCancel;
bool mShuttingDown = false;
#ifdef DEBUG
bool mReadChunk = false;
#endif
};
MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> ReadableStreamPipeTo(
ReadableStream* aSource, WritableStream* aDest, bool aPreventClose,
bool aPreventAbort, bool aPreventCancel, AbortSignal* aSignal,
ErrorResult& aRv);
} // namespace mozilla::dom
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ReadableStreamPipeTo_h

View File

@ -46,11 +46,6 @@ use webrender::{
};
use wr_malloc_size_of::MallocSizeOfOps;
#[cfg(target_os = "macos")]
use core_foundation::string::CFString;
#[cfg(target_os = "macos")]
use core_graphics::font::CGFont;
extern "C" {
#[cfg(target_os = "android")]
fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int;
@ -2298,20 +2293,9 @@ fn read_font_descriptor(bytes: &mut WrVecU8, index: u32) -> NativeFontHandle {
#[cfg(target_os = "macos")]
fn read_font_descriptor(bytes: &mut WrVecU8, _index: u32) -> NativeFontHandle {
let chars = bytes.flush_into_vec();
let name = String::from_utf8(chars).unwrap();
let font = match CGFont::from_name(&CFString::new(&*name)) {
Ok(font) => font,
Err(_) => {
// If for some reason we failed to load a font descriptor, then our
// only options are to either abort or substitute a fallback font.
// It is preferable to use a fallback font instead so that rendering
// can at least still proceed in some fashion without erroring.
// Lucida Grande is the fallback font in Gecko, so use that here.
CGFont::from_name(&CFString::from_static_string("Lucida Grande"))
.expect("Failed reading font descriptor and could not load fallback font")
},
};
NativeFontHandle(font)
NativeFontHandle {
name: String::from_utf8(chars).unwrap()
}
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]

View File

@ -32,6 +32,10 @@ use std::sync::Arc;
#[cfg(target_os = "windows")]
use dwrote;
#[cfg(target_os = "macos")]
use core_foundation::string::CFString;
#[cfg(target_os = "macos")]
use core_graphics::font::CGFont;
#[cfg(target_os = "macos")]
use foreign_types::ForeignType;
@ -782,7 +786,19 @@ impl Moz2dBlobImageHandler {
#[cfg(target_os = "macos")]
fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
unsafe { AddNativeFontHandle(key, handle.0.as_ptr() as *mut c_void, 0) };
let font = match CGFont::from_name(&CFString::new(&handle.name)) {
Ok(font) => font,
Err(_) => {
// If for some reason we failed to load a font descriptor, then our
// only options are to either abort or substitute a fallback font.
// It is preferable to use a fallback font instead so that rendering
// can at least still proceed in some fashion without erroring.
// Lucida Grande is the fallback font in Gecko, so use that here.
CGFont::from_name(&CFString::from_static_string("Lucida Grande"))
.expect("Failed reading font descriptor and could not load fallback font")
},
};
unsafe { AddNativeFontHandle(key, font.as_ptr() as *mut c_void, 0) };
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]

2
gfx/wr/Cargo.lock generated
View File

@ -1719,8 +1719,6 @@ dependencies = [
"app_units",
"bitflags",
"byteorder",
"core-foundation 0.9.2",
"core-graphics 0.22.3",
"crossbeam-channel",
"derive_more",
"euclid",

View File

@ -14,7 +14,7 @@ use core_graphics::base::{kCGBitmapByteOrder32Little};
use core_graphics::color_space::CGColorSpace;
use core_graphics::context::CGContext;
use core_graphics::context::{CGBlendMode, CGTextDrawingMode};
use core_graphics::font::CGGlyph;
use core_graphics::font::{CGFont, CGGlyph};
use core_graphics::geometry::{CGAffineTransform, CGPoint, CGSize};
use core_graphics::geometry::{CG_AFFINE_TRANSFORM_IDENTITY, CGRect};
use core_text;
@ -276,16 +276,28 @@ impl FontContext {
// and use the descriptor for that. Normally we'd try to avoid new_from_CGFont
// because that adds the CGFont to the descriptor cache which can keep the CGFont
// around for a long time, but that should be ok for non-web (native) fonts.
let cf_name = CFString::new(&native_font_handle.name);
let name = native_font_handle.0.postscript_name();
// For "hidden" system fonts, whose names start with a period,
// we can't instantiate CTFonts via a descriptor. We're really
// supposed to use CTFontCreateUIFontForLanguage, but for now
// we just use the CGFont.
let desc = if name.to_string().starts_with('.') {
core_text::font::new_from_CGFont(&native_font_handle.0, 0.).copy_descriptor()
let desc = if native_font_handle.name.starts_with('.') {
let cg_font = match CGFont::from_name(&cf_name) {
Ok(cg_font) => cg_font,
Err(_) => {
// If for some reason we failed to load a font descriptor, then our
// only options are to either abort or substitute a fallback font.
// It is preferable to use a fallback font instead so that rendering
// can at least still proceed in some fashion without erroring.
// Lucida Grande is the fallback font in Gecko, so use that here.
CGFont::from_name(&CFString::from_static_string("Lucida Grande"))
.expect("couldn't find font with postscript name and couldn't load fallback font")
}
};
core_text::font::new_from_CGFont(&cg_font, 0.).copy_descriptor()
} else {
core_text::font_descriptor::new_from_postscript_name(&name)
core_text::font_descriptor::new_from_postscript_name(&cf_name)
};
self.ct_font_descs

View File

@ -1970,7 +1970,7 @@ impl ResourceCache {
#[cfg(target_os = "macos")]
FontTemplate::Native(ref native) => {
PlainFontTemplate {
data: native.0.postscript_name().to_string(),
data: native.name.clone(),
index: 0,
}
}

View File

@ -27,7 +27,3 @@ time = "0.1"
malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "wr_malloc_size_of" }
peek-poke = { version = "0.2", path = "../peek-poke", features = ["extras"] }
crossbeam-channel = "0.5"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.9"
core-graphics = "0.22"

View File

@ -2,15 +2,7 @@
* 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/. */
#[cfg(target_os = "macos")]
use core_foundation::string::CFString;
#[cfg(target_os = "macos")]
use core_graphics::font::CGFont;
use peek_poke::PeekPoke;
#[cfg(target_os = "macos")]
use serde::de::{self, Deserialize, Deserializer};
#[cfg(target_os = "macos")]
use serde::ser::{Serialize, Serializer};
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
#[cfg(not(target_os = "macos"))]
@ -206,37 +198,9 @@ pub struct NativeFontHandle {
}
#[cfg(target_os = "macos")]
#[derive(Clone)]
pub struct NativeFontHandle(pub CGFont);
#[cfg(target_os = "macos")]
impl Serialize for NativeFontHandle {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0
.postscript_name()
.to_string()
.serialize(serializer)
}
}
#[cfg(target_os = "macos")]
impl<'de> Deserialize<'de> for NativeFontHandle {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let postscript_name: String = Deserialize::deserialize(deserializer)?;
match CGFont::from_name(&CFString::new(&*postscript_name)) {
Ok(font) => Ok(NativeFontHandle(font)),
Err(_) => Err(de::Error::custom(
"Couldn't find a font with that PostScript name!",
)),
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NativeFontHandle {
pub name: String,
}
#[repr(C)]

View File

@ -24,10 +24,6 @@ extern crate bitflags;
extern crate byteorder;
#[cfg(feature = "nightly")]
extern crate core;
#[cfg(target_os = "macos")]
extern crate core_foundation;
#[cfg(target_os = "macos")]
extern crate core_graphics;
extern crate derive_more;
#[macro_use]
extern crate malloc_size_of_derive;

View File

@ -378,7 +378,7 @@ void NotifyWakeLockChange(const WakeLockInformation& aInfo) {
WakeLockObservers()->BroadcastInformation(aInfo);
}
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
const ScreenOrientation& aOrientation) {
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), nullptr);

View File

@ -220,8 +220,8 @@ void NotifyWakeLockChange(const hal::WakeLockInformation& aWakeLockInfo);
* Lock the screen orientation to the specific orientation.
* @return A promise indicating that the screen orientation has been locked.
*/
[[nodiscard]] RefPtr<mozilla::MozPromise<bool, bool, false>>
LockScreenOrientation(const hal::ScreenOrientation& aOrientation);
[[nodiscard]] RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
const hal::ScreenOrientation& aOrientation);
/**
* Unlock the screen orientation.

View File

@ -101,25 +101,39 @@ static bool IsSupportedScreenOrientation(hal::ScreenOrientation aOrientation) {
return false;
}
RefPtr<MozPromise<bool, bool, false>> LockScreenOrientation(
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
const hal::ScreenOrientation& aOrientation) {
using LockPromise = MozPromise<bool, bool, false>;
if (!IsSupportedScreenOrientation(aOrientation)) {
NS_WARNING("Unsupported screen orientation type");
return LockPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
}
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
if (!runtime) {
return LockPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
__func__);
}
auto result = runtime->LockScreenOrientation(uint32_t(aOrientation));
auto geckoResult = java::GeckoResult::LocalRef(std::move(result));
if (!geckoResult) {
return LockPromise::CreateAndReject(false, __func__);
return GenericNonExclusivePromise::FromGeckoResult(geckoResult)
->Then(
GetCurrentSerialEventTarget(), __func__,
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
if (aValue.IsResolve()) {
if (aValue.ResolveValue()) {
return GenericNonExclusivePromise::CreateAndResolve(true,
__func__);
}
return LockPromise::FromGeckoResult(geckoResult);
// Delegated orientation controller returns failure for
// lock.
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_DOM_ABORT_ERR, __func__);
}
// Browser side doesn't implement orientation delegate.
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
});
}
void UnlockScreenOrientation() {

View File

@ -6,10 +6,10 @@
namespace mozilla::hal_impl {
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
const hal::ScreenOrientation& aOrientation) {
return mozilla::MozPromise<bool, bool, false>::CreateAndReject(false,
__func__);
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
}
void UnlockScreenOrientation() {}

View File

@ -82,7 +82,7 @@ parent:
returns (WakeLockInformation aWakeLockInfo);
async LockScreenOrientation(ScreenOrientation aOrientation)
returns (bool allowed);
returns (nsresult result);
async UnlockScreenOrientation();
child:

View File

@ -69,20 +69,23 @@ void GetCurrentNetworkInformation(NetworkInformation* aNetworkInfo) {
Hal()->SendGetCurrentNetworkInformation(aNetworkInfo);
}
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
const hal::ScreenOrientation& aOrientation) {
return Hal()
->SendLockScreenOrientation(aOrientation)
->Then(
GetCurrentSerialEventTarget(), __func__,
[=](const mozilla::MozPromise<bool, ipc::ResponseRejectReason,
->Then(GetCurrentSerialEventTarget(), __func__,
[](const mozilla::MozPromise<nsresult, ipc::ResponseRejectReason,
true>::ResolveOrRejectValue& aValue) {
if (aValue.IsResolve() && aValue.ResolveValue()) {
return mozilla::MozPromise<bool, bool, false>::CreateAndResolve(
if (aValue.IsResolve()) {
if (NS_SUCCEEDED(aValue.ResolveValue())) {
return GenericNonExclusivePromise::CreateAndResolve(
true, __func__);
}
return mozilla::MozPromise<bool, bool, false>::CreateAndReject(
false, __func__);
return GenericNonExclusivePromise::CreateAndReject(
aValue.ResolveValue(), __func__);
}
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_FAILURE, __func__);
});
}
@ -223,14 +226,16 @@ class HalParent : public PHalParent,
// fullscreen. We don't have that information currently.
hal::LockScreenOrientation(aOrientation)
->Then(GetMainThreadSerialEventTarget(), __func__,
[aResolve](const mozilla::MozPromise<
bool, bool, false>::ResolveOrRejectValue& aValue) {
->Then(
GetMainThreadSerialEventTarget(), __func__,
[aResolve](const GenericNonExclusivePromise::ResolveOrRejectValue&
aValue) {
if (aValue.IsResolve()) {
aResolve(aValue.ResolveValue());
} else {
aResolve(false);
MOZ_ASSERT(aValue.ResolveValue());
aResolve(NS_OK);
return;
}
aResolve(aValue.RejectValue());
});
return IPC_OK();
}

View File

@ -59,7 +59,9 @@ ProcessRuntime::ProcessRuntime(const ProcessCategory aProcessCategory)
# if defined(MOZILLA_INTERNAL_API)
// If we're inside XUL, and we're the parent process, then we trust that
// this has already been initialized for us prior to XUL being loaded.
if (aProcessCategory != ProcessCategory::GeckoBrowserParent) {
// Only required in the child if the Resource ID has been passed down.
if (aProcessCategory != ProcessCategory::GeckoBrowserParent &&
ActCtxResource::GetAccessibilityResourceId()) {
mActCtxRgn.emplace(ActCtxResource::GetAccessibilityResource());
}
# elif defined(MOZ_HAS_MOZGLUE)

View File

@ -195,23 +195,43 @@ static HMODULE GetContainingModuleHandle() {
return thisModule;
}
ActCtxResource ActCtxResource::GetAccessibilityResource() {
ActCtxResource result = {};
result.mModule = GetContainingModuleHandle();
static uint16_t sActCtxResourceId = 0;
/* static */
void ActCtxResource::SetAccessibilityResourceId(uint16_t aResourceId) {
sActCtxResourceId = aResourceId;
}
/* static */
uint16_t ActCtxResource::GetAccessibilityResourceId() {
return sActCtxResourceId;
}
static void EnsureAccessibilityResourceId() {
if (!sActCtxResourceId) {
#if defined(HAVE_64BIT_BUILD)
// The manifest for 64-bit Windows is embedded with resource ID 64.
result.mId = 64;
sActCtxResourceId = 64;
#else
// The manifest for 32-bit Windows is embedded with resource ID 32.
// Beginning with Windows 10 Creators Update, 32-bit builds always use the
// 64-bit manifest. Older builds of Windows may or may not require the 64-bit
// manifest: UseIAccessibleProxyStub() determines the course of action.
// 64-bit manifest. Older builds of Windows may or may not require the
// 64-bit manifest: UseIAccessibleProxyStub() determines the course of
// action.
if (mozilla::IsWin10CreatorsUpdateOrLater() || UseIAccessibleProxyStub()) {
result.mId = 64;
sActCtxResourceId = 64;
} else {
result.mId = 32;
sActCtxResourceId = 32;
}
#endif // defined(HAVE_64BIT_BUILD)
}
}
ActCtxResource ActCtxResource::GetAccessibilityResource() {
ActCtxResource result = {};
result.mModule = GetContainingModuleHandle();
EnsureAccessibilityResourceId();
result.mId = GetAccessibilityResourceId();
return result;
}

View File

@ -16,6 +16,17 @@ struct ActCtxResource {
uint16_t mId;
HMODULE mModule;
/**
* Set the resource ID used by GetAccessibilityResource. This is so that
* sandboxed child processes can use a value passed down from the parent.
*/
static MFBT_API void SetAccessibilityResourceId(uint16_t aResourceId);
/**
* Get the resource ID used by GetAccessibilityResource.
*/
static MFBT_API uint16_t GetAccessibilityResourceId();
/**
* @return ActCtxResource of a11y manifest resource to be passed to
* mscom::ActivationContext

View File

@ -0,0 +1,11 @@
<style>
* {
rotate: 93deg 6 0 -1;
}
</style>
<script>
window.onload = () => {
document.execCommand("selectAll", false);
}
</script>
<textarea>a</textarea>

View File

@ -564,4 +564,5 @@ load 1729578.html
load 1729581.html
load 1734007.html
load 1745860.html
pref(layout.accessiblecaret.enabled,true) load 1746989.html
load 1752649.html

View File

@ -2441,11 +2441,12 @@ nsLayoutUtils::TransformResult nsLayoutUtils::TransformRect(
0.5f,
std::numeric_limits<Float>::max() * devPixelsPerAppUnitFromFrame,
std::numeric_limits<Float>::max() * devPixelsPerAppUnitFromFrame));
aRect.x = NSToCoordRound(toDevPixels.x / devPixelsPerAppUnitToFrame);
aRect.y = NSToCoordRound(toDevPixels.y / devPixelsPerAppUnitToFrame);
aRect.width = NSToCoordRound(toDevPixels.width / devPixelsPerAppUnitToFrame);
aRect.x = NSToCoordRoundWithClamp(toDevPixels.x / devPixelsPerAppUnitToFrame);
aRect.y = NSToCoordRoundWithClamp(toDevPixels.y / devPixelsPerAppUnitToFrame);
aRect.width =
NSToCoordRoundWithClamp(toDevPixels.width / devPixelsPerAppUnitToFrame);
aRect.height =
NSToCoordRound(toDevPixels.height / devPixelsPerAppUnitToFrame);
NSToCoordRoundWithClamp(toDevPixels.height / devPixelsPerAppUnitToFrame);
return TRANSFORM_SUCCEEDED;
}
@ -9237,7 +9238,9 @@ static nsSize ComputeMaxSizeForPartialPrerender(nsIFrame* aFrame,
// so that the result bound's width and height would be pretty much same
// as the one rotated by the inverse matrix.
result = transform2D.TransformBounds(result);
return nsSize(result.width, result.height);
return nsSize(
result.width < (float)nscoord_MAX ? result.width : nscoord_MAX,
result.height < (float)nscoord_MAX ? result.height : nscoord_MAX);
}
/* static */

View File

@ -525,6 +525,8 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
return;
}
mSizedToPopup = aSizedToPopup;
SchedulePaint();
bool shouldPosition = [&] {
@ -694,16 +696,13 @@ void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
if (needCallback && !mReflowCallbackData.mPosted) {
pc->PresShell()->PostReflowCallback(this);
mReflowCallbackData.MarkPosted(aParentMenu, aSizedToPopup, openChanged);
mReflowCallbackData.MarkPosted(aParentMenu, openChanged);
}
}
bool nsMenuPopupFrame::ReflowFinished() {
SetPopupPosition(mReflowCallbackData.mAnchor, false,
mReflowCallbackData.mSizedToPopup);
SetPopupPosition(mReflowCallbackData.mAnchor, false, mSizedToPopup);
mReflowCallbackData.Clear();
return false;
}
@ -2415,7 +2414,7 @@ void nsMenuPopupFrame::MoveTo(const CSSPoint& aPos, bool aUpdateAttrs) {
mAnchorType = MenuPopupAnchorType_Point;
mScreenRect.MoveTo(appUnitsPos);
SetPopupPosition(nullptr, true, false);
SetPopupPosition(nullptr, true, mSizedToPopup);
RefPtr<Element> popup = mContent->AsElement();
if (aUpdateAttrs && (popup->HasAttr(kNameSpaceID_None, nsGkAtoms::left) ||

View File

@ -562,6 +562,9 @@ class nsMenuPopupFrame final : public nsBoxFrame,
// Used for store rectangle which the popup is going to be anchored to,
// we need that for Wayland
nsRect mAnchorRect;
// Store SizedToPopup attribute for MoveTo call to avoid
// unwanted popup resize there.
bool mSizedToPopup = false;
// If the panel prefers to "slide" rather than resize, then the arrow gets
// positioned at this offset (along either the x or y axis, depending on
@ -585,26 +588,19 @@ class nsMenuPopupFrame final : public nsBoxFrame,
struct ReflowCallbackData {
ReflowCallbackData()
: mPosted(false),
mAnchor(nullptr),
mSizedToPopup(false),
mIsOpenChanged(false) {}
void MarkPosted(nsIFrame* aAnchor, bool aSizedToPopup,
bool aIsOpenChanged) {
: mPosted(false), mAnchor(nullptr), mIsOpenChanged(false) {}
void MarkPosted(nsIFrame* aAnchor, bool aIsOpenChanged) {
mPosted = true;
mAnchor = aAnchor;
mSizedToPopup = aSizedToPopup;
mIsOpenChanged = aIsOpenChanged;
}
void Clear() {
mPosted = false;
mAnchor = nullptr;
mSizedToPopup = false;
mIsOpenChanged = false;
}
bool mPosted;
nsIFrame* mAnchor;
bool mSizedToPopup;
bool mIsOpenChanged;
};
ReflowCallbackData mReflowCallbackData;

View File

@ -178,4 +178,34 @@ class OrientationDelegateTest : BaseSessionTest() {
}
})
}
@Test fun orientationLockUnsupported() {
// If no delegate, orientation.lock must throws NotSupportedError
sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
goFullscreen()
val promise = mainSession.evaluatePromiseJS("""
new Promise(r => {
screen.orientation.lock('landscape-primary')
.then(() => r("successful"))
.catch(e => r(e.name))
})
""".trimIndent())
assertThat("The operation must throw NotSupportedError",
promise.value,
equalTo("NotSupportedError"))
val promise2 = mainSession.evaluatePromiseJS("""
new Promise(r => {
screen.orientation.lock(screen.orientation.type)
.then(() => r("successful"))
.catch(e => r(e.name))
})
""".trimIndent())
assertThat("The operation must throw NotSupportedError even if same orientation",
promise2.value,
equalTo("NotSupportedError"))
}
}

View File

@ -919,16 +919,18 @@ public final class GeckoRuntime implements Parcelable {
final OrientationController.OrientationDelegate delegate =
getOrientationController().getDelegate();
if (delegate == null) {
res.complete(false);
} else {
// Delegate is not set
res.completeExceptionally(new Exception("Not supported"));
return;
}
final GeckoResult<AllowOrDeny> response =
delegate.onOrientationLock(toAndroidOrientation(aOrientation));
if (response == null) {
res.complete(false);
} else {
// Delegate is default. So lock orientation is not implemented
res.completeExceptionally(new Exception("Not supported"));
return;
}
res.completeFrom(response.map(v -> v == AllowOrDeny.ALLOW));
}
}
});
return res;
}

View File

@ -362,7 +362,7 @@ function auth_handler(metadata, response) {
}
let httpserv;
function setup() {
add_setup(() => {
Services.prefs.setBoolPref("network.auth.force-generic-ntlm", true);
Services.prefs.setBoolPref("network.auth.force-generic-ntlm-v1", true);
Services.prefs.setBoolPref("network.dns.native-is-localhost", true);
@ -380,8 +380,7 @@ function setup() {
await httpserv.stop();
});
}
setup();
});
add_task(async function test_ntlm_first() {
Services.prefs.setBoolPref(

View File

@ -226,10 +226,14 @@ event.sendKeys = function(keyString, win) {
}
for (let i = 0; i < keyString.length; i++) {
const rawKey = keyString.charAt(i);
const key = { ...keyData.getData(rawKey), ...modifiers };
if (key.modifier) {
modifiers[key.modifier] = true;
let keyValue = keyString.charAt(i);
if (modifiers.shiftKey) {
keyValue = keyData.getShiftedKey(keyValue);
}
const data = keyData.getData(keyValue);
const key = { ...data, ...modifiers };
if (data.modifier) {
modifiers[data.modifier] = true;
}
event.sendSingleKey(key, win);
}

View File

@ -171,6 +171,11 @@ class WebDriverBiDiConnection extends WebSocketConnection {
} else {
assert.session(this.session);
// Bug 1741854 - Workaround to deny internal methods to be called
if (command.startsWith("_")) {
throw new error.UnknownCommandError(method);
}
// Finally, instruct the session to execute the command
result = await this.session.execute(module, command, params);
}

View File

@ -161,6 +161,7 @@ flatpak build-finish build \
--talk-name=org.freedesktop.Notifications \
--own-name="org.mpris.MediaPlayer2.firefox.*" \
--own-name="org.mozilla.firefox.*" \
--own-name="org.mozilla.firefox_beta.*" \
--command=firefox
flatpak build-export --disable-sandbox --no-update-summary --exclude='/share/runtime/langpack/*/*' repo build "$FLATPAK_BRANCH"

View File

@ -0,0 +1,4 @@
[errors.py]
disabled:
if release_or_beta: https://bugzilla.mozilla.org/show_bug.cgi?id=1712902

View File

@ -0,0 +1,9 @@
import pytest
from webdriver.bidi.error import UnknownCommandException
@pytest.mark.asyncio
async def test_internal_method(bidi_session, send_blocking_command):
with pytest.raises(UnknownCommandException):
await send_blocking_command("log._applySessionData", {})

View File

@ -9,5 +9,6 @@ sys.path.insert(0, os.path.join(webdriver_path))
pytest_plugins = [
"tests.support.fixtures",
"tests.support.fixtures_bidi",
"tests.support.fixtures_http",
]

View File

@ -13,6 +13,7 @@ module.exports = {
Cu: true,
AppConstants: true,
ExtensionAPI: true,
ExtensionAPIPersistent: true,
ExtensionCommon: true,
ExtensionUtils: true,
extensions: true,

View File

@ -160,13 +160,14 @@ Services.obs.addObserver(StrongPromise, "extensions-onMessage-witness");
// Simple single-event emitter-like helper, exposes the EventManager api.
class SimpleEventAPI extends EventManager {
constructor(context, name) {
super({ context, name });
this.fires = new Set();
this.register = fire => {
this.fires.add(fire);
let fires = new Set();
let register = fire => {
fires.add(fire);
fire.location = context.getCaller();
return () => this.fires.delete(fire);
return () => fires.delete(fire);
};
super({ context, name, register });
this.fires = fires;
}
emit(...args) {
return [...this.fires].map(fire => fire.asyncWithoutClone(...args));

View File

@ -363,6 +363,72 @@ class ExtensionAPI extends EventEmitter {
}
}
/**
* Subclass to add APIs commonly used with persistent events.
* If a namespace uses events, it should use this subclass.
*
* this.apiNamespace = class extends ExtensionAPIPersistent {};
*/
class ExtensionAPIPersistent extends ExtensionAPI {
/**
* Check for event entry.
*
* @param {string} event The event name e.g. onStateChanged
* @returns {boolean}
*/
hasEventRegistrar(event) {
return (
this.PERSISTENT_EVENTS && Object.hasOwn(this.PERSISTENT_EVENTS, event)
);
}
/**
* Get the event registration fuction
*
* @param {string} event The event name e.g. onStateChanged
* @returns {Function} register is used to start the listener
* register returns an object containing
* a convert and unregister function.
*/
getEventRegistrar(event) {
if (this.hasEventRegistrar(event)) {
return this.PERSISTENT_EVENTS[event].bind(this);
}
}
/**
* Used when instantiating an EventManager instance to register the listener.
*
* @param {Object} options used for event registration
* @param {BaseContext} options.context Passed when creating an EventManager instance.
* @param {string} options.event The function passed to the listener to fire the event.
* @param {Function} options.fire The function passed to the listener to fire the event.
* @returns {Function} the unregister function used in the EventManager.
*/
registerEventListener(options) {
let register = this.getEventRegistrar(options.event);
if (register) {
return register(options).unregister;
}
}
/**
* Used to prime a listener for when the background script is not running.
*
* @param {string} event The event name e.g. onStateChanged or captiveURL.onChange.
* @param {Function} fire The function passed to the listener to fire the event.
* @param {Array} params Params passed to the event listener.
* @param {boolean} isInStartup unused here but passed for subclass use.
* @returns {Object} the unregister and convert functions used in the EventManager.
*/
primeListener(event, fire, params, isInStartup) {
let register = this.getEventRegistrar(event);
if (register) {
return register({ fire, isInStartup }, ...params);
}
}
}
/**
* A wrapper around a window that returns the window iff the inner window
* matches the inner window at the construction of this wrapper.
@ -1743,6 +1809,7 @@ class SchemaAPIManager extends EventEmitter {
Cr,
Cu,
ExtensionAPI,
ExtensionAPIPersistent,
ExtensionCommon,
MatchGlob,
MatchPattern,
@ -2145,6 +2212,9 @@ class EventManager {
* The API module name, required for persistent events.
* @param {string} params.event
* The API event name, required for persistent events.
* @param {ExtensionAPI} params.extensionApi
* The API intance. If the API uses the ExtensionAPIPersistent class, some simplification is
* possible by passing the api (self or this) and the internal register function will be used.
* @param {string} [params.name]
* A name used only for debugging. If not provided, name is built from module and event.
* @param {functon} params.register
@ -2160,6 +2230,7 @@ class EventManager {
event,
name,
register,
extensionApi,
inputHandling = false,
} = params;
this.context = context;
@ -2168,11 +2239,21 @@ class EventManager {
this.name = name;
this.register = register;
this.inputHandling = inputHandling;
if (!name) {
this.name = `${module}.${event}`;
}
if (!this.register && extensionApi instanceof ExtensionAPIPersistent) {
this.register = fire => {
return extensionApi.registerEventListener({ context, event, fire });
};
}
if (!this.register) {
throw new Error(
`EventManager requires register method for ${this.name}.`
);
}
this.canPersistEvents =
module &&
event &&
@ -2328,7 +2409,6 @@ class EventManager {
try {
let handler = api.primeListener(
extension,
event,
fire,
listener.params,

View File

@ -102,7 +102,7 @@ this.alarms = class extends ExtensionAPI {
};
}
primeListener(extension, event, fire) {
primeListener(event, fire) {
if (event == "onAlarm") {
return this.registerOnAlarm(fire);
}

View File

@ -375,7 +375,8 @@ this.browserSettings = class extends ExtensionAPI {
};
}
primeListener(extension, event, fire) {
primeListener(event, fire) {
let { extension } = this;
if (event == "homepageOverride") {
return this.homePageOverrideListener(fire);
}

View File

@ -29,7 +29,7 @@ const CAPTIVE_URL_PREF = "captivedetect.canonicalURL";
var { ExtensionError } = ExtensionUtils;
this.captivePortal = class extends ExtensionAPI {
this.captivePortal = class extends ExtensionAPIPersistent {
checkCaptivePortalEnabled() {
if (!gCaptivePortalEnabled) {
throw new ExtensionError("Captive Portal detection is not enabled");
@ -52,7 +52,7 @@ this.captivePortal = class extends ExtensionAPI {
}
PERSISTENT_EVENTS = {
onStateChanged: fire => {
onStateChanged({ fire }) {
this.checkCaptivePortalEnabled();
let observer = (subject, topic) => {
@ -75,7 +75,7 @@ this.captivePortal = class extends ExtensionAPI {
},
};
},
onConnectivityAvailable: fire => {
onConnectivityAvailable({ fire }) {
this.checkCaptivePortalEnabled();
let observer = (subject, topic, data) => {
@ -95,7 +95,7 @@ this.captivePortal = class extends ExtensionAPI {
},
};
},
"captiveURL.onChange": fire => {
"captiveURL.onChange": ({ fire }) => {
let listener = (text, id) => {
fire.async({
levelOfControl: "not_controllable",
@ -114,12 +114,6 @@ this.captivePortal = class extends ExtensionAPI {
},
};
primeListener(extension, event, fire) {
if (Object.hasOwn(this.PERSISTENT_EVENTS, event)) {
return this.PERSISTENT_EVENTS[event](fire);
}
}
getAPI(context) {
let self = this;
return {
@ -136,18 +130,13 @@ this.captivePortal = class extends ExtensionAPI {
context,
module: "captivePortal",
event: "onStateChanged",
register: fire => {
return self.PERSISTENT_EVENTS.onStateChanged(fire).unregister;
},
extensionApi: self,
}).api(),
onConnectivityAvailable: new EventManager({
context,
module: "captivePortal",
event: "onConnectivityAvailable",
register: fire => {
return self.PERSISTENT_EVENTS.onConnectivityAvailable(fire)
.unregister;
},
extensionApi: self,
}).api(),
canonicalURL: getSettingsAPI({
context,
@ -160,10 +149,7 @@ this.captivePortal = class extends ExtensionAPI {
context,
module: "captivePortal",
event: "captiveURL.onChange",
register: fire => {
return self.PERSISTENT_EVENTS["captiveURL.onChange"](fire)
.unregister;
},
extensionApi: self,
}).api(),
}),
},

View File

@ -450,7 +450,8 @@ ExtensionPreferencesManager.addSetting("network.tlsVersionRestriction", {
});
this.privacy = class extends ExtensionAPI {
primeListener(extension, event, fire) {
primeListener(event, fire) {
let { extension } = this;
let listener = getPrimedSettingsListener({
extension,
name: event,

View File

@ -125,9 +125,14 @@ function registerProxyFilterEvent(
}
this.proxy = class extends ExtensionAPI {
primeListener(extension, event, fire, params) {
primeListener(event, fire, params) {
if (event === "onRequest") {
return registerProxyFilterEvent(undefined, extension, fire, ...params);
return registerProxyFilterEvent(
undefined,
this.extension,
fire,
...params
);
}
}

View File

@ -123,10 +123,10 @@ function makeWebRequestEvent(context, event) {
}
this.webRequest = class extends ExtensionAPI {
primeListener(extension, event, fire, params, isInStartup) {
primeListener(event, fire, params, isInStartup) {
// During early startup if the listener does not use blocking we do not prime it.
if (!isInStartup || params[1]?.includes("blocking")) {
return registerEvent(extension, event, fire, ...params);
return registerEvent(this.extension, event, fire, ...params);
}
}

View File

@ -11,7 +11,7 @@ const { ExtensionAPI } = ExtensionCommon;
/* global EventManager */
const API = class extends ExtensionAPI {
static namespace = undefined;
primeListener(extension, event, fire, params) {
primeListener(event, fire, params) {
// eslint-disable-next-line no-undef
let { eventName, throwError, ignoreListener } =
this.constructor.testOptions || {};

View File

@ -748,8 +748,9 @@ HttpObserverManager = {
// errorCheck is called in ChannelWrapper::onStartRequest, we should check
// the errorString after onStartRequest to make sure errors have a chance
// to be processed before we fall back to a generic error string.
let onStart = function() {
channel.removeEventListener("start", onStart);
channel.addEventListener(
"start",
() => {
if (!channel.errorString) {
this.runChannelListener(channel, "onErrorOccurred", {
error:
@ -757,8 +758,9 @@ HttpObserverManager = {
`NS_ERROR_NET_UNKNOWN_${lastActivity}`,
});
}
};
channel.addEventListener("start", onStart);
},
{ once: true }
);
} else if (
lastActivity !== this.GOOD_LAST_ACTIVITY &&
lastActivity !==

View File

@ -121,19 +121,20 @@ notification[type="critical"] > hbox > .messageImage {
.messageCloseButton > .toolbarbutton-icon {
padding: 6px;
/* Override width from close-icon.css */
width: 32px !important;
width: 32px;
/* Close button needs to be clickable from the edge of the window */
margin-inline-end: 8px;
}
.messageCloseButton:-moz-focusring {
.messageCloseButton:focus-visible {
/* Override the dotted outline from button.css */
outline: none;
}
.messageCloseButton:-moz-focusring > .toolbarbutton-icon {
outline: var(--toolbarbutton-focus-outline, 2px solid currentColor);
.messageCloseButton:focus-visible > .toolbarbutton-icon {
outline: var(--focus-outline);
outline-offset: calc(var(--focus-outline-width) * -1);
border-radius: var(--toolbarbutton-border-radius, 4px);
}
.notification-button {
@ -159,19 +160,14 @@ notification[type="critical"] > hbox > .messageImage {
background-color: var(--notification-button-background-active);
}
.notification-button:-moz-focusring {
outline: var(--toolbarbutton-focus-outline, 2px solid currentColor);
.notification-button:focus-visible {
outline: var(--focus-outline);
outline-offset: var(--focus-outline-offset);
}
.notification-button.primary {
background-color: var(--notification-primary-button-background);
/* Override button.css hover & active styles */
color: var(--notification-primary-button-text) !important;
}
.notification-button.primary:-moz-focusring {
outline: 4px solid rgba(0, 96, 223, 0.5);
outline-offset: -1px;
color: var(--notification-primary-button-text);
}
.notification-button.primary:not([disabled]):hover {

View File

@ -129,6 +129,11 @@ static CommandLineArg<bool> sSafeMode{"-safeMode", "safemode"};
static CommandLineArg<bool> sIsForBrowser{"-isForBrowser", "isforbrowser"};
static CommandLineArg<bool> sNotForBrowser{"-notForBrowser", "notforbrowser"};
#if defined(XP_WIN) && defined(ACCESSIBILITY)
static CommandLineArg<uint64_t> sA11yResourceId{"-a11yResourceId",
"a11yresourceid"};
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif

View File

@ -27,6 +27,10 @@
# include "mozilla/ScopeExit.h"
# include "mozilla/WinDllServices.h"
# include "WinUtils.h"
# ifdef ACCESSIBILITY
# include "mozilla/GeckoArgs.h"
# include "mozilla/mscom/ActCtxResource.h"
# endif
#endif
#include "nsAppRunner.h"
@ -620,6 +624,16 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
// Associate this thread with a UI MessageLoop
MessageLoop uiMessageLoop(uiLoopType);
{
#if defined(XP_WIN) && defined(ACCESSIBILITY)
// The accessibility resource ID is passed down on the command line
// because its retrieval causes issues with the sandbox. When it is set,
// it is required for ProcessRuntime construction within ProcessChild.
auto a11yResourceId = geckoargs::sA11yResourceId.Get(aArgc, aArgv);
if (a11yResourceId.isSome()) {
mscom::ActCtxResource::SetAccessibilityResourceId(*a11yResourceId);
}
#endif
UniquePtr<ProcessChild> process;
switch (XRE_GetProcessType()) {
case GeckoProcessType_Default:

View File

@ -103,5 +103,11 @@ nsString Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
return result;
}
template <>
nsresult Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
MOZ_ASSERT(aData.IsInstanceOf<jni::Throwable>());
return NS_ERROR_FAILURE;
}
} // namespace jni
} // namespace mozilla

View File

@ -172,13 +172,15 @@ void SerializedTaskDispatcher::Destroy() {
void SerializedTaskDispatcher::PostTaskToMain(
already_AddRefed<nsIRunnable> aTask) {
RefPtr<nsIRunnable> task = aTask;
auto data = mData.Lock();
if (data->mDestroyed) {
return;
}
nsISerialEventTarget* eventTarget = GetMainThreadSerialEventTarget();
data->mTasks.push({std::move(aTask), eventTarget});
data->mTasks.push({std::move(task), eventTarget});
MOZ_ASSERT_IF(!data->mCurrentRunnable, data->mTasks.size() == 1);
PostTasksIfNecessary(eventTarget, data);
@ -186,6 +188,8 @@ void SerializedTaskDispatcher::PostTaskToMain(
void SerializedTaskDispatcher::PostTaskToCalculator(
already_AddRefed<nsIRunnable> aTask) {
RefPtr<nsIRunnable> task = aTask;
auto data = mData.Lock();
if (data->mDestroyed) {
return;
@ -193,7 +197,7 @@ void SerializedTaskDispatcher::PostTaskToCalculator(
nsISerialEventTarget* eventTarget =
WinWindowOcclusionTracker::OcclusionCalculatorLoop()->SerialEventTarget();
data->mTasks.push({std::move(aTask), eventTarget});
data->mTasks.push({std::move(task), eventTarget});
MOZ_ASSERT_IF(!data->mCurrentRunnable, data->mTasks.size() == 1);
PostTasksIfNecessary(eventTarget, data);
@ -236,6 +240,8 @@ void SerializedTaskDispatcher::HandleDelayedTask(
MOZ_ASSERT(WinWindowOcclusionTracker::IsInWinWindowOcclusionThread());
CALC_LOG(LogLevel::Debug, "SerializedTaskDispatcher::HandleDelayedTask()");
RefPtr<nsIRunnable> task = aTask;
auto data = mData.Lock();
if (data->mDestroyed) {
return;
@ -243,7 +249,7 @@ void SerializedTaskDispatcher::HandleDelayedTask(
nsISerialEventTarget* eventTarget =
WinWindowOcclusionTracker::OcclusionCalculatorLoop()->SerialEventTarget();
data->mTasks.push({std::move(aTask), eventTarget});
data->mTasks.push({std::move(task), eventTarget});
MOZ_ASSERT_IF(!data->mCurrentRunnable, data->mTasks.size() == 1);
PostTasksIfNecessary(eventTarget, data);