Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / screen_orientation / ScreenOrientation.cpp
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
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
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
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
87 ScreenOrientation* ScreenOrientation::create(LocalFrame* frame)
88 {
89     ASSERT(frame);
90
91     ScreenOrientation* orientation = 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
104 ScreenOrientation::ScreenOrientation(LocalFrame* frame)
105     : DOMWindowProperty(frame)
106     , m_type(WebScreenOrientationUndefined)
107     , m_angle(0)
108 {
109 }
110
111 ScreenOrientation::~ScreenOrientation()
112 {
113 }
114
115 const WTF::AtomicString& ScreenOrientation::interfaceName() const
116 {
117     return EventTargetNames::ScreenOrientation;
118 }
119
120 ExecutionContext* ScreenOrientation::executionContext() const
121 {
122     if (!m_frame)
123         return 0;
124     return m_frame->document();
125 }
126
127 String ScreenOrientation::type() const
128 {
129     return orientationTypeToString(m_type);
130 }
131
132 unsigned short ScreenOrientation::angle() const
133 {
134     return m_angle;
135 }
136
137 void ScreenOrientation::setType(WebScreenOrientationType type)
138 {
139     m_type = type;
140 }
141
142 void ScreenOrientation::setAngle(unsigned short angle)
143 {
144     m_angle = angle;
145 }
146
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
170 void ScreenOrientation::unlock()
171 {
172     if (!controller())
173         return;
174
175     controller()->unlock();
176 }
177
178 ScreenOrientationController* ScreenOrientation::controller()
179 {
180     if (!m_frame)
181         return 0;
182
183     return ScreenOrientationController::from(*m_frame);
184 }
185
186 void ScreenOrientation::trace(Visitor* visitor)
187 {
188     EventTargetWithInlineData::trace(visitor);
189     DOMWindowProperty::trace(visitor);
190 }
191
192 } // namespace blink