OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/screen_orientation/ScreenOrientationController.h" | 6 #include "modules/screen_orientation/ScreenOrientationController.h" |
7 | 7 |
8 #include "core/events/Event.h" | |
9 #include "core/frame/LocalDOMWindow.h" | 8 #include "core/frame/LocalDOMWindow.h" |
10 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
11 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
12 #include "core/frame/Screen.h" | 11 #include "core/frame/Screen.h" |
13 #include "core/page/Page.h" | 12 #include "core/page/Page.h" |
14 #include "modules/screen_orientation/OrientationInformation.h" | |
15 #include "platform/LayoutTestSupport.h" | 13 #include "platform/LayoutTestSupport.h" |
16 #include "platform/PlatformScreen.h" | 14 #include "platform/PlatformScreen.h" |
17 #include "public/platform/WebScreenOrientationClient.h" | 15 #include "public/platform/WebScreenOrientationClient.h" |
18 | 16 |
19 namespace WebCore { | 17 namespace WebCore { |
20 | 18 |
21 ScreenOrientationController::~ScreenOrientationController() | 19 ScreenOrientationController::~ScreenOrientationController() |
22 { | 20 { |
23 } | 21 } |
24 | 22 |
25 void ScreenOrientationController::persistentHostHasBeenDestroyed() | 23 void ScreenOrientationController::persistentHostHasBeenDestroyed() |
26 { | 24 { |
27 // Unregister lifecycle observation once page is being torn down. | 25 // Unregister lifecycle observation once page is being torn down. |
28 observeContext(0); | 26 observeContext(0); |
29 } | 27 } |
30 | 28 |
31 void ScreenOrientationController::provideTo(LocalFrame& frame, blink::WebScreenO
rientationClient* client) | 29 void ScreenOrientationController::provideTo(LocalFrame& frame, blink::WebScreenO
rientationClient* client) |
32 { | 30 { |
33 ScreenOrientationController* controller = new ScreenOrientationController(fr
ame, client); | 31 ScreenOrientationController* controller = new ScreenOrientationController(fr
ame, client); |
34 WillBeHeapSupplement<LocalFrame>::provideTo(frame, supplementName(), adoptPt
rWillBeNoop(controller)); | 32 WillBeHeapSupplement<LocalFrame>::provideTo(frame, supplementName(), adoptPt
rWillBeNoop(controller)); |
35 } | 33 } |
36 | 34 |
37 ScreenOrientationController& ScreenOrientationController::from(LocalFrame& frame
) | 35 ScreenOrientationController& ScreenOrientationController::from(LocalFrame& frame
) |
38 { | 36 { |
39 return *static_cast<ScreenOrientationController*>(WillBeHeapSupplement<Local
Frame>::from(frame, supplementName())); | 37 return *static_cast<ScreenOrientationController*>(WillBeHeapSupplement<Local
Frame>::from(frame, supplementName())); |
40 } | 38 } |
41 | 39 |
42 ScreenOrientationController::ScreenOrientationController(LocalFrame& frame, blin
k::WebScreenOrientationClient* client) | 40 ScreenOrientationController::ScreenOrientationController(LocalFrame& frame, blin
k::WebScreenOrientationClient* client) |
43 : PageLifecycleObserver(frame.page()) | 41 : PageLifecycleObserver(frame.page()) |
44 , m_orientation(new OrientationInformation) | 42 , m_overrideOrientation(blink::WebScreenOrientationUndefined) |
45 , m_client(client) | 43 , m_client(client) |
46 , m_frame(frame) | 44 , m_frame(frame) |
47 { | 45 { |
48 } | 46 } |
49 | 47 |
50 const char* ScreenOrientationController::supplementName() | 48 const char* ScreenOrientationController::supplementName() |
51 { | 49 { |
52 return "ScreenOrientationController"; | 50 return "ScreenOrientationController"; |
53 } | 51 } |
54 | 52 |
(...skipping 17 matching lines...) Expand all Loading... |
72 case 180: | 70 case 180: |
73 return isTallDisplay ? blink::WebScreenOrientationPortraitSecondary : bl
ink::WebScreenOrientationLandscapeSecondary; | 71 return isTallDisplay ? blink::WebScreenOrientationPortraitSecondary : bl
ink::WebScreenOrientationLandscapeSecondary; |
74 case 270: | 72 case 270: |
75 return isTallDisplay ? blink::WebScreenOrientationLandscapeSecondary : b
link::WebScreenOrientationPortraitPrimary; | 73 return isTallDisplay ? blink::WebScreenOrientationLandscapeSecondary : b
link::WebScreenOrientationPortraitPrimary; |
76 default: | 74 default: |
77 ASSERT_NOT_REACHED(); | 75 ASSERT_NOT_REACHED(); |
78 return blink::WebScreenOrientationPortraitPrimary; | 76 return blink::WebScreenOrientationPortraitPrimary; |
79 } | 77 } |
80 } | 78 } |
81 | 79 |
82 void ScreenOrientationController::updateOrientation() | 80 void ScreenOrientationController::pageVisibilityChanged() |
83 { | 81 { |
| 82 if (page() && page()->visibilityState() == PageVisibilityStateVisible) { |
| 83 blink::WebScreenOrientationType oldOrientation = m_overrideOrientation; |
| 84 m_overrideOrientation = blink::WebScreenOrientationUndefined; |
| 85 // FIXME: sendOrientationChangeEvent() currently send an event all the |
| 86 // children of the frame, so it should only be called on the frame on |
| 87 // top of the tree. We would need the embedder to call |
| 88 // sendOrientationChangeEvent on every WebFrame part of a WebView to be |
| 89 // able to remove this. |
| 90 if (m_frame == m_frame.localFrameRoot() && oldOrientation != orientation
()) |
| 91 m_frame.sendOrientationChangeEvent(); |
| 92 } else if (m_overrideOrientation == blink::WebScreenOrientationUndefined) { |
| 93 // The page is no longer visible, store the last know screen orientation |
| 94 // so that we keep returning this orientation until the page becomes |
| 95 // visible again. |
| 96 m_overrideOrientation = orientation(); |
| 97 } |
| 98 } |
| 99 |
| 100 blink::WebScreenOrientationType ScreenOrientationController::orientation() const |
| 101 { |
| 102 if (m_overrideOrientation != blink::WebScreenOrientationUndefined) { |
| 103 // The page is not visible, keep returning the last known screen orienta
tion. |
| 104 ASSERT(!page() || page()->visibilityState() != PageVisibilityStateVisibl
e); |
| 105 return m_overrideOrientation; |
| 106 } |
| 107 |
84 blink::WebScreenOrientationType orientationType = screenOrientationType(m_fr
ame.view()); | 108 blink::WebScreenOrientationType orientationType = screenOrientationType(m_fr
ame.view()); |
85 if (orientationType == blink::WebScreenOrientationUndefined) { | 109 if (orientationType == blink::WebScreenOrientationUndefined) { |
86 // The embedder could not provide us with an orientation, deduce it ours
elves. | 110 // The embedder could not provide us with an orientation, deduce it ours
elves. |
87 orientationType = computeOrientation(m_frame.view()); | 111 orientationType = computeOrientation(m_frame.view()); |
88 } | 112 } |
89 ASSERT(orientationType != blink::WebScreenOrientationUndefined); | 113 ASSERT(orientationType != blink::WebScreenOrientationUndefined); |
90 | 114 return orientationType; |
91 m_orientation->setType(orientationType); | |
92 m_orientation->setAngle(screenOrientationAngle(m_frame.view())); | |
93 } | |
94 | |
95 void ScreenOrientationController::pageVisibilityChanged() | |
96 { | |
97 if (!page() || page()->visibilityState() != PageVisibilityStateVisible) | |
98 return; | |
99 | |
100 // The orientation type and angle are tied in a way that if the angle has | |
101 // changed, the type must have changed. | |
102 unsigned short currentAngle = screenOrientationAngle(m_frame.view()); | |
103 | |
104 // FIXME: sendOrientationChangeEvent() currently send an event all the | |
105 // children of the frame, so it should only be called on the frame on | |
106 // top of the tree. We would need the embedder to call | |
107 // sendOrientationChangeEvent on every WebFrame part of a WebView to be | |
108 // able to remove this. | |
109 if (m_frame == m_frame.localFrameRoot() && m_orientation->angle() != current
Angle) | |
110 notifyOrientationChanged(); | |
111 } | |
112 | |
113 void ScreenOrientationController::notifyOrientationChanged() | |
114 { | |
115 if (!RuntimeEnabledFeatures::orientationEventEnabled() && !RuntimeEnabledFea
tures::screenOrientationEnabled()) | |
116 return; | |
117 | |
118 if (!page() || page()->visibilityState() != PageVisibilityStateVisible) | |
119 return; | |
120 | |
121 updateOrientation(); | |
122 | |
123 // Keep track of the frames that need to be notified before notifying the | |
124 // current frame as it will prevent side effects from the orientationchange | |
125 // event handlers. | |
126 Vector<RefPtr<LocalFrame> > childFrames; | |
127 for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree(
).nextSibling()) { | |
128 if (child->isLocalFrame()) | |
129 childFrames.append(toLocalFrame(child)); | |
130 } | |
131 | |
132 // Notify current frame. | |
133 LocalDOMWindow* window = m_frame.domWindow(); | |
134 if (window) | |
135 window->dispatchEvent(Event::create(EventTypeNames::orientationchange)); | |
136 | |
137 // Notify subframes. | |
138 for (size_t i = 0; i < childFrames.size(); ++i) | |
139 ScreenOrientationController::from(*childFrames[i]).notifyOrientationChan
ged(); | |
140 } | |
141 | |
142 OrientationInformation* ScreenOrientationController::orientation() | |
143 { | |
144 if (!m_orientation->initialized()) | |
145 updateOrientation(); | |
146 | |
147 return m_orientation.get(); | |
148 } | 115 } |
149 | 116 |
150 void ScreenOrientationController::lockOrientation(blink::WebScreenOrientationLoc
kType orientation, blink::WebLockOrientationCallback* callback) | 117 void ScreenOrientationController::lockOrientation(blink::WebScreenOrientationLoc
kType orientation, blink::WebLockOrientationCallback* callback) |
151 { | 118 { |
152 if (!m_client) { | 119 if (!m_client) { |
153 return; | 120 return; |
154 } | 121 } |
155 | 122 |
156 m_client->lockOrientation(orientation, callback); | 123 m_client->lockOrientation(orientation, callback); |
157 } | 124 } |
158 | 125 |
159 void ScreenOrientationController::unlockOrientation() | 126 void ScreenOrientationController::unlockOrientation() |
160 { | 127 { |
161 if (!m_client) { | 128 if (!m_client) { |
162 return; | 129 return; |
163 } | 130 } |
164 | 131 |
165 m_client->unlockOrientation(); | 132 m_client->unlockOrientation(); |
166 } | 133 } |
167 | 134 |
168 void ScreenOrientationController::trace(Visitor* visitor) | |
169 { | |
170 WillBeHeapSupplement<LocalFrame>::trace(visitor); | |
171 visitor->trace(m_orientation); | |
172 } | |
173 | |
174 } // namespace WebCore | 135 } // namespace WebCore |
OLD | NEW |