Skip to content

Commit

Permalink
Bug 920734 - Part 1: Implement window.orientation and window.onorient…
Browse files Browse the repository at this point in the history
…ationchange. r=baku
  • Loading branch information
William Chen committed Oct 24, 2015
1 parent 36d5e5d commit 1799f33
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 0 deletions.
55 changes: 55 additions & 0 deletions dom/base/WindowOrientationObserver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "WindowOrientationObserver.h"

#include "nsGlobalWindow.h"
#include "mozilla/Hal.h"

/**
* This class is used by nsGlobalWindow to implement window.orientation
* and window.onorientationchange. This class is defined in its own file
* because Hal.h pulls in windows.h and can't be included from
* nsGlobalWindow.cpp
*/
WindowOrientationObserver::WindowOrientationObserver(
nsGlobalWindow* aGlobalWindow)
: mWindow(aGlobalWindow)
{
MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
hal::RegisterScreenConfigurationObserver(this);

hal::ScreenConfiguration config;
hal::GetCurrentScreenConfiguration(&config);
mAngle = config.angle();
}

WindowOrientationObserver::~WindowOrientationObserver()
{
hal::UnregisterScreenConfigurationObserver(this);
}

void
WindowOrientationObserver::Notify(
const mozilla::hal::ScreenConfiguration& aConfiguration)
{
uint16_t currentAngle = aConfiguration.angle();
if (mAngle != currentAngle && mWindow->IsCurrentInnerWindow()) {
mAngle = currentAngle;
mWindow->GetOuterWindow()->DispatchCustomEvent(NS_LITERAL_STRING("orientationchange"));
}
}

/* static */ int16_t
WindowOrientationObserver::OrientationAngle()
{
hal::ScreenConfiguration config;
hal::GetCurrentScreenConfiguration(&config);
int16_t angle = static_cast<int16_t>(config.angle());
// config.angle() returns 0, 90, 180 or 270.
// window.orientation returns -90, 0, 90 or 180.
return angle <= 180 ? angle : angle - 360;
}
35 changes: 35 additions & 0 deletions dom/base/WindowOrientationObserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_WindowOrientationObserver_h
#define mozilla_dom_WindowOrientationObserver_h

#include "mozilla/HalScreenConfiguration.h"

class nsGlobalWindow;

namespace mozilla {
namespace dom {

class WindowOrientationObserver final :
public mozilla::hal::ScreenConfigurationObserver
{
public:
explicit WindowOrientationObserver(nsGlobalWindow* aGlobalWindow);
~WindowOrientationObserver();
void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override;
static int16_t OrientationAngle();

private:
// Weak pointer, instance is owned by mWindow.
nsGlobalWindow* MOZ_NON_OWNING_REF mWindow;
uint16_t mAngle;
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_WindowOrientationObserver_h
2 changes: 2 additions & 0 deletions dom/base/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ EXPORTS.mozilla.dom += [
'URL.h',
'URLSearchParams.h',
'WebSocket.h',
'WindowOrientationObserver.h',
]

UNIFIED_SOURCES += [
Expand Down Expand Up @@ -355,6 +356,7 @@ UNIFIED_SOURCES += [
'URLSearchParams.cpp',
'WebSocket.cpp',
'WindowNamedPropertiesHandler.cpp',
'WindowOrientationObserver.cpp',
]

if CONFIG['MOZ_WEBRTC']:
Expand Down
1 change: 1 addition & 0 deletions dom/base/nsGkAtomList.h
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ GK_ATOM(onobsolete, "onobsolete")
GK_ATOM(ononline, "ononline")
GK_ATOM(onoffline, "onoffline")
GK_ATOM(onopen, "onopen")
GK_ATOM(onorientationchange, "onorientationchange")
GK_ATOM(onotastatuschange, "onotastatuschange")
GK_ATOM(onoverflow, "onoverflow")
GK_ATOM(onoverflowchanged, "onoverflowchanged")
Expand Down
41 changes: 41 additions & 0 deletions dom/base/nsGlobalWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "mozilla/dom/DOMStorage.h"
#include "mozilla/dom/StorageEvent.h"
#include "mozilla/dom/StorageEventBinding.h"
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
#include "mozilla/dom/WindowOrientationObserver.h"
#endif
#include "nsDOMOfflineResourceList.h"
#include "nsError.h"
#include "nsIIdleService.h"
Expand Down Expand Up @@ -1527,6 +1530,10 @@ nsGlobalWindow::CleanUp()
mSpeechSynthesis = nullptr;
#endif

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
mOrientationChangeObserver = nullptr;
#endif

ClearControllers();

mOpener = nullptr; // Forces Release
Expand Down Expand Up @@ -1641,6 +1648,10 @@ nsGlobalWindow::FreeInnerObjects()
mScreen = nullptr;
}

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
mOrientationChangeObserver = nullptr;
#endif

if (mDoc) {
// Remember the document's principal and URI.
mDocumentPrincipal = mDoc->NodePrincipal();
Expand Down Expand Up @@ -13654,6 +13665,27 @@ nsGlobalWindow::DisableDeviceSensor(uint32_t aType)
}
}

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
void
nsGlobalWindow::EnableOrientationChangeListener()
{
MOZ_ASSERT(IsInnerWindow());

if (!mOrientationChangeObserver) {
mOrientationChangeObserver =
new WindowOrientationObserver(this);
}
}

void
nsGlobalWindow::DisableOrientationChangeListener()
{
MOZ_ASSERT(IsInnerWindow());

mOrientationChangeObserver = nullptr;
}
#endif

void
nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/)
{
Expand Down Expand Up @@ -14501,6 +14533,15 @@ nsGlobalWindow::IsModalContentWindow(JSContext* aCx, JSObject* aGlobal)
return xpc::WindowOrNull(aGlobal)->IsModalContentWindow();
}


#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
int16_t
nsGlobalWindow::Orientation() const
{
return WindowOrientationObserver::OrientationAngle();
}
#endif

NS_IMETHODIMP
nsGlobalWindow::GetConsole(JSContext* aCx,
JS::MutableHandle<JS::Value> aConsole)
Expand Down
16 changes: 16 additions & 0 deletions dom/base/nsGlobalWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ class RequestOrUSVString;
class Selection;
class SpeechSynthesis;
class WakeLock;
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
class WindowOrientationObserver;
#endif
namespace cache {
class CacheStorage;
} // namespace cache
Expand Down Expand Up @@ -656,6 +659,11 @@ class nsGlobalWindow : public mozilla::dom::EventTarget,
virtual void EnableDeviceSensor(uint32_t aType) override;
virtual void DisableDeviceSensor(uint32_t aType) override;

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
virtual void EnableOrientationChangeListener() override;
virtual void DisableOrientationChangeListener() override;
#endif

virtual void EnableTimeChangeNotifications() override;
virtual void DisableTimeChangeNotifications() override;

Expand Down Expand Up @@ -907,6 +915,10 @@ class nsGlobalWindow : public mozilla::dom::EventTarget,
mozilla::dom::Navigator* GetNavigator(mozilla::ErrorResult& aError);
nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
int16_t Orientation() const;
#endif

mozilla::dom::Console* GetConsole(mozilla::ErrorResult& aRv);

void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult,
Expand Down Expand Up @@ -1822,6 +1834,10 @@ class nsGlobalWindow : public mozilla::dom::EventTarget,

nsTArray<uint32_t> mEnabledSensors;

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
nsAutoPtr<mozilla::dom::WindowOrientationObserver> mOrientationChangeObserver;
#endif

#ifdef MOZ_WEBSPEECH
// mSpeechSynthesis is only used on inner windows.
RefPtr<mozilla::dom::SpeechSynthesis> mSpeechSynthesis;
Expand Down
5 changes: 5 additions & 0 deletions dom/base/nsPIDOMWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,11 @@ class nsPIDOMWindow : public nsIDOMWindowInternal
*/
virtual void DisableDeviceSensor(uint32_t aType) = 0;

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
virtual void EnableOrientationChangeListener() = 0;
virtual void DisableOrientationChangeListener() = 0;
#endif

virtual void EnableTimeChangeNotifications() = 0;
virtual void DisableTimeChangeNotifications() = 0;

Expand Down
2 changes: 2 additions & 0 deletions dom/base/test/mochitest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ skip-if = buildapp == 'mulet'
[test_window_extensible.html]
[test_window_indexing.html]
[test_window_named_frame_enumeration.html]
[test_window_orientation.html]
skip-if = toolkit != 'gonk'
[test_writable-replaceable.html]
[test_navigatorPrefOverride.html]
[test_EventSource_redirects.html]
Expand Down
33 changes: 33 additions & 0 deletions dom/base/test/test_window_orientation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for window.orientation</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="orientationcommon.js"></script>
<div id="log"></div>
<script>
async_test(function(t) {
var originalOrientation = screen.orientation.type;
var alternateOrientation = originalOrientation == "portrait-primary" ?
"landscape-primary" : "portrait-primary";

var originalWindowOrientation = window.orientation;
window.onorientationchange = function() {
t.step(function() { assert_not_equals(window.orientation, originalWindowOrientation); });

var p2 = specialPowersUnlock();
p2.then(function() {
t.done();
}).catch(t.step_func(function(err) {
assert_unreached("Error unlocking orientation: " + err);
t.done();
}));
}

var p1 = specialPowersLock(alternateOrientation);
p1.catch(t.step_func(function(err) {
assert_unreached("Error locking orientation: " + err);
t.done();
}));
}, "Test window.orientation and orientationchange.");
</script>
17 changes: 17 additions & 0 deletions dom/events/EventListenerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ EventListenerManager::AddEventListenerInternal(
EnableDevice(eDeviceLight);
} else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
EnableDevice(eDeviceMotion);
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
} else if (aTypeAtom == nsGkAtoms::onorientationchange) {
EnableDevice(eOrientationChange);
#endif
#ifdef MOZ_B2G
} else if (aTypeAtom == nsGkAtoms::onmoztimechange) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
Expand Down Expand Up @@ -431,6 +435,9 @@ EventListenerManager::IsDeviceType(EventMessage aEventMessage)
case eDeviceLight:
case eDeviceProximity:
case eUserProximity:
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
case eOrientationChange:
#endif
return true;
default:
break;
Expand Down Expand Up @@ -462,6 +469,11 @@ EventListenerManager::EnableDevice(EventMessage aEventMessage)
window->EnableDeviceSensor(SENSOR_LINEAR_ACCELERATION);
window->EnableDeviceSensor(SENSOR_GYROSCOPE);
break;
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
case eOrientationChange:
window->EnableOrientationChangeListener();
break;
#endif
default:
NS_WARNING("Enabling an unknown device sensor.");
break;
Expand Down Expand Up @@ -492,6 +504,11 @@ EventListenerManager::DisableDevice(EventMessage aEventMessage)
case eDeviceLight:
window->DisableDeviceSensor(SENSOR_LIGHT);
break;
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
case eOrientationChange:
window->DisableOrientationChangeListener();
break;
#endif
default:
NS_WARNING("Disabling an unknown device sensor.");
break;
Expand Down
6 changes: 6 additions & 0 deletions dom/events/EventNameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,12 @@ WINDOW_EVENT(online,
eOnline,
EventNameType_XUL | EventNameType_HTMLBodyOrFramesetOnly,
eBasicEventClass)
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
WINDOW_EVENT(orientationchange,
eOrientationChange,
EventNameType_HTMLBodyOrFramesetOnly,
eBasicEventClass)
#endif
WINDOW_EVENT(pagehide,
ePageHide,
EventNameType_HTMLBodyOrFramesetOnly,
Expand Down
8 changes: 8 additions & 0 deletions dom/webidl/Window.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,14 @@ Window implements TouchEventHandlers;

Window implements OnErrorEventHandlerForWindow;

#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
// https://compat.spec.whatwg.org/#windoworientation-interface
partial interface Window {
readonly attribute short orientation;
attribute EventHandler onorientationchange;
};
#endif

// ConsoleAPI
partial interface Window {
[Replaceable, GetterThrows]
Expand Down
3 changes: 3 additions & 0 deletions widget/EventMessageList.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ NS_EVENT_MESSAGE(eDeviceMotion)
NS_EVENT_MESSAGE(eDeviceProximity)
NS_EVENT_MESSAGE(eUserProximity)
NS_EVENT_MESSAGE(eDeviceLight)
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
NS_EVENT_MESSAGE(eOrientationChange)
#endif

NS_EVENT_MESSAGE(eShow)

Expand Down

0 comments on commit 1799f33

Please sign in to comment.