1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// 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 "modules/screen_orientation/ScreenOrientationController.h"
#include "core/dom/Document.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Screen.h"
#include "core/page/Page.h"
#include "platform/LayoutTestSupport.h"
#include "platform/PlatformScreen.h"
#include "public/platform/WebScreenOrientationClient.h"
namespace WebCore {
ScreenOrientationController::~ScreenOrientationController()
{
}
void ScreenOrientationController::persistentHostHasBeenDestroyed()
{
// Unregister lifecycle observation once page is being torn down.
observeContext(0);
}
void ScreenOrientationController::provideTo(LocalFrame& frame, blink::WebScreenOrientationClient* client)
{
ScreenOrientationController* controller = new ScreenOrientationController(frame, client);
WillBeHeapSupplement<LocalFrame>::provideTo(frame, supplementName(), adoptPtrWillBeNoop(controller));
}
ScreenOrientationController& ScreenOrientationController::from(LocalFrame& frame)
{
return *static_cast<ScreenOrientationController*>(WillBeHeapSupplement<LocalFrame>::from(frame, supplementName()));
}
ScreenOrientationController::ScreenOrientationController(LocalFrame& frame, blink::WebScreenOrientationClient* client)
: PageLifecycleObserver(frame.page())
, m_overrideOrientation(blink::WebScreenOrientationUndefined)
, m_client(client)
, m_frame(frame)
{
}
const char* ScreenOrientationController::supplementName()
{
return "ScreenOrientationController";
}
// Compute the screen orientation using the orientation angle and the screen width / height.
blink::WebScreenOrientationType ScreenOrientationController::computeOrientation(FrameView* view)
{
// Bypass orientation detection in layout tests to get consistent results.
// FIXME: The screen dimension should be fixed when running the layout tests to avoid such
// issues.
if (isRunningLayoutTest())
return blink::WebScreenOrientationPortraitPrimary;
FloatRect rect = screenRect(view);
uint16_t rotation = screenOrientationAngle(view);
bool isTallDisplay = rotation % 180 ? rect.height() < rect.width() : rect.height() > rect.width();
switch (rotation) {
case 0:
return isTallDisplay ? blink::WebScreenOrientationPortraitPrimary : blink::WebScreenOrientationLandscapePrimary;
case 90:
return isTallDisplay ? blink::WebScreenOrientationLandscapePrimary : blink::WebScreenOrientationPortraitSecondary;
case 180:
return isTallDisplay ? blink::WebScreenOrientationPortraitSecondary : blink::WebScreenOrientationLandscapeSecondary;
case 270:
return isTallDisplay ? blink::WebScreenOrientationLandscapeSecondary : blink::WebScreenOrientationPortraitPrimary;
default:
ASSERT_NOT_REACHED();
return blink::WebScreenOrientationPortraitPrimary;
}
}
void ScreenOrientationController::pageVisibilityChanged()
{
if (page() && page()->visibilityState() == PageVisibilityStateVisible) {
blink::WebScreenOrientationType oldOrientation = m_overrideOrientation;
m_overrideOrientation = blink::WebScreenOrientationUndefined;
// FIXME: sendOrientationChangeEvent() currently send an event all the
// children of the frame, so it should only be called on the frame on
// top of the tree. We would need the embedder to call
// sendOrientationChangeEvent on every WebFrame part of a WebView to be
// able to remove this.
if (m_frame == m_frame.localFrameRoot() && oldOrientation != orientation())
m_frame.sendOrientationChangeEvent();
} else if (m_overrideOrientation == blink::WebScreenOrientationUndefined) {
// The page is no longer visible, store the last know screen orientation
// so that we keep returning this orientation until the page becomes
// visible again.
m_overrideOrientation = orientation();
}
}
blink::WebScreenOrientationType ScreenOrientationController::orientation() const
{
if (m_overrideOrientation != blink::WebScreenOrientationUndefined) {
// The page is not visible, keep returning the last known screen orientation.
ASSERT(!page() || page()->visibilityState() != PageVisibilityStateVisible);
return m_overrideOrientation;
}
blink::WebScreenOrientationType orientationType = screenOrientationType(m_frame.view());
if (orientationType == blink::WebScreenOrientationUndefined) {
// The embedder could not provide us with an orientation, deduce it ourselves.
orientationType = computeOrientation(m_frame.view());
}
ASSERT(orientationType != blink::WebScreenOrientationUndefined);
return orientationType;
}
void ScreenOrientationController::lockOrientation(blink::WebScreenOrientationLockType orientation, blink::WebLockOrientationCallback* callback)
{
if (!m_client) {
return;
}
m_client->lockOrientation(orientation, callback);
}
void ScreenOrientationController::unlockOrientation()
{
if (!m_client) {
return;
}
m_client->unlockOrientation();
}
} // namespace WebCore
|