Remove vibrator DOM interface and support code.
parent
2290a2a266
commit
a167facb42
|
@ -526,7 +526,6 @@ hardware/lights.h
|
||||||
hardware/power.h
|
hardware/power.h
|
||||||
hardware_legacy/power.h
|
hardware_legacy/power.h
|
||||||
hardware_legacy/uevent.h
|
hardware_legacy/uevent.h
|
||||||
hardware_legacy/vibrator.h
|
|
||||||
#endif
|
#endif
|
||||||
HIToolbox/HIToolbox.h
|
HIToolbox/HIToolbox.h
|
||||||
hlink.h
|
hlink.h
|
||||||
|
|
|
@ -97,11 +97,6 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
static bool sVibratorEnabled = false;
|
|
||||||
static uint32_t sMaxVibrateMS = 0;
|
|
||||||
static uint32_t sMaxVibrateListLen = 0;
|
|
||||||
static const char* kVibrationPermissionType = "vibration";
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AddPermission(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPermission,
|
AddPermission(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPermission,
|
||||||
uint32_t aExpireType, int64_t aExpireTime)
|
uint32_t aExpireType, int64_t aExpireTime)
|
||||||
|
@ -152,12 +147,7 @@ GetPermission(nsIPrincipal* aPrincipal, const char* aType)
|
||||||
void
|
void
|
||||||
Navigator::Init()
|
Navigator::Init()
|
||||||
{
|
{
|
||||||
Preferences::AddBoolVarCache(&sVibratorEnabled,
|
// Add any Preferences::Add*VarCache(&sPref, "pref", default) here if needed.
|
||||||
"dom.vibrator.enabled", true);
|
|
||||||
Preferences::AddUintVarCache(&sMaxVibrateMS,
|
|
||||||
"dom.vibrator.max_vibrate_ms", 10000);
|
|
||||||
Preferences::AddUintVarCache(&sMaxVibrateListLen,
|
|
||||||
"dom.vibrator.max_vibrate_list_len", 128);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigator::Navigator(nsPIDOMWindowInner* aWindow)
|
Navigator::Navigator(nsPIDOMWindowInner* aWindow)
|
||||||
|
@ -705,82 +695,6 @@ Navigator::RefreshMIMEArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class VibrateWindowListener : public nsIDOMEventListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VibrateWindowListener(nsPIDOMWindowInner* aWindow, nsIDocument* aDocument)
|
|
||||||
{
|
|
||||||
mWindow = do_GetWeakReference(aWindow);
|
|
||||||
mDocument = do_GetWeakReference(aDocument);
|
|
||||||
|
|
||||||
NS_NAMED_LITERAL_STRING(visibilitychange, "visibilitychange");
|
|
||||||
aDocument->AddSystemEventListener(visibilitychange,
|
|
||||||
this, /* listener */
|
|
||||||
true, /* use capture */
|
|
||||||
false /* wants untrusted */);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveListener();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIDOMEVENTLISTENER
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual ~VibrateWindowListener()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nsWeakPtr mWindow;
|
|
||||||
nsWeakPtr mDocument;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(VibrateWindowListener, nsIDOMEventListener)
|
|
||||||
|
|
||||||
StaticRefPtr<VibrateWindowListener> gVibrateWindowListener;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
MayVibrate(nsIDocument* doc) {
|
|
||||||
// Hidden documents cannot start or stop a vibration.
|
|
||||||
return (doc && !doc->Hidden());
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
VibrateWindowListener::HandleEvent(nsIDOMEvent* aEvent)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDocument> doc =
|
|
||||||
do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
|
|
||||||
|
|
||||||
if (!MayVibrate(doc)) {
|
|
||||||
// It's important that we call CancelVibrate(), not Vibrate() with an
|
|
||||||
// empty list, because Vibrate() will fail if we're no longer focused, but
|
|
||||||
// CancelVibrate() will succeed, so long as nobody else has started a new
|
|
||||||
// vibration pattern.
|
|
||||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(mWindow);
|
|
||||||
hal::CancelVibrate(window);
|
|
||||||
RemoveListener();
|
|
||||||
gVibrateWindowListener = nullptr;
|
|
||||||
// Careful: The line above might have deleted |this|!
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VibrateWindowListener::RemoveListener()
|
|
||||||
{
|
|
||||||
nsCOMPtr<EventTarget> target = do_QueryReferent(mDocument);
|
|
||||||
if (!target) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NS_NAMED_LITERAL_STRING(visibilitychange, "visibilitychange");
|
|
||||||
target->RemoveSystemEventListener(visibilitychange, this,
|
|
||||||
true /* use capture */);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Navigator::AddIdleObserver(MozIdleObserver& aIdleObserver, ErrorResult& aRv)
|
Navigator::AddIdleObserver(MozIdleObserver& aIdleObserver, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
@ -809,111 +723,6 @@ Navigator::RemoveIdleObserver(MozIdleObserver& aIdleObserver, ErrorResult& aRv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Navigator::SetVibrationPermission(bool aPermitted, bool aPersistent)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsTArray<uint32_t> pattern;
|
|
||||||
pattern.SwapElements(mRequestedVibrationPattern);
|
|
||||||
|
|
||||||
if (!mWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
|
|
||||||
|
|
||||||
if (!MayVibrate(doc)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aPermitted) {
|
|
||||||
// Add a listener to cancel the vibration if the document becomes hidden,
|
|
||||||
// and remove the old visibility listener, if there was one.
|
|
||||||
if (!gVibrateWindowListener) {
|
|
||||||
// If gVibrateWindowListener is null, this is the first time we've vibrated,
|
|
||||||
// and we need to register a listener to clear gVibrateWindowListener on
|
|
||||||
// shutdown.
|
|
||||||
ClearOnShutdown(&gVibrateWindowListener);
|
|
||||||
} else {
|
|
||||||
gVibrateWindowListener->RemoveListener();
|
|
||||||
}
|
|
||||||
gVibrateWindowListener = new VibrateWindowListener(mWindow, doc);
|
|
||||||
hal::Vibrate(pattern, mWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aPersistent) {
|
|
||||||
AddPermission(doc->NodePrincipal(), kVibrationPermissionType,
|
|
||||||
aPermitted ? nsIPermissionManager::ALLOW_ACTION :
|
|
||||||
nsIPermissionManager::DENY_ACTION,
|
|
||||||
nsIPermissionManager::EXPIRE_SESSION, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Navigator::Vibrate(uint32_t aDuration)
|
|
||||||
{
|
|
||||||
AutoTArray<uint32_t, 1> pattern;
|
|
||||||
pattern.AppendElement(aDuration);
|
|
||||||
return Vibrate(pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
if (!mWindow) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
|
|
||||||
|
|
||||||
if (!MayVibrate(doc)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsTArray<uint32_t> pattern(aPattern);
|
|
||||||
|
|
||||||
if (pattern.Length() > sMaxVibrateListLen) {
|
|
||||||
pattern.SetLength(sMaxVibrateListLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < pattern.Length(); ++i) {
|
|
||||||
pattern[i] = std::min(sMaxVibrateMS, pattern[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The spec says we check sVibratorEnabled after we've done the sanity
|
|
||||||
// checking on the pattern.
|
|
||||||
if (!sVibratorEnabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mRequestedVibrationPattern.SwapElements(pattern);
|
|
||||||
uint32_t permission = GetPermission(mWindow, kVibrationPermissionType);
|
|
||||||
|
|
||||||
if (permission == nsIPermissionManager::ALLOW_ACTION ||
|
|
||||||
mRequestedVibrationPattern.IsEmpty() ||
|
|
||||||
(mRequestedVibrationPattern.Length() == 1 &&
|
|
||||||
mRequestedVibrationPattern[0] == 0)) {
|
|
||||||
// Always allow cancelling vibration and respect session permissions.
|
|
||||||
SetVibrationPermission(true /* permitted */, false /* persistent */);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
|
||||||
if (!obs || permission == nsIPermissionManager::DENY_ACTION) {
|
|
||||||
// Abort without observer service or on denied session permission.
|
|
||||||
SetVibrationPermission(false /* permitted */, false /* persistent */);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request user permission.
|
|
||||||
obs->NotifyObservers(ToSupports(this), "Vibration:Request", nullptr);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Pointer Events interface
|
// Pointer Events interface
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
|
@ -149,9 +149,6 @@ public:
|
||||||
// NavigatorBinding::ClearCachedUserAgentValue(this);
|
// NavigatorBinding::ClearCachedUserAgentValue(this);
|
||||||
void ClearUserAgentCache();
|
void ClearUserAgentCache();
|
||||||
|
|
||||||
bool Vibrate(uint32_t aDuration);
|
|
||||||
bool Vibrate(const nsTArray<uint32_t>& aDuration);
|
|
||||||
void SetVibrationPermission(bool aPermitted, bool aPersistent);
|
|
||||||
uint32_t MaxTouchPoints();
|
uint32_t MaxTouchPoints();
|
||||||
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
|
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,7 +122,6 @@ run-if = e10s
|
||||||
[test_storagePermissionsReject.html]
|
[test_storagePermissionsReject.html]
|
||||||
[test_storagePermissionsRejectForeign.html]
|
[test_storagePermissionsRejectForeign.html]
|
||||||
[test_stylesheetPI.html]
|
[test_stylesheetPI.html]
|
||||||
[test_vibrator.html]
|
|
||||||
[test_WebKitCSSMatrix.html]
|
[test_WebKitCSSMatrix.html]
|
||||||
[test_windowedhistoryframes.html]
|
[test_windowedhistoryframes.html]
|
||||||
[test_windowProperties.html]
|
[test_windowProperties.html]
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for Vibrator</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<!-- Although we can't test that the vibrator works properly, we can test that
|
|
||||||
navigator.vibrate throws an exception where appropriate. -->
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
var result;
|
|
||||||
function expectFailure(param) {
|
|
||||||
result = navigator.vibrate(param);
|
|
||||||
is(result, false, 'vibrate(' + param + ') should have failed.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectSuccess(param) {
|
|
||||||
result = navigator.vibrate(param);
|
|
||||||
is(result, true, 'vibrate(' + param + ') must succeed.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function tests(aEnabled) {
|
|
||||||
// Some edge cases that the bindings should handle for us.
|
|
||||||
expectSuccess(null);
|
|
||||||
expectSuccess(undefined);
|
|
||||||
// -1 will be converted to the highest unsigned long then clamped.
|
|
||||||
expectSuccess(-1);
|
|
||||||
expectSuccess('a');
|
|
||||||
// -1 will be converted to the highest unsigned long then clamped.
|
|
||||||
expectSuccess([100, -1]);
|
|
||||||
expectSuccess([100, 'a']);
|
|
||||||
|
|
||||||
var maxVibrateMs = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_ms');
|
|
||||||
var maxVibrateListLen = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_list_len');
|
|
||||||
|
|
||||||
// If we pass a vibration pattern with a value higher than max_vibrate_ms or a
|
|
||||||
// pattern longer than max_vibrate_list_len, the call should succeed but the
|
|
||||||
// pattern should be modified to match the restrictions.
|
|
||||||
|
|
||||||
// Values will be clamped to dom.vibrator.max_vibrate_ms.
|
|
||||||
expectSuccess(maxVibrateMs + 1);
|
|
||||||
expectSuccess([maxVibrateMs + 1]);
|
|
||||||
|
|
||||||
var arr = [];
|
|
||||||
for (var i = 0; i < maxVibrateListLen + 1; i++) {
|
|
||||||
arr[i] = 0;
|
|
||||||
}
|
|
||||||
// The array will be truncated to have a length equal to dom.vibrator.max_vibrate_list_len.
|
|
||||||
expectSuccess(arr);
|
|
||||||
|
|
||||||
|
|
||||||
expectSuccess(0);
|
|
||||||
expectSuccess([]);
|
|
||||||
expectSuccess('1000');
|
|
||||||
expectSuccess(1000);
|
|
||||||
expectSuccess(1000.1);
|
|
||||||
expectSuccess([0, 0, 0]);
|
|
||||||
expectSuccess(['1000', 1000]);
|
|
||||||
expectSuccess([1000, 1000]);
|
|
||||||
expectSuccess([1000, 1000.1]);
|
|
||||||
|
|
||||||
// The following loop shouldn't cause us to crash. See bug 701716.
|
|
||||||
for (var i = 0; i < 10000; i++) {
|
|
||||||
navigator.vibrate([100, 100]);
|
|
||||||
}
|
|
||||||
ok(true, "Didn't crash after issuing a lot of vibrate() calls.");
|
|
||||||
if(!aEnabled)
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{type: 'vibration', allow: true, context: document}
|
|
||||||
], function() {
|
|
||||||
// Test with the vibrator pref enabled.
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [['dom.vibrator.enabled', true]]}, function() {
|
|
||||||
tests(true);
|
|
||||||
SpecialPowers.pushPrefEnv({"set": [['dom.vibrator.enabled', false]]}, tests(false));
|
|
||||||
});
|
|
||||||
// Everything should be the same when the vibrator is disabled -- in
|
|
||||||
// particular, a disabled vibrator shouldn't eat failures we'd otherwise
|
|
||||||
// observe.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -13,9 +13,9 @@
|
||||||
* http://www.w3.org/TR/beacon/#sec-beacon-method
|
* http://www.w3.org/TR/beacon/#sec-beacon-method
|
||||||
* https://html.spec.whatwg.org/#navigatorconcurrenthardware
|
* https://html.spec.whatwg.org/#navigatorconcurrenthardware
|
||||||
*
|
*
|
||||||
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
|
* © Copyright 2004-2020 Apple Computer, Inc., Mozilla Foundation,
|
||||||
* Opera Software ASA. You are granted a license to use, reproduce
|
* Opera Software ASA and Moonchild Productions. You are granted a license to use,
|
||||||
* and create derivative works of this document.
|
* reproduce and create derivative works of this document.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
||||||
|
@ -124,14 +124,6 @@ interface NavigatorGeolocation {
|
||||||
};
|
};
|
||||||
Navigator implements NavigatorGeolocation;
|
Navigator implements NavigatorGeolocation;
|
||||||
|
|
||||||
// http://www.w3.org/TR/vibration/#vibration-interface
|
|
||||||
partial interface Navigator {
|
|
||||||
// We don't support sequences in unions yet
|
|
||||||
//boolean vibrate ((unsigned long or sequence<unsigned long>) pattern);
|
|
||||||
boolean vibrate(unsigned long duration);
|
|
||||||
boolean vibrate(sequence<unsigned long> pattern);
|
|
||||||
};
|
|
||||||
|
|
||||||
// http://www.w3.org/TR/pointerevents/#extensions-to-the-navigator-interface
|
// http://www.w3.org/TR/pointerevents/#extensions-to-the-navigator-interface
|
||||||
partial interface Navigator {
|
partial interface Navigator {
|
||||||
[Pref="dom.w3c_pointer_events.enabled"]
|
[Pref="dom.w3c_pointer_events.enabled"]
|
||||||
|
@ -140,17 +132,6 @@ partial interface Navigator {
|
||||||
|
|
||||||
// Mozilla-specific extensions
|
// Mozilla-specific extensions
|
||||||
|
|
||||||
// Chrome-only interface for Vibration API permission handling.
|
|
||||||
partial interface Navigator {
|
|
||||||
/* Set permission state to device vibration.
|
|
||||||
* @param permitted permission state (true for allowing vibration)
|
|
||||||
* @param persistent make the permission session-persistent
|
|
||||||
*/
|
|
||||||
[ChromeOnly]
|
|
||||||
void setVibrationPermission(boolean permitted,
|
|
||||||
optional boolean persistent = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
callback interface MozIdleObserver {
|
callback interface MozIdleObserver {
|
||||||
// Time is in seconds and is read only when idle observers are added
|
// Time is in seconds and is read only when idle observers are added
|
||||||
// and removed.
|
// and removed.
|
||||||
|
|
79
hal/Hal.cpp
79
hal/Hal.cpp
|
@ -94,87 +94,8 @@ WindowIsActive(nsPIDOMWindowInner* aWindow)
|
||||||
return !document->Hidden();
|
return !document->Hidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
|
|
||||||
|
|
||||||
void InitLastIDToVibrate()
|
|
||||||
{
|
|
||||||
gLastIDToVibrate = new WindowIdentifier::IDArrayType();
|
|
||||||
ClearOnShutdown(&gLastIDToVibrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void
|
|
||||||
Vibrate(const nsTArray<uint32_t>& pattern, nsPIDOMWindowInner* window)
|
|
||||||
{
|
|
||||||
Vibrate(pattern, WindowIdentifier(window));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
|
|
||||||
{
|
|
||||||
AssertMainThread();
|
|
||||||
|
|
||||||
// Only active windows may start vibrations. If |id| hasn't gone
|
|
||||||
// through the IPC layer -- that is, if our caller is the outside
|
|
||||||
// world, not hal_proxy -- check whether the window is active. If
|
|
||||||
// |id| has gone through IPC, don't check the window's visibility;
|
|
||||||
// only the window corresponding to the bottommost process has its
|
|
||||||
// visibility state set correctly.
|
|
||||||
if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
|
|
||||||
HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!InSandbox()) {
|
|
||||||
if (!gLastIDToVibrate) {
|
|
||||||
InitLastIDToVibrate();
|
|
||||||
}
|
|
||||||
*gLastIDToVibrate = id.AsArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't forward our ID if we are not in the sandbox, because hal_impl
|
|
||||||
// doesn't need it, and we don't want it to be tempted to read it. The
|
|
||||||
// empty identifier will assert if it's used.
|
|
||||||
PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CancelVibrate(nsPIDOMWindowInner* window)
|
|
||||||
{
|
|
||||||
CancelVibrate(WindowIdentifier(window));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CancelVibrate(const WindowIdentifier &id)
|
|
||||||
{
|
|
||||||
AssertMainThread();
|
|
||||||
|
|
||||||
// Although only active windows may start vibrations, a window may
|
|
||||||
// cancel its own vibration even if it's no longer active.
|
|
||||||
//
|
|
||||||
// After a window is marked as inactive, it sends a CancelVibrate
|
|
||||||
// request. We want this request to cancel a playing vibration
|
|
||||||
// started by that window, so we certainly don't want to reject the
|
|
||||||
// cancellation request because the window is now inactive.
|
|
||||||
//
|
|
||||||
// But it could be the case that, after this window became inactive,
|
|
||||||
// some other window came along and started a vibration. We don't
|
|
||||||
// want this window's cancellation request to cancel that window's
|
|
||||||
// actively-playing vibration!
|
|
||||||
//
|
|
||||||
// To solve this problem, we keep track of the id of the last window
|
|
||||||
// to start a vibration, and only accepts cancellation requests from
|
|
||||||
// the same window. All other cancellation requests are ignored.
|
|
||||||
|
|
||||||
if (InSandbox() || (gLastIDToVibrate && *gLastIDToVibrate == id.AsArray())) {
|
|
||||||
// Don't forward our ID if we are not in the sandbox, because hal_impl
|
|
||||||
// doesn't need it, and we don't want it to be tempted to read it. The
|
|
||||||
// empty identifier will assert if it's used.
|
|
||||||
PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id : WindowIdentifier()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class InfoType>
|
template <class InfoType>
|
||||||
class ObserversManager
|
class ObserversManager
|
||||||
{
|
{
|
||||||
|
|
35
hal/Hal.h
35
hal/Hal.h
|
@ -50,41 +50,6 @@ typedef Observer<SystemTimezoneChangeInformation> SystemTimezoneChangeObserver;
|
||||||
|
|
||||||
namespace MOZ_HAL_NAMESPACE {
|
namespace MOZ_HAL_NAMESPACE {
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn the default vibrator device on/off per the pattern specified
|
|
||||||
* by |pattern|. Each element in the pattern is the number of
|
|
||||||
* milliseconds to turn the vibrator on or off. The first element in
|
|
||||||
* |pattern| is an "on" element, the next is "off", and so on.
|
|
||||||
*
|
|
||||||
* If |pattern| is empty, any in-progress vibration is canceled.
|
|
||||||
*
|
|
||||||
* Only an active window within an active tab may call Vibrate; calls
|
|
||||||
* from inactive windows and windows on inactive tabs do nothing.
|
|
||||||
*
|
|
||||||
* If you're calling hal::Vibrate from the outside world, pass an
|
|
||||||
* nsIDOMWindow* in place of the WindowIdentifier parameter.
|
|
||||||
* The method with WindowIdentifier will be called automatically.
|
|
||||||
*/
|
|
||||||
void Vibrate(const nsTArray<uint32_t>& pattern,
|
|
||||||
nsPIDOMWindowInner* aWindow);
|
|
||||||
void Vibrate(const nsTArray<uint32_t>& pattern,
|
|
||||||
const hal::WindowIdentifier &id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel a vibration started by the content window identified by
|
|
||||||
* WindowIdentifier.
|
|
||||||
*
|
|
||||||
* If the window was the last window to start a vibration, the
|
|
||||||
* cancellation request will go through even if the window is not
|
|
||||||
* active.
|
|
||||||
*
|
|
||||||
* As with hal::Vibrate(), if you're calling hal::CancelVibrate from the outside
|
|
||||||
* world, pass an nsIDOMWindow*. The method with WindowIdentifier will be called
|
|
||||||
* automatically.
|
|
||||||
*/
|
|
||||||
void CancelVibrate(nsPIDOMWindowInner* aWindow);
|
|
||||||
void CancelVibrate(const hal::WindowIdentifier &id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the device's screen is currently enabled.
|
* Determine whether the device's screen is currently enabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* 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 "Hal.h"
|
|
||||||
|
|
||||||
using mozilla::hal::WindowIdentifier;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace hal_impl {
|
|
||||||
|
|
||||||
void
|
|
||||||
Vibrate(const nsTArray<uint32_t>& pattern, const hal::WindowIdentifier &)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
CancelVibrate(const hal::WindowIdentifier &)
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // namespace hal_impl
|
|
||||||
} // namespace mozilla
|
|
|
@ -43,7 +43,6 @@ elif CONFIG['OS_TARGET'] == 'Linux':
|
||||||
'fallback/FallbackAlarm.cpp',
|
'fallback/FallbackAlarm.cpp',
|
||||||
'fallback/FallbackScreenConfiguration.cpp',
|
'fallback/FallbackScreenConfiguration.cpp',
|
||||||
'fallback/FallbackSensor.cpp',
|
'fallback/FallbackSensor.cpp',
|
||||||
'fallback/FallbackVibration.cpp',
|
|
||||||
'linux/LinuxMemory.cpp',
|
'linux/LinuxMemory.cpp',
|
||||||
'linux/LinuxPower.cpp',
|
'linux/LinuxPower.cpp',
|
||||||
]
|
]
|
||||||
|
@ -53,7 +52,6 @@ elif CONFIG['OS_TARGET'] == 'WINNT':
|
||||||
'fallback/FallbackMemory.cpp',
|
'fallback/FallbackMemory.cpp',
|
||||||
'fallback/FallbackPower.cpp',
|
'fallback/FallbackPower.cpp',
|
||||||
'fallback/FallbackScreenConfiguration.cpp',
|
'fallback/FallbackScreenConfiguration.cpp',
|
||||||
'fallback/FallbackVibration.cpp',
|
|
||||||
'windows/WindowsSensor.cpp',
|
'windows/WindowsSensor.cpp',
|
||||||
]
|
]
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||||
|
@ -62,7 +60,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||||
'fallback/FallbackMemory.cpp',
|
'fallback/FallbackMemory.cpp',
|
||||||
'fallback/FallbackPower.cpp',
|
'fallback/FallbackPower.cpp',
|
||||||
'fallback/FallbackScreenConfiguration.cpp',
|
'fallback/FallbackScreenConfiguration.cpp',
|
||||||
'fallback/FallbackVibration.cpp',
|
|
||||||
]
|
]
|
||||||
elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
@ -71,7 +68,6 @@ elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
||||||
'fallback/FallbackPower.cpp',
|
'fallback/FallbackPower.cpp',
|
||||||
'fallback/FallbackScreenConfiguration.cpp',
|
'fallback/FallbackScreenConfiguration.cpp',
|
||||||
'fallback/FallbackSensor.cpp',
|
'fallback/FallbackSensor.cpp',
|
||||||
'fallback/FallbackVibration.cpp',
|
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
@ -80,7 +76,6 @@ else:
|
||||||
'fallback/FallbackPower.cpp',
|
'fallback/FallbackPower.cpp',
|
||||||
'fallback/FallbackScreenConfiguration.cpp',
|
'fallback/FallbackScreenConfiguration.cpp',
|
||||||
'fallback/FallbackSensor.cpp',
|
'fallback/FallbackSensor.cpp',
|
||||||
'fallback/FallbackVibration.cpp',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
|
|
@ -69,9 +69,6 @@ child:
|
||||||
async NotifySystemTimezoneChange(SystemTimezoneChangeInformation aSystemTimezoneChangeInfo);
|
async NotifySystemTimezoneChange(SystemTimezoneChangeInformation aSystemTimezoneChangeInfo);
|
||||||
|
|
||||||
parent:
|
parent:
|
||||||
async Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser);
|
|
||||||
async CancelVibrate(uint64_t[] id, PBrowser browser);
|
|
||||||
|
|
||||||
async EnableNetworkNotifications();
|
async EnableNetworkNotifications();
|
||||||
async DisableNetworkNotifications();
|
async DisableNetworkNotifications();
|
||||||
sync GetCurrentNetworkInformation()
|
sync GetCurrentNetworkInformation()
|
||||||
|
|
|
@ -45,28 +45,6 @@ Hal()
|
||||||
return sHal;
|
return sHal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
|
|
||||||
{
|
|
||||||
HAL_LOG("Vibrate: Sending to parent process.");
|
|
||||||
|
|
||||||
AutoTArray<uint32_t, 8> p(pattern);
|
|
||||||
|
|
||||||
WindowIdentifier newID(id);
|
|
||||||
newID.AppendProcessID();
|
|
||||||
Hal()->SendVibrate(p, newID.AsArray(), TabChild::GetFrom(newID.GetWindow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CancelVibrate(const WindowIdentifier &id)
|
|
||||||
{
|
|
||||||
HAL_LOG("CancelVibrate: Sending to parent process.");
|
|
||||||
|
|
||||||
WindowIdentifier newID(id);
|
|
||||||
newID.AppendProcessID();
|
|
||||||
Hal()->SendCancelVibrate(newID.AsArray(), TabChild::GetFrom(newID.GetWindow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EnableNetworkNotifications()
|
EnableNetworkNotifications()
|
||||||
{
|
{
|
||||||
|
@ -379,36 +357,6 @@ public:
|
||||||
hal::UnregisterSystemTimezoneChangeObserver(this);
|
hal::UnregisterSystemTimezoneChangeObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool
|
|
||||||
RecvVibrate(InfallibleTArray<unsigned int>&& pattern,
|
|
||||||
InfallibleTArray<uint64_t>&& id,
|
|
||||||
PBrowserParent *browserParent) override
|
|
||||||
{
|
|
||||||
// We give all content vibration permission.
|
|
||||||
// TabParent *tabParent = TabParent::GetFrom(browserParent);
|
|
||||||
/* xxxkhuey wtf
|
|
||||||
nsCOMPtr<nsIDOMWindow> window =
|
|
||||||
do_QueryInterface(tabParent->GetBrowserDOMWindow());
|
|
||||||
*/
|
|
||||||
WindowIdentifier newID(id, nullptr);
|
|
||||||
hal::Vibrate(pattern, newID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
RecvCancelVibrate(InfallibleTArray<uint64_t> &&id,
|
|
||||||
PBrowserParent *browserParent) override
|
|
||||||
{
|
|
||||||
//TabParent *tabParent = TabParent::GetFrom(browserParent);
|
|
||||||
/* XXXkhuey wtf
|
|
||||||
nsCOMPtr<nsIDOMWindow> window =
|
|
||||||
tabParent->GetBrowserDOMWindow();
|
|
||||||
*/
|
|
||||||
WindowIdentifier newID(id, nullptr);
|
|
||||||
hal::CancelVibrate(newID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
RecvEnableNetworkNotifications() override {
|
RecvEnableNetworkNotifications() override {
|
||||||
// We give all content access to this network-status information.
|
// We give all content access to this network-status information.
|
||||||
|
|
|
@ -4751,10 +4751,6 @@ pref("dom.event.handling-user-input-time-limit", 1000);
|
||||||
// Whether we should layerize all animated images (if otherwise possible).
|
// Whether we should layerize all animated images (if otherwise possible).
|
||||||
pref("layout.animated-image-layers.enabled", false);
|
pref("layout.animated-image-layers.enabled", false);
|
||||||
|
|
||||||
pref("dom.vibrator.enabled", true);
|
|
||||||
pref("dom.vibrator.max_vibrate_ms", 10000);
|
|
||||||
pref("dom.vibrator.max_vibrate_list_len", 128);
|
|
||||||
|
|
||||||
// Abort API
|
// Abort API
|
||||||
pref("dom.abortController.enabled", true);
|
pref("dom.abortController.enabled", true);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
@dontcallmedom
|
|
||||||
@zqzhang
|
|
||||||
@xinliux
|
|
|
@ -1,27 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test that the vibrate() method is present (with or without vendor prefix)</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom'/>
|
|
||||||
<meta name='assert' content='Check that the vibrate() method is present.'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
This test checks for the presence of the <code>vibrate()</code> method, taking
|
|
||||||
vendor prefixes into account.
|
|
||||||
</p>
|
|
||||||
<div id='log'></div>
|
|
||||||
<script src='/resources/testharness.js'></script>
|
|
||||||
<script src='/resources/testharnessreport.js'></script>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
test(function () {
|
|
||||||
assert_true(undefined !== navigator.vibrate, "navigator.vibrate exists");
|
|
||||||
}, "vibrate() is present on navigator");
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,38 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
<title>Vibration API: cancel ongoing vibrate() when hidden by switching tab/window</title>
|
|
||||||
<link rel='author' title='Intel' href='http://www.intel.com'>
|
|
||||||
<link rel='help' href='http://dev.w3.org/2009/dap/vibration/#vibration-interface'>
|
|
||||||
<meta name='flags' content='interact'>
|
|
||||||
<meta name='assert' content='If the visibilitychange event is dispatched at the Document in a browsing context, cancel the pre-existing instance of the processing vibration patterns algorithm'>
|
|
||||||
<style>
|
|
||||||
button {
|
|
||||||
height: 100px;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate for a short period of time (roughly one
|
|
||||||
second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
|
|
||||||
the test has failed.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
var win;
|
|
||||||
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById('vib').onclick = function () {
|
|
||||||
navigator.vibrate(5000);
|
|
||||||
setTimeout(function () {
|
|
||||||
win = window.open('about:blank', '_blank');
|
|
||||||
setTimeout(function() {
|
|
||||||
win.close();
|
|
||||||
}, 100);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: cancel ongoing vibrate() with 0</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
<meta name='assert' content='If pattern is 0, cancel the pre-existing instance of the processing vibration patterns algorithm'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate for a short period of time (roughly one
|
|
||||||
second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
|
|
||||||
the test has failed.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate(5000);
|
|
||||||
setTimeout(function () {
|
|
||||||
navigator.vibrate(0);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
<title>Vibration API: cancel ongoing vibrate() with [0]</title>
|
|
||||||
<link rel='author' title='Intel' href='http://www.intel.com'>
|
|
||||||
<link rel='help' href='http://dev.w3.org/2009/dap/vibration/#vibration-interface'>
|
|
||||||
<meta name='flags' content='interact'>
|
|
||||||
<meta name='assert' content='If pattern contains a single entry with a value of 0, cancel the pre-existing instance of the processing vibration patterns algorithm'>
|
|
||||||
<style>
|
|
||||||
button {
|
|
||||||
height: 100px;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate for a short period of time (roughly one
|
|
||||||
second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
|
|
||||||
the test has failed.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById('vib').onclick = function () {
|
|
||||||
navigator.vibrate(5000);
|
|
||||||
setTimeout(function () {
|
|
||||||
navigator.vibrate([0]);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: cancel ongoing vibrate() with []</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
<meta name='assert' content='If pattern is an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate for a short period of time (roughly one
|
|
||||||
second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
|
|
||||||
the test has failed.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate(5000);
|
|
||||||
setTimeout(function () {
|
|
||||||
navigator.vibrate([]);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,32 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: cancel ongoing vibrate() with a new call to vibrate</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
<meta name='assert' content='Cancel the pre-existing instance of the processing vibration patterns algorithm, if any.'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate continuously for a short period of time (roughly one
|
|
||||||
second), then vibrate a series of short bursts. If the initial continuously vibration is longer (roughly five
|
|
||||||
seconds, it should feel somewhat long) or if there is no series of short vibration bursts then the test has
|
|
||||||
failed.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate(5000);
|
|
||||||
setTimeout(function () {
|
|
||||||
navigator.vibrate([200, 200, 200, 200, 200, 200, 200, 200, 200]);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<title>IDL harness tests for Vibration API</title>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
This test validates the IDL defined by the Vibration API.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
This test uses <a href="/resources/idlharness.js">idlharness.js</a>
|
|
||||||
</p>
|
|
||||||
<div id="log"></div>
|
|
||||||
<script src=/resources/testharness.js></script>
|
|
||||||
<script src=/resources/testharnessreport.js></script>
|
|
||||||
<script src=/resources/WebIDLParser.js></script>
|
|
||||||
<script src=/resources/idlharness.js></script>
|
|
||||||
<script>
|
|
||||||
var idl_array = new IdlArray();
|
|
||||||
idl_array.add_untested_idls("interface Navigator {};");
|
|
||||||
idl_array.add_idls("partial interface Navigator { boolean vibrate ((unsigned long or sequence<unsigned long>) pattern);};");
|
|
||||||
idl_array.add_objects({Navigator: ['navigator']});
|
|
||||||
idl_array.test();
|
|
||||||
</script>
|
|
|
@ -1,79 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
<title>Vibration API: vibrate(invalid)</title>
|
|
||||||
<link rel='author' title='Intel' href='http://www.intel.com'>
|
|
||||||
<link rel='help' href='http://dev.w3.org/2009/dap/vibration/#vibration-interface'>
|
|
||||||
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
This test checks the <code>vibrate()</code> method with invalid parameter,
|
|
||||||
taking vendor prefixes into account.
|
|
||||||
</p>
|
|
||||||
<div id='log'></div>
|
|
||||||
<script src='/resources/testharness.js'></script>
|
|
||||||
<script src='/resources/testharnessreport.js'></script>
|
|
||||||
<script src='../support/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
test(function() {
|
|
||||||
assert_throws(new TypeError(), function() {
|
|
||||||
navigator.vibrate();
|
|
||||||
}, 'Argument is required, so was expecting a TypeError.');
|
|
||||||
}, 'Missing pattern argument');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate(undefined);
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of undefined resolves to []');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate(null);
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of null resolves to []');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate('one');
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of empty string resolves to [""]');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate('one');
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of string resolves to ["one"]');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate(new String('one'));
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of String instance resolves to ["one"]');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate(NaN);
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of NaN resolves to [NaN]');
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
try {
|
|
||||||
navigator.vibrate({});
|
|
||||||
} catch(e) {
|
|
||||||
assert_unreached('error message: ' + e.message);
|
|
||||||
}
|
|
||||||
}, 'pattern of {} resolves to [{}]');
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test a pattern array parameter to vibrate() with an extra (even) item</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
<meta name='assert' content='If the length of pattern is even, then remove the last entry in pattern.'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate three times for one second, separated
|
|
||||||
by one second intervals.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate([1000, 1000, 1000, 1000, 1000, 1000]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test a pattern array parameter to vibrate()</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate three times for one second, separated
|
|
||||||
by one second intervals.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate([1000, 1000, 1000, 1000, 1000]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset='utf-8'>
|
|
||||||
<title>Vibration API: test a pattern array with 0ms vibration and still to vibrate()</title>
|
|
||||||
<link rel='author' title='Intel' href='http://www.intel.com'>
|
|
||||||
<link rel='help' href='http://dev.w3.org/2009/dap/vibration/#vibration-interface'>
|
|
||||||
<meta name='flags' content='interact'>
|
|
||||||
<style>
|
|
||||||
button {
|
|
||||||
height: 100px;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate continuously for about two seconds, once.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<div id='log'></div>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate([0, 0, 2000]);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test that calls to vibrate() are silently ignored when the device cannot vibrate</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, no-vibrator'/>
|
|
||||||
<meta name='assert' content='If the device does not provide a vibration mechanism, or it is disabled, the user agent must silently ignore any invocations of the vibrate() method.'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
<strong>This test is only useful on devices that do not have vibration capability</strong>.
|
|
||||||
If your device supports vibration, then <strong>skip</strong> this test. An implementation
|
|
||||||
supporting this API but running on a device that cannot vibrate must silently ignore the
|
|
||||||
call (we test that it doesn't throw).
|
|
||||||
</p>
|
|
||||||
<div id='log'></div>
|
|
||||||
<script src='/resources/testharness.js'></script>
|
|
||||||
<script src='/resources/testharnessreport.js'></script>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
test(function () {
|
|
||||||
assert_true(navigator.vibrate(1000), "vibrate() returns true when vibration is not supported");
|
|
||||||
}, "Calling vibrate returns true");
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test a simple array parameter to vibrate()</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate continuously for about two seconds, once.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<div id='log'></div>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate([2000]);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,25 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset='utf-8'/>
|
|
||||||
<title>Vibration API: test a simple scalar parameter to vibrate()</title>
|
|
||||||
<link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
|
|
||||||
<link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
|
|
||||||
<meta name='flags' content='dom, interact'/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Description</h1>
|
|
||||||
<p>
|
|
||||||
After hitting the button below, your device must vibrate continuously for about two seconds, once.
|
|
||||||
</p>
|
|
||||||
<button id='vib'>Vibrate!</button>
|
|
||||||
<script src='/common/vendor-prefix.js' data-prefixed-objects='[{"ancestors":["navigator"], "name":"vibrate"}]'></script>
|
|
||||||
<script>
|
|
||||||
if (undefined !== navigator.vibrate) {
|
|
||||||
document.getElementById("vib").onclick = function () {
|
|
||||||
navigator.vibrate(2000);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue