• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "config.h"
6 #include "modules/screen_orientation/ScreenOrientation.h"
7 
8 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "core/dom/DOMException.h"
11 #include "core/dom/Document.h"
12 #include "core/dom/ExceptionCode.h"
13 #include "core/frame/LocalFrame.h"
14 #include "modules/EventTargetModules.h"
15 #include "modules/screen_orientation/LockOrientationCallback.h"
16 #include "modules/screen_orientation/ScreenOrientationController.h"
17 #include "public/platform/WebScreenOrientationType.h"
18 
19 // This code assumes that WebScreenOrientationType values are included in WebScreenOrientationLockType.
20 #define COMPILE_ASSERT_MATCHING_ENUM(enum1, enum2) \
21     COMPILE_ASSERT(static_cast<unsigned>(blink::enum1) == static_cast<unsigned>(blink::enum2), mismatching_types)
22 COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationPortraitPrimary, WebScreenOrientationLockPortraitPrimary);
23 COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationPortraitSecondary, WebScreenOrientationLockPortraitSecondary);
24 COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationLandscapePrimary, WebScreenOrientationLockLandscapePrimary);
25 COMPILE_ASSERT_MATCHING_ENUM(WebScreenOrientationLandscapeSecondary, WebScreenOrientationLockLandscapeSecondary);
26 
27 namespace blink {
28 
29 struct ScreenOrientationInfo {
30     const AtomicString& name;
31     unsigned orientation;
32 };
33 
orientationsMap(unsigned & length)34 static ScreenOrientationInfo* orientationsMap(unsigned& length)
35 {
36     DEFINE_STATIC_LOCAL(const AtomicString, portraitPrimary, ("portrait-primary", AtomicString::ConstructFromLiteral));
37     DEFINE_STATIC_LOCAL(const AtomicString, portraitSecondary, ("portrait-secondary", AtomicString::ConstructFromLiteral));
38     DEFINE_STATIC_LOCAL(const AtomicString, landscapePrimary, ("landscape-primary", AtomicString::ConstructFromLiteral));
39     DEFINE_STATIC_LOCAL(const AtomicString, landscapeSecondary, ("landscape-secondary", AtomicString::ConstructFromLiteral));
40     DEFINE_STATIC_LOCAL(const AtomicString, any, ("any", AtomicString::ConstructFromLiteral));
41     DEFINE_STATIC_LOCAL(const AtomicString, portrait, ("portrait", AtomicString::ConstructFromLiteral));
42     DEFINE_STATIC_LOCAL(const AtomicString, landscape, ("landscape", AtomicString::ConstructFromLiteral));
43     DEFINE_STATIC_LOCAL(const AtomicString, natural, ("natural", AtomicString::ConstructFromLiteral));
44 
45     static ScreenOrientationInfo orientationMap[] = {
46         { portraitPrimary, WebScreenOrientationLockPortraitPrimary },
47         { portraitSecondary, WebScreenOrientationLockPortraitSecondary },
48         { landscapePrimary, WebScreenOrientationLockLandscapePrimary },
49         { landscapeSecondary, WebScreenOrientationLockLandscapeSecondary },
50         { any, WebScreenOrientationLockAny },
51         { portrait, WebScreenOrientationLockPortrait },
52         { landscape, WebScreenOrientationLockLandscape },
53         { natural, WebScreenOrientationLockNatural }
54     };
55     length = WTF_ARRAY_LENGTH(orientationMap);
56 
57     return orientationMap;
58 }
59 
orientationTypeToString(WebScreenOrientationType orientation)60 const AtomicString& ScreenOrientation::orientationTypeToString(WebScreenOrientationType orientation)
61 {
62     unsigned length = 0;
63     ScreenOrientationInfo* orientationMap = orientationsMap(length);
64     for (unsigned i = 0; i < length; ++i) {
65         if (static_cast<unsigned>(orientation) == orientationMap[i].orientation)
66             return orientationMap[i].name;
67     }
68 
69     ASSERT_NOT_REACHED();
70     return nullAtom;
71 }
72 
stringToOrientationLock(const AtomicString & orientationLockString)73 static WebScreenOrientationLockType stringToOrientationLock(const AtomicString& orientationLockString)
74 {
75     unsigned length = 0;
76     ScreenOrientationInfo* orientationMap = orientationsMap(length);
77     for (unsigned i = 0; i < length; ++i) {
78         if (orientationMap[i].name == orientationLockString)
79             return static_cast<WebScreenOrientationLockType>(orientationMap[i].orientation);
80     }
81 
82     ASSERT_NOT_REACHED();
83     return WebScreenOrientationLockDefault;
84 }
85 
86 // static
create(LocalFrame * frame)87 ScreenOrientation* ScreenOrientation::create(LocalFrame* frame)
88 {
89     ASSERT(frame);
90 
91     ScreenOrientation* orientation = adoptRefCountedGarbageCollectedWillBeNoop(new ScreenOrientation(frame));
92     ASSERT(orientation->controller());
93     // FIXME: ideally, we would like to provide the ScreenOrientationController
94     // the case where it is not defined but for the moment, it is eagerly
95     // created when the LocalFrame is created so we shouldn't be in that
96     // situation.
97     // In order to create the ScreenOrientationController lazily, we would need
98     // to be able to access WebFrameClient from modules/.
99 
100     orientation->controller()->setOrientation(orientation);
101     return orientation;
102 }
103 
ScreenOrientation(LocalFrame * frame)104 ScreenOrientation::ScreenOrientation(LocalFrame* frame)
105     : DOMWindowProperty(frame)
106     , m_type(WebScreenOrientationUndefined)
107     , m_angle(0)
108 {
109 }
110 
~ScreenOrientation()111 ScreenOrientation::~ScreenOrientation()
112 {
113 }
114 
interfaceName() const115 const WTF::AtomicString& ScreenOrientation::interfaceName() const
116 {
117     return EventTargetNames::ScreenOrientation;
118 }
119 
executionContext() const120 ExecutionContext* ScreenOrientation::executionContext() const
121 {
122     if (!m_frame)
123         return 0;
124     return m_frame->document();
125 }
126 
type() const127 String ScreenOrientation::type() const
128 {
129     return orientationTypeToString(m_type);
130 }
131 
angle() const132 unsigned short ScreenOrientation::angle() const
133 {
134     return m_angle;
135 }
136 
setType(WebScreenOrientationType type)137 void ScreenOrientation::setType(WebScreenOrientationType type)
138 {
139     m_type = type;
140 }
141 
setAngle(unsigned short angle)142 void ScreenOrientation::setAngle(unsigned short angle)
143 {
144     m_angle = angle;
145 }
146 
lock(ScriptState * state,const AtomicString & lockString)147 ScriptPromise ScreenOrientation::lock(ScriptState* state, const AtomicString& lockString)
148 {
149     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(state);
150     ScriptPromise promise = resolver->promise();
151 
152     Document* document = m_frame ? m_frame->document() : 0;
153 
154     if (!document || !controller()) {
155         RefPtrWillBeRawPtr<DOMException> exception = DOMException::create(InvalidStateError, "The object is no longer associated to a document.");
156         resolver->reject(exception);
157         return promise;
158     }
159 
160     if (document->isSandboxed(SandboxOrientationLock)) {
161         RefPtrWillBeRawPtr<DOMException> exception = DOMException::create(SecurityError, "The document is sandboxed and lacks the 'allow-orientation-lock' flag.");
162         resolver->reject(exception);
163         return promise;
164     }
165 
166     controller()->lock(stringToOrientationLock(lockString), new LockOrientationCallback(resolver));
167     return promise;
168 }
169 
unlock()170 void ScreenOrientation::unlock()
171 {
172     if (!controller())
173         return;
174 
175     controller()->unlock();
176 }
177 
controller()178 ScreenOrientationController* ScreenOrientation::controller()
179 {
180     if (!m_frame)
181         return 0;
182 
183     return ScreenOrientationController::from(*m_frame);
184 }
185 
trace(Visitor * visitor)186 void ScreenOrientation::trace(Visitor* visitor)
187 {
188     EventTargetWithInlineData::trace(visitor);
189     DOMWindowProperty::trace(visitor);
190 }
191 
192 } // namespace blink
193