Index: Source/modules/screen_orientation/ScreenOrientationController.cpp |
diff --git a/Source/modules/screen_orientation/ScreenOrientationController.cpp b/Source/modules/screen_orientation/ScreenOrientationController.cpp |
index af35b986950871a69d10afc1166fb7977f197568..e8b8c133e35e8f05fbdfde2407d21aee35e7be69 100644 |
--- a/Source/modules/screen_orientation/ScreenOrientationController.cpp |
+++ b/Source/modules/screen_orientation/ScreenOrientationController.cpp |
@@ -5,11 +5,11 @@ |
#include "config.h" |
#include "modules/screen_orientation/ScreenOrientationController.h" |
-#include "core/frame/LocalDOMWindow.h" |
+#include "core/events/Event.h" |
#include "core/frame/FrameView.h" |
#include "core/frame/LocalFrame.h" |
-#include "core/frame/Screen.h" |
#include "core/page/Page.h" |
+#include "modules/screen_orientation/ScreenOrientation.h" |
#include "platform/LayoutTestSupport.h" |
#include "platform/PlatformScreen.h" |
#include "public/platform/WebScreenOrientationClient.h" |
@@ -28,18 +28,19 @@ void ScreenOrientationController::persistentHostHasBeenDestroyed() |
void ScreenOrientationController::provideTo(LocalFrame& frame, blink::WebScreenOrientationClient* client) |
{ |
+ ASSERT(RuntimeEnabledFeatures::screenOrientationEnabled()); |
+ |
ScreenOrientationController* controller = new ScreenOrientationController(frame, client); |
WillBeHeapSupplement<LocalFrame>::provideTo(frame, supplementName(), adoptPtrWillBeNoop(controller)); |
} |
-ScreenOrientationController& ScreenOrientationController::from(LocalFrame& frame) |
+ScreenOrientationController* ScreenOrientationController::from(LocalFrame& frame) |
{ |
- return *static_cast<ScreenOrientationController*>(WillBeHeapSupplement<LocalFrame>::from(frame, supplementName())); |
+ return static_cast<ScreenOrientationController*>(WillBeHeapSupplement<LocalFrame>::from(frame, supplementName())); |
} |
ScreenOrientationController::ScreenOrientationController(LocalFrame& frame, blink::WebScreenOrientationClient* client) |
: PageLifecycleObserver(frame.page()) |
- , m_overrideOrientation(blink::WebScreenOrientationUndefined) |
, m_client(client) |
, m_frame(frame) |
{ |
@@ -77,33 +78,9 @@ blink::WebScreenOrientationType ScreenOrientationController::computeOrientation( |
} |
} |
-void ScreenOrientationController::pageVisibilityChanged() |
+void ScreenOrientationController::updateOrientation() |
{ |
- if (page() && page()->visibilityState() == PageVisibilityStateVisible) { |
- blink::WebScreenOrientationType oldOrientation = m_overrideOrientation; |
- m_overrideOrientation = blink::WebScreenOrientationUndefined; |
- // FIXME: sendOrientationChangeEvent() currently send an event all the |
- // children of the frame, so it should only be called on the frame on |
- // top of the tree. We would need the embedder to call |
- // sendOrientationChangeEvent on every WebFrame part of a WebView to be |
- // able to remove this. |
- if (m_frame == m_frame.localFrameRoot() && oldOrientation != orientation()) |
- m_frame.sendOrientationChangeEvent(); |
- } else if (m_overrideOrientation == blink::WebScreenOrientationUndefined) { |
- // The page is no longer visible, store the last know screen orientation |
- // so that we keep returning this orientation until the page becomes |
- // visible again. |
- m_overrideOrientation = orientation(); |
- } |
-} |
- |
-blink::WebScreenOrientationType ScreenOrientationController::orientation() const |
-{ |
- if (m_overrideOrientation != blink::WebScreenOrientationUndefined) { |
- // The page is not visible, keep returning the last known screen orientation. |
- ASSERT(!page() || page()->visibilityState() != PageVisibilityStateVisible); |
- return m_overrideOrientation; |
- } |
+ ASSERT(m_orientation); |
blink::WebScreenOrientationType orientationType = screenOrientationType(m_frame.view()); |
if (orientationType == blink::WebScreenOrientationUndefined) { |
@@ -111,10 +88,66 @@ blink::WebScreenOrientationType ScreenOrientationController::orientation() const |
orientationType = computeOrientation(m_frame.view()); |
} |
ASSERT(orientationType != blink::WebScreenOrientationUndefined); |
- return orientationType; |
+ |
+ m_orientation->setType(orientationType); |
+ m_orientation->setAngle(screenOrientationAngle(m_frame.view())); |
+} |
+ |
+void ScreenOrientationController::pageVisibilityChanged() |
+{ |
+ if (!m_orientation || !page() || page()->visibilityState() != PageVisibilityStateVisible) |
+ return; |
+ |
+ // The orientation type and angle are tied in a way that if the angle has |
+ // changed, the type must have changed. |
+ unsigned short currentAngle = screenOrientationAngle(m_frame.view()); |
+ |
+ // FIXME: sendOrientationChangeEvent() currently send an event all the |
+ // children of the frame, so it should only be called on the frame on |
+ // top of the tree. We would need the embedder to call |
+ // sendOrientationChangeEvent on every WebFrame part of a WebView to be |
+ // able to remove this. |
+ if (m_frame == m_frame.localFrameRoot() && m_orientation->angle() != currentAngle) |
+ notifyOrientationChanged(); |
+} |
+ |
+void ScreenOrientationController::notifyOrientationChanged() |
+{ |
+ ASSERT(RuntimeEnabledFeatures::screenOrientationEnabled()); |
+ |
+ if (!m_orientation || !page() || page()->visibilityState() != PageVisibilityStateVisible) |
+ return; |
+ |
+ updateOrientation(); |
+ |
+ // Keep track of the frames that need to be notified before notifying the |
+ // current frame as it will prevent side effects from the change event |
+ // handlers. |
+ Vector<RefPtr<LocalFrame> > childFrames; |
+ for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling()) { |
+ if (child->isLocalFrame()) |
+ childFrames.append(toLocalFrame(child)); |
+ } |
+ |
+ // Notify current orientation object. |
+ m_orientation->dispatchEvent(Event::create(EventTypeNames::change)); |
+ |
+ // ... and child frames, if they have a ScreenOrientationController. |
+ for (size_t i = 0; i < childFrames.size(); ++i) { |
+ ScreenOrientationController* controller = ScreenOrientationController::from(*childFrames[i]); |
+ if (controller) |
+ controller->notifyOrientationChanged(); |
+ } |
} |
-void ScreenOrientationController::lockOrientation(blink::WebScreenOrientationLockType orientation, blink::WebLockOrientationCallback* callback) |
+void ScreenOrientationController::setOrientation(ScreenOrientation* orientation) |
+{ |
+ m_orientation = orientation; |
+ if (m_orientation) |
+ updateOrientation(); |
+} |
+ |
+void ScreenOrientationController::lock(blink::WebScreenOrientationLockType orientation, blink::WebLockOrientationCallback* callback) |
{ |
if (!m_client) { |
return; |
@@ -123,7 +156,7 @@ void ScreenOrientationController::lockOrientation(blink::WebScreenOrientationLoc |
m_client->lockOrientation(orientation, callback); |
} |
-void ScreenOrientationController::unlockOrientation() |
+void ScreenOrientationController::unlock() |
{ |
if (!m_client) { |
return; |
@@ -132,4 +165,15 @@ void ScreenOrientationController::unlockOrientation() |
m_client->unlockOrientation(); |
} |
+const LocalFrame& ScreenOrientationController::frame() const |
+{ |
+ return m_frame; |
+} |
+ |
+void ScreenOrientationController::trace(Visitor* visitor) |
+{ |
+ visitor->trace(m_orientation); |
+ WillBeHeapSupplement<LocalFrame>::trace(visitor); |
+} |
+ |
} // namespace WebCore |