Home | History | Annotate | Download | only in screen_orientation
      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 = 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 
    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
    193