forked from mirrors/gecko-dev
Bug 1753574 - hal::LockOrientation can return error status. r=smaug,geckoview-reviewers,agi,calu
From https://w3c.github.io/screen-orientation/#apply-an-orientation-lock > 7.2. Apply an orientation lock > > The steps to apply an orientation lock to a Document using orientation are as > follows: > > 1. If the user agent does not support locking the screen orientation, return > a promise rejected with a "NotSupportedError" DOMException and abort > these steps. So if orientation controller delegate isn't set, we should throw `NotSupportedError`. But, actually, we throws `AbortError`, so this isn't correct. To return any DOM error from platform implementation of `screen.orientation.lock`, I would like to change return value to `GenericPromise`'s. Differential Revision: https://phabricator.services.mozilla.com/D137970
This commit is contained in:
parent
ad14d19c54
commit
3493d2727e
11 changed files with 110 additions and 64 deletions
|
|
@ -152,8 +152,6 @@ ScreenOrientation::LockOrientationTask::LockOrientationTask(
|
||||||
|
|
||||||
ScreenOrientation::LockOrientationTask::~LockOrientationTask() = default;
|
ScreenOrientation::LockOrientationTask::~LockOrientationTask() = default;
|
||||||
|
|
||||||
using LockOrientationPromise = MozPromise<bool, bool, false>;
|
|
||||||
|
|
||||||
bool ScreenOrientation::LockOrientationTask::OrientationLockContains(
|
bool ScreenOrientation::LockOrientationTask::OrientationLockContains(
|
||||||
OrientationType aOrientationType) {
|
OrientationType aOrientationType) {
|
||||||
return bool(mOrientationLock & OrientationTypeToInternal(aOrientationType));
|
return bool(mOrientationLock & OrientationTypeToInternal(aOrientationType));
|
||||||
|
|
@ -189,15 +187,16 @@ ScreenOrientation::LockOrientationTask::Run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mScreenOrientation->LockDeviceOrientation(mOrientationLock, mIsFullscreen)
|
mScreenOrientation->LockDeviceOrientation(mOrientationLock, mIsFullscreen)
|
||||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
->Then(
|
||||||
[self = RefPtr{this}](
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
const LockOrientationPromise::ResolveOrRejectValue& aValue) {
|
[self = RefPtr{this}](
|
||||||
if (aValue.IsResolve()) {
|
const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
|
||||||
return;
|
if (aValue.IsResolve()) {
|
||||||
}
|
return;
|
||||||
self->mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
}
|
||||||
self->mDocument->ClearOrientationPendingPromise();
|
self->mPromise->MaybeReject(aValue.RejectValue());
|
||||||
});
|
self->mDocument->ClearOrientationPendingPromise();
|
||||||
|
});
|
||||||
|
|
||||||
BrowsingContext* bc = mDocument->GetBrowsingContext();
|
BrowsingContext* bc = mDocument->GetBrowsingContext();
|
||||||
if (OrientationLockContains(bc->GetCurrentOrientationType()) ||
|
if (OrientationLockContains(bc->GetCurrentOrientationType()) ||
|
||||||
|
|
@ -352,10 +351,11 @@ already_AddRefed<Promise> ScreenOrientation::LockInternal(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
|
RefPtr<GenericNonExclusivePromise> ScreenOrientation::LockDeviceOrientation(
|
||||||
hal::ScreenOrientation aOrientation, bool aIsFullscreen) {
|
hal::ScreenOrientation aOrientation, bool aIsFullscreen) {
|
||||||
if (!GetOwner()) {
|
if (!GetOwner()) {
|
||||||
return LockOrientationPromise::CreateAndReject(false, __func__);
|
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
|
||||||
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<EventTarget> target = GetOwner()->GetDoc();
|
nsCOMPtr<EventTarget> target = GetOwner()->GetDoc();
|
||||||
|
|
@ -364,7 +364,8 @@ RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
|
||||||
// This needs to be done before LockScreenOrientation call to make sure
|
// This needs to be done before LockScreenOrientation call to make sure
|
||||||
// the locking can be unlocked.
|
// the locking can be unlocked.
|
||||||
if (aIsFullscreen && !target) {
|
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.
|
// We are fullscreen and lock has been accepted.
|
||||||
|
|
@ -377,7 +378,8 @@ RefPtr<LockOrientationPromise> ScreenOrientation::LockDeviceOrientation(
|
||||||
mFullscreenListener,
|
mFullscreenListener,
|
||||||
/* aUseCapture = */ true);
|
/* aUseCapture = */ true);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return LockOrientationPromise::CreateAndReject(false, __func__);
|
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
|
||||||
|
__func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -552,8 +554,7 @@ void ScreenOrientation::UpdateActiveOrientationLock(
|
||||||
hal::LockScreenOrientation(aOrientation)
|
hal::LockScreenOrientation(aOrientation)
|
||||||
->Then(
|
->Then(
|
||||||
GetMainThreadSerialEventTarget(), __func__,
|
GetMainThreadSerialEventTarget(), __func__,
|
||||||
[](const mozilla::MozPromise<bool, bool,
|
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
|
||||||
false>::ResolveOrRejectValue& aValue) {
|
|
||||||
NS_WARNING_ASSERTION(aValue.IsResolve(),
|
NS_WARNING_ASSERTION(aValue.IsResolve(),
|
||||||
"hal::LockScreenOrientation failed");
|
"hal::LockScreenOrientation failed");
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class ScreenOrientation final : public DOMEventTargetHelper {
|
||||||
|
|
||||||
// This method calls into the HAL to lock the device and sets
|
// This method calls into the HAL to lock the device and sets
|
||||||
// up listeners for full screen change.
|
// up listeners for full screen change.
|
||||||
RefPtr<MozPromise<bool, bool, false>> LockDeviceOrientation(
|
RefPtr<GenericNonExclusivePromise> LockDeviceOrientation(
|
||||||
hal::ScreenOrientation aOrientation, bool aIsFullscreen);
|
hal::ScreenOrientation aOrientation, bool aIsFullscreen);
|
||||||
|
|
||||||
// This method calls in to the HAL to unlock the device and removes
|
// This method calls in to the HAL to unlock the device and removes
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ void NotifyWakeLockChange(const WakeLockInformation& aInfo) {
|
||||||
WakeLockObservers()->BroadcastInformation(aInfo);
|
WakeLockObservers()->BroadcastInformation(aInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
const ScreenOrientation& aOrientation) {
|
const ScreenOrientation& aOrientation) {
|
||||||
AssertMainThread();
|
AssertMainThread();
|
||||||
RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), nullptr);
|
RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), nullptr);
|
||||||
|
|
|
||||||
|
|
@ -220,8 +220,8 @@ void NotifyWakeLockChange(const hal::WakeLockInformation& aWakeLockInfo);
|
||||||
* Lock the screen orientation to the specific orientation.
|
* Lock the screen orientation to the specific orientation.
|
||||||
* @return A promise indicating that the screen orientation has been locked.
|
* @return A promise indicating that the screen orientation has been locked.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] RefPtr<mozilla::MozPromise<bool, bool, false>>
|
[[nodiscard]] RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
LockScreenOrientation(const hal::ScreenOrientation& aOrientation);
|
const hal::ScreenOrientation& aOrientation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlock the screen orientation.
|
* Unlock the screen orientation.
|
||||||
|
|
|
||||||
|
|
@ -101,25 +101,39 @@ static bool IsSupportedScreenOrientation(hal::ScreenOrientation aOrientation) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MozPromise<bool, bool, false>> LockScreenOrientation(
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
const hal::ScreenOrientation& aOrientation) {
|
const hal::ScreenOrientation& aOrientation) {
|
||||||
using LockPromise = MozPromise<bool, bool, false>;
|
|
||||||
|
|
||||||
if (!IsSupportedScreenOrientation(aOrientation)) {
|
if (!IsSupportedScreenOrientation(aOrientation)) {
|
||||||
NS_WARNING("Unsupported screen orientation type");
|
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();
|
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
|
||||||
if (!runtime) {
|
if (!runtime) {
|
||||||
return LockPromise::CreateAndReject(false, __func__);
|
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR,
|
||||||
|
__func__);
|
||||||
}
|
}
|
||||||
auto result = runtime->LockScreenOrientation(uint32_t(aOrientation));
|
auto result = runtime->LockScreenOrientation(uint32_t(aOrientation));
|
||||||
auto geckoResult = java::GeckoResult::LocalRef(std::move(result));
|
auto geckoResult = java::GeckoResult::LocalRef(std::move(result));
|
||||||
if (!geckoResult) {
|
return GenericNonExclusivePromise::FromGeckoResult(geckoResult)
|
||||||
return LockPromise::CreateAndReject(false, __func__);
|
->Then(
|
||||||
}
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
return LockPromise::FromGeckoResult(geckoResult);
|
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) {
|
||||||
|
if (aValue.IsResolve()) {
|
||||||
|
if (aValue.ResolveValue()) {
|
||||||
|
return GenericNonExclusivePromise::CreateAndResolve(true,
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
// 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() {
|
void UnlockScreenOrientation() {
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
namespace mozilla::hal_impl {
|
namespace mozilla::hal_impl {
|
||||||
|
|
||||||
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
const hal::ScreenOrientation& aOrientation) {
|
const hal::ScreenOrientation& aOrientation) {
|
||||||
return mozilla::MozPromise<bool, bool, false>::CreateAndReject(false,
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
__func__);
|
NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnlockScreenOrientation() {}
|
void UnlockScreenOrientation() {}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ parent:
|
||||||
returns (WakeLockInformation aWakeLockInfo);
|
returns (WakeLockInformation aWakeLockInfo);
|
||||||
|
|
||||||
async LockScreenOrientation(ScreenOrientation aOrientation)
|
async LockScreenOrientation(ScreenOrientation aOrientation)
|
||||||
returns (bool allowed);
|
returns (nsresult result);
|
||||||
async UnlockScreenOrientation();
|
async UnlockScreenOrientation();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
|
|
|
||||||
|
|
@ -69,21 +69,24 @@ void GetCurrentNetworkInformation(NetworkInformation* aNetworkInfo) {
|
||||||
Hal()->SendGetCurrentNetworkInformation(aNetworkInfo);
|
Hal()->SendGetCurrentNetworkInformation(aNetworkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<mozilla::MozPromise<bool, bool, false>> LockScreenOrientation(
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
||||||
const hal::ScreenOrientation& aOrientation) {
|
const hal::ScreenOrientation& aOrientation) {
|
||||||
return Hal()
|
return Hal()
|
||||||
->SendLockScreenOrientation(aOrientation)
|
->SendLockScreenOrientation(aOrientation)
|
||||||
->Then(
|
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
[](const mozilla::MozPromise<nsresult, ipc::ResponseRejectReason,
|
||||||
[=](const mozilla::MozPromise<bool, ipc::ResponseRejectReason,
|
true>::ResolveOrRejectValue& aValue) {
|
||||||
true>::ResolveOrRejectValue& aValue) {
|
if (aValue.IsResolve()) {
|
||||||
if (aValue.IsResolve() && aValue.ResolveValue()) {
|
if (NS_SUCCEEDED(aValue.ResolveValue())) {
|
||||||
return mozilla::MozPromise<bool, bool, false>::CreateAndResolve(
|
return GenericNonExclusivePromise::CreateAndResolve(
|
||||||
true, __func__);
|
true, __func__);
|
||||||
}
|
}
|
||||||
return mozilla::MozPromise<bool, bool, false>::CreateAndReject(
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
false, __func__);
|
aValue.ResolveValue(), __func__);
|
||||||
});
|
}
|
||||||
|
return GenericNonExclusivePromise::CreateAndReject(
|
||||||
|
NS_ERROR_FAILURE, __func__);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnlockScreenOrientation() { Hal()->SendUnlockScreenOrientation(); }
|
void UnlockScreenOrientation() { Hal()->SendUnlockScreenOrientation(); }
|
||||||
|
|
@ -223,15 +226,17 @@ class HalParent : public PHalParent,
|
||||||
// fullscreen. We don't have that information currently.
|
// fullscreen. We don't have that information currently.
|
||||||
|
|
||||||
hal::LockScreenOrientation(aOrientation)
|
hal::LockScreenOrientation(aOrientation)
|
||||||
->Then(GetMainThreadSerialEventTarget(), __func__,
|
->Then(
|
||||||
[aResolve](const mozilla::MozPromise<
|
GetMainThreadSerialEventTarget(), __func__,
|
||||||
bool, bool, false>::ResolveOrRejectValue& aValue) {
|
[aResolve](const GenericNonExclusivePromise::ResolveOrRejectValue&
|
||||||
if (aValue.IsResolve()) {
|
aValue) {
|
||||||
aResolve(aValue.ResolveValue());
|
if (aValue.IsResolve()) {
|
||||||
} else {
|
MOZ_ASSERT(aValue.ResolveValue());
|
||||||
aResolve(false);
|
aResolve(NS_OK);
|
||||||
}
|
return;
|
||||||
});
|
}
|
||||||
|
aResolve(aValue.RejectValue());
|
||||||
|
});
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,4 +178,22 @@ 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"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -919,16 +919,18 @@ public final class GeckoRuntime implements Parcelable {
|
||||||
final OrientationController.OrientationDelegate delegate =
|
final OrientationController.OrientationDelegate delegate =
|
||||||
getOrientationController().getDelegate();
|
getOrientationController().getDelegate();
|
||||||
if (delegate == null) {
|
if (delegate == null) {
|
||||||
res.complete(false);
|
// Delegate is not set
|
||||||
} else {
|
res.completeExceptionally(new Exception("Not supported"));
|
||||||
final GeckoResult<AllowOrDeny> response =
|
return;
|
||||||
delegate.onOrientationLock(toAndroidOrientation(aOrientation));
|
|
||||||
if (response == null) {
|
|
||||||
res.complete(false);
|
|
||||||
} else {
|
|
||||||
res.completeFrom(response.map(v -> v == AllowOrDeny.ALLOW));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
final GeckoResult<AllowOrDeny> response =
|
||||||
|
delegate.onOrientationLock(toAndroidOrientation(aOrientation));
|
||||||
|
if (response == null) {
|
||||||
|
// 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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,5 +103,11 @@ nsString Java2Native(mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
|
||||||
return result;
|
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 jni
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue