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,13 +187,14 @@ ScreenOrientation::LockOrientationTask::Run() { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   mScreenOrientation->LockDeviceOrientation(mOrientationLock, mIsFullscreen) |   mScreenOrientation->LockDeviceOrientation(mOrientationLock, mIsFullscreen) | ||||||
|       ->Then(GetCurrentSerialEventTarget(), __func__, |       ->Then( | ||||||
|  |           GetCurrentSerialEventTarget(), __func__, | ||||||
|           [self = RefPtr{this}]( |           [self = RefPtr{this}]( | ||||||
|                  const LockOrientationPromise::ResolveOrRejectValue& aValue) { |               const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) { | ||||||
|             if (aValue.IsResolve()) { |             if (aValue.IsResolve()) { | ||||||
|               return; |               return; | ||||||
|             } |             } | ||||||
|                self->mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); |             self->mPromise->MaybeReject(aValue.RejectValue()); | ||||||
|             self->mDocument->ClearOrientationPendingPromise(); |             self->mDocument->ClearOrientationPendingPromise(); | ||||||
|           }); |           }); | ||||||
| 
 | 
 | ||||||
|  | @ -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__, | ||||||
|  |           [](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() { | 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,20 +69,23 @@ 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() && aValue.ResolveValue()) { |                if (aValue.IsResolve()) { | ||||||
|               return mozilla::MozPromise<bool, bool, false>::CreateAndResolve( |                  if (NS_SUCCEEDED(aValue.ResolveValue())) { | ||||||
|  |                    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__); | ||||||
|              }); |              }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -223,14 +226,16 @@ 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& | ||||||
|  |                            aValue) { | ||||||
|               if (aValue.IsResolve()) { |               if (aValue.IsResolve()) { | ||||||
|                    aResolve(aValue.ResolveValue()); |                 MOZ_ASSERT(aValue.ResolveValue()); | ||||||
|                  } else { |                 aResolve(NS_OK); | ||||||
|                    aResolve(false); |                 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")); | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|           final GeckoResult<AllowOrDeny> response = |           final GeckoResult<AllowOrDeny> response = | ||||||
|               delegate.onOrientationLock(toAndroidOrientation(aOrientation)); |               delegate.onOrientationLock(toAndroidOrientation(aOrientation)); | ||||||
|           if (response == null) { |           if (response == null) { | ||||||
|               res.complete(false); |             // Delegate is default. So lock orientation is not implemented | ||||||
|             } else { |             res.completeExceptionally(new Exception("Not supported")); | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|           res.completeFrom(response.map(v -> v == AllowOrDeny.ALLOW)); |           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
	
	 Makoto Kato
						Makoto Kato