Chromium Code Reviews| Index: Source/modules/screen_orientation/ScreenOrientation.cpp |
| diff --git a/Source/modules/screen_orientation/ScreenOrientation.cpp b/Source/modules/screen_orientation/ScreenOrientation.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bdb8bb78a393150506701635963c733b0c1ecabb |
| --- /dev/null |
| +++ b/Source/modules/screen_orientation/ScreenOrientation.cpp |
| @@ -0,0 +1,216 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "config.h" |
| +#include "ScreenOrientation.h" |
| + |
| +#include "core/frame/Frame.h" |
| +#include "core/frame/Screen.h" |
| +#include "core/page/ChromeClient.h" |
| +#include "modules/screen_orientation/ScreenOrientationClient.h" |
| +#include "modules/screen_orientation/ScreenOrientationController.h" |
| + |
| +namespace WebCore { |
| + |
| +ScreenOrientation::ScreenOrientation(Screen* screen) |
| + : DOMWindowProperty(screen->frame()) |
| + , PageLifecycleObserver(page()) |
| + , ActiveDOMObject(frame() ? frame()->document() : 0) |
| + , m_screen(screen) |
| + , m_orientationLockTimer(this, &ScreenOrientation::orientationLockTimerFired) |
| + , m_lockedOrientations(OrientationAny) |
| +{ |
| + ASSERT(screen); |
|
Peter Beverloo
2014/02/12 18:19:37
We'd already have crashed if !screen, since you're
Inactive
2014/02/12 19:38:37
Good point, I will move this assertion to the call
|
| + ScreenOrientationController* controller = ScreenOrientationController::from(page()); |
| + if (controller) |
| + controller->addObserver(this); |
| +} |
| + |
| +ScreenOrientation::~ScreenOrientation() |
| +{ |
| +} |
| + |
| +const char* ScreenOrientation::supplementName() |
| +{ |
| + return "ScreenOrientation"; |
| +} |
| + |
| +void ScreenOrientation::orientationLockTimerFired(Timer<ScreenOrientation>*) |
| +{ |
| + ScreenOrientationClient* client = ScreenOrientationController::clientFrom(page()); |
| + if (!client) |
| + return; |
| + |
| + client->lockOrientation(m_lockedOrientations); |
| +} |
| + |
| +void ScreenOrientation::didCommitLoad(Frame*) |
| +{ |
| + // New page loaded, unlock screen orientation. |
| + unlockOrientation(); |
| +} |
| + |
| +void ScreenOrientation::willDestroyGlobalObjectInFrame() |
| +{ |
| + m_screen = 0; |
| + DOMWindowProperty::willDestroyGlobalObjectInFrame(); |
| +} |
| + |
| +void ScreenOrientation::willDetachGlobalObjectFromFrame() |
| +{ |
| + m_screen = 0; |
| + DOMWindowProperty::willDetachGlobalObjectFromFrame(); |
| +} |
| + |
| +void ScreenOrientation::stop() |
| +{ |
| + ScreenOrientationController* controller = ScreenOrientationController::from(page()); |
| + if (controller) |
| + controller->removeObserver(this); |
| +} |
| + |
| +Page* ScreenOrientation::page() const |
| +{ |
| + return frame() ? frame()->page() : 0; |
| +} |
| + |
| +ScreenOrientation* ScreenOrientation::from(Screen* screen) |
| +{ |
| + ScreenOrientation* supplement = static_cast<ScreenOrientation*>(Supplement<Screen>::from(screen, supplementName())); |
| + if (!supplement) { |
| + supplement = new ScreenOrientation(screen); |
|
Peter Beverloo
2014/02/12 18:19:37
If you do need to ASSERT(screen), this would be a
Inactive
2014/02/12 19:38:37
Done.
|
| + supplement->suspendIfNeeded(); |
| + provideTo(screen, supplementName(), adoptPtr(supplement)); |
| + } |
| + return supplement; |
| +} |
| + |
| +struct ScreenOrientationInfo { |
| + const AtomicString& name; |
| + ScreenOrientationValues orientation; |
| +}; |
| + |
| +static ScreenOrientationInfo* allowedOrientationsMap(unsigned& length) |
| +{ |
| + DEFINE_STATIC_LOCAL(const AtomicString, portrait, ("portrait", AtomicString::ConstructFromLiteral)); |
| + DEFINE_STATIC_LOCAL(const AtomicString, portraitPrimary, ("portrait-primary", AtomicString::ConstructFromLiteral)); |
| + DEFINE_STATIC_LOCAL(const AtomicString, portraitSecondary, ("portrait-secondary", AtomicString::ConstructFromLiteral)); |
| + DEFINE_STATIC_LOCAL(const AtomicString, landscape, ("landscape", AtomicString::ConstructFromLiteral)); |
| + DEFINE_STATIC_LOCAL(const AtomicString, landscapePrimary, ("landscape-primary", AtomicString::ConstructFromLiteral)); |
| + DEFINE_STATIC_LOCAL(const AtomicString, landscapeSecondary, ("landscape-secondary", AtomicString::ConstructFromLiteral)); |
| + |
| + static ScreenOrientationInfo orientationMap[] = { |
| + { portrait, OrientationPortrait }, |
| + { portraitPrimary, OrientationPortraitPrimary }, |
| + { portraitSecondary, OrientationPortraitSecondary }, |
| + { landscape, OrientationLandscape }, |
| + { landscapePrimary, OrientationLandscapePrimary }, |
| + { landscapeSecondary, OrientationLandscapeSecondary } |
| + }; |
| + length = WTF_ARRAY_LENGTH(orientationMap); |
| + return orientationMap; |
| +} |
| + |
| +const AtomicString& ScreenOrientation::orientationToString(ScreenOrientationValue orientation) |
| +{ |
| + unsigned length = 0; |
| + ScreenOrientationInfo* orientationMap = allowedOrientationsMap(length); |
| + for (unsigned i = 0; i < length; ++i) { |
| + if (orientationMap[i].orientation == orientation) |
| + return orientationMap[i].name; |
| + } |
| + ASSERT_NOT_REACHED(); |
|
Peter Beverloo
2014/02/12 18:19:37
nit: maybe add a note that OrientationInvalid and
Inactive
2014/02/12 19:38:37
Done.
|
| + return nullAtom; |
| +} |
| + |
| +ScreenOrientationValues ScreenOrientation::stringToOrientationValues(const AtomicString& orientation) |
| +{ |
| + unsigned length = 0; |
| + ScreenOrientationInfo* orientationMap = allowedOrientationsMap(length); |
| + for (unsigned i = 0; i < length; ++i) { |
| + if (orientationMap[i].name == orientation) |
| + return orientationMap[i].orientation; |
| + } |
| + return OrientationInvalid; |
| +} |
| + |
| +const AtomicString& ScreenOrientation::orientation(Screen* screen) |
| +{ |
| + ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
| + ASSERT(screenOrientation); |
| + |
| + ScreenOrientationController* controller = ScreenOrientationController::from(screenOrientation->page()); |
| + if (!controller) |
| + return orientationToString(OrientationPortraitPrimary); |
| + |
| + return orientationToString(controller->orientation()); |
| +} |
| + |
| +bool ScreenOrientation::lockOrientation(Screen* screen, const Vector<String>& orientationsVector) |
| +{ |
| + ScreenOrientationValues orientations = OrientationInvalid; |
| + |
| + for (unsigned i = 0; i < orientationsVector.size(); ++i) { |
| + ScreenOrientationValues inputOrientation = stringToOrientationValues(AtomicString(orientationsVector[i])); |
| + if (inputOrientation == OrientationInvalid) |
| + return false; |
| + orientations |= inputOrientation; |
| + } |
| + |
| + if (!orientations) |
| + return false; |
| + |
| + ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
| + ASSERT(screenOrientation); |
| + screenOrientation->lockOrientationAsync(orientations); |
| + return true; |
| +} |
| + |
| +bool ScreenOrientation::lockOrientation(Screen* screen, const AtomicString& orientationString) |
| +{ |
| + ScreenOrientationValues orientation = stringToOrientationValues(orientationString); |
| + if (!orientation) |
| + return false; |
| + |
| + ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
| + ASSERT(screenOrientation); |
| + screenOrientation->lockOrientationAsync(orientation); |
| + return true; |
| +} |
| + |
| +void ScreenOrientation::lockOrientationAsync(ScreenOrientationValues orientations) |
| +{ |
| + ASSERT(!(orientations & OrientationInvalid)); |
| + |
| + m_lockedOrientations = orientations; |
| + if (!m_orientationLockTimer.isActive()) |
| + m_orientationLockTimer.startOneShot(0); |
|
mlamouri (slow - plz ping)
2014/02/12 20:11:26
I do not think having this call async here is real
Inactive
2014/02/12 21:08:04
I am not sure about this one. I think this is a qu
mlamouri (slow - plz ping)
2014/02/13 16:12:08
I guess I will let the Webkit/Blink experienced fo
Inactive
2014/02/13 16:32:26
Yes, I asked for clarification on the spec about u
|
| +} |
| + |
| +void ScreenOrientation::unlockOrientation(Screen* screen) |
| +{ |
| + ScreenOrientation* screenOrientation = ScreenOrientation::from(screen); |
| + ASSERT(screenOrientation); |
| + screenOrientation->unlockOrientation(); |
| +} |
| + |
| +void ScreenOrientation::unlockOrientation() |
| +{ |
| + if (m_lockedOrientations == OrientationAny) |
| + return; // Not currently locked. |
|
mlamouri (slow - plz ping)
2014/02/12 20:11:26
This is actually a false assumption. I believe tha
Inactive
2014/02/12 21:08:04
Well, we are not locked due to JS. Why pass call u
mlamouri (slow - plz ping)
2014/02/13 16:12:08
This code would be call if |screen.unlockOrientati
|
| + |
| + m_lockedOrientations = OrientationAny; |
|
mlamouri (slow - plz ping)
2014/02/12 20:11:26
Generally speaking, I think you can get ride of m_
mlamouri (slow - plz ping)
2014/02/12 20:11:26
I
Inactive
2014/02/12 21:08:04
I need it as long as I keep locking asynchronously
mlamouri (slow - plz ping)
2014/02/13 16:12:08
Sadly, indeed.
|
| + |
| + ScreenOrientationClient* client = ScreenOrientationController::clientFrom(page()); |
| + if (client) |
| + client->unlockOrientation(); |
| +} |
| + |
| +void ScreenOrientation::orientationChanged() |
| +{ |
| + if (m_screen) |
| + m_screen->dispatchEvent(Event::create(EventTypeNames::orientationchange)); |
| +} |
| + |
| +} // namespace WebCore |