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.
6 #include "modules/screen_orientation/ScreenOrientation.h"
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"
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);
29 struct ScreenOrientationInfo {
30 const AtomicString& name;
34 static ScreenOrientationInfo* orientationsMap(unsigned& length)
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));
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 }
55 length = WTF_ARRAY_LENGTH(orientationMap);
57 return orientationMap;
60 const AtomicString& ScreenOrientation::orientationTypeToString(WebScreenOrientationType orientation)
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;
73 static WebScreenOrientationLockType stringToOrientationLock(const AtomicString& orientationLockString)
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);
83 return WebScreenOrientationLockDefault;
87 ScreenOrientation* ScreenOrientation::create(LocalFrame* frame)
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
97 // In order to create the ScreenOrientationController lazily, we would need
98 // to be able to access WebFrameClient from modules/.
100 orientation->controller()->setOrientation(orientation);
104 ScreenOrientation::ScreenOrientation(LocalFrame* frame)
105 : DOMWindowProperty(frame)
106 , m_type(WebScreenOrientationUndefined)
111 ScreenOrientation::~ScreenOrientation()
115 const WTF::AtomicString& ScreenOrientation::interfaceName() const
117 return EventTargetNames::ScreenOrientation;
120 ExecutionContext* ScreenOrientation::executionContext() const
124 return m_frame->document();
127 String ScreenOrientation::type() const
129 return orientationTypeToString(m_type);
132 unsigned short ScreenOrientation::angle() const
137 void ScreenOrientation::setType(WebScreenOrientationType type)
142 void ScreenOrientation::setAngle(unsigned short angle)
147 ScriptPromise ScreenOrientation::lock(ScriptState* state, const AtomicString& lockString)
149 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(state);
150 ScriptPromise promise = resolver->promise();
152 Document* document = m_frame ? m_frame->document() : 0;
154 if (!document || !controller()) {
155 RefPtrWillBeRawPtr<DOMException> exception = DOMException::create(InvalidStateError, "The object is no longer associated to a document.");
156 resolver->reject(exception);
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);
166 controller()->lock(stringToOrientationLock(lockString), new LockOrientationCallback(resolver));
170 void ScreenOrientation::unlock()
175 controller()->unlock();
178 ScreenOrientationController* ScreenOrientation::controller()
183 return ScreenOrientationController::from(*m_frame);
186 void ScreenOrientation::trace(Visitor* visitor)
188 EventTargetWithInlineData::trace(visitor);
189 DOMWindowProperty::trace(visitor);