mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
2ffe6398eb
42 changed files with 222 additions and 1023 deletions
|
|
@ -526,7 +526,6 @@ hardware/lights.h
|
|||
hardware/power.h
|
||||
hardware_legacy/power.h
|
||||
hardware_legacy/uevent.h
|
||||
hardware_legacy/vibrator.h
|
||||
#endif
|
||||
HIToolbox/HIToolbox.h
|
||||
hlink.h
|
||||
|
|
|
|||
|
|
@ -97,11 +97,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static bool sVibratorEnabled = false;
|
||||
static uint32_t sMaxVibrateMS = 0;
|
||||
static uint32_t sMaxVibrateListLen = 0;
|
||||
static const char* kVibrationPermissionType = "vibration";
|
||||
|
||||
static void
|
||||
AddPermission(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPermission,
|
||||
uint32_t aExpireType, int64_t aExpireTime)
|
||||
|
|
@ -152,12 +147,7 @@ GetPermission(nsIPrincipal* aPrincipal, const char* aType)
|
|||
void
|
||||
Navigator::Init()
|
||||
{
|
||||
Preferences::AddBoolVarCache(&sVibratorEnabled,
|
||||
"dom.vibrator.enabled", true);
|
||||
Preferences::AddUintVarCache(&sMaxVibrateMS,
|
||||
"dom.vibrator.max_vibrate_ms", 10000);
|
||||
Preferences::AddUintVarCache(&sMaxVibrateListLen,
|
||||
"dom.vibrator.max_vibrate_list_len", 128);
|
||||
// Add any Preferences::Add*VarCache(&sPref, "pref", default) here if needed.
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
//*****************************************************************************
|
||||
|
|
|
|||
|
|
@ -149,9 +149,6 @@ public:
|
|||
// NavigatorBinding::ClearCachedUserAgentValue(this);
|
||||
void ClearUserAgentCache();
|
||||
|
||||
bool Vibrate(uint32_t aDuration);
|
||||
bool Vibrate(const nsTArray<uint32_t>& aDuration);
|
||||
void SetVibrationPermission(bool aPermitted, bool aPersistent);
|
||||
uint32_t MaxTouchPoints();
|
||||
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ run-if = e10s
|
|||
[test_storagePermissionsReject.html]
|
||||
[test_storagePermissionsRejectForeign.html]
|
||||
[test_stylesheetPI.html]
|
||||
[test_vibrator.html]
|
||||
[test_WebKitCSSMatrix.html]
|
||||
[test_windowedhistoryframes.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
|
||||
* https://html.spec.whatwg.org/#navigatorconcurrenthardware
|
||||
*
|
||||
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
|
||||
* Opera Software ASA. You are granted a license to use, reproduce
|
||||
* and create derivative works of this document.
|
||||
* © Copyright 2004-2020 Apple Computer, Inc., Mozilla Foundation,
|
||||
* Opera Software ASA and Moonchild Productions. You are granted a license to use,
|
||||
* reproduce and create derivative works of this document.
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
||||
|
|
@ -124,14 +124,6 @@ interface 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
|
||||
partial interface Navigator {
|
||||
[Pref="dom.w3c_pointer_events.enabled"]
|
||||
|
|
@ -140,17 +132,6 @@ partial interface Navigator {
|
|||
|
||||
// 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 {
|
||||
// Time is in seconds and is read only when idle observers are added
|
||||
// and removed.
|
||||
|
|
|
|||
79
hal/Hal.cpp
79
hal/Hal.cpp
|
|
@ -94,87 +94,8 @@ WindowIsActive(nsPIDOMWindowInner* aWindow)
|
|||
return !document->Hidden();
|
||||
}
|
||||
|
||||
StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
|
||||
|
||||
void InitLastIDToVibrate()
|
||||
{
|
||||
gLastIDToVibrate = new WindowIdentifier::IDArrayType();
|
||||
ClearOnShutdown(&gLastIDToVibrate);
|
||||
}
|
||||
|
||||
} // 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>
|
||||
class ObserversManager
|
||||
{
|
||||
|
|
|
|||
35
hal/Hal.h
35
hal/Hal.h
|
|
@ -50,41 +50,6 @@ typedef Observer<SystemTimezoneChangeInformation> SystemTimezoneChangeObserver;
|
|||
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -29,7 +29,6 @@ if CONFIG['OS_TARGET'] == 'Linux':
|
|||
'fallback/FallbackAlarm.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
'fallback/FallbackSensor.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
'linux/LinuxMemory.cpp',
|
||||
'linux/LinuxPower.cpp',
|
||||
]
|
||||
|
|
@ -39,7 +38,6 @@ elif CONFIG['OS_TARGET'] == 'WINNT':
|
|||
'fallback/FallbackMemory.cpp',
|
||||
'fallback/FallbackPower.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
'windows/WindowsSensor.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
|
|
@ -48,7 +46,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||
'fallback/FallbackMemory.cpp',
|
||||
'fallback/FallbackPower.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
]
|
||||
elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
||||
UNIFIED_SOURCES += [
|
||||
|
|
@ -57,7 +54,6 @@ elif CONFIG['OS_TARGET'] in ('OpenBSD', 'NetBSD', 'FreeBSD', 'DragonFly'):
|
|||
'fallback/FallbackPower.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
'fallback/FallbackSensor.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
|
|
@ -66,7 +62,6 @@ else:
|
|||
'fallback/FallbackPower.cpp',
|
||||
'fallback/FallbackScreenConfiguration.cpp',
|
||||
'fallback/FallbackSensor.cpp',
|
||||
'fallback/FallbackVibration.cpp',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@ child:
|
|||
async NotifySystemTimezoneChange(SystemTimezoneChangeInformation aSystemTimezoneChangeInfo);
|
||||
|
||||
parent:
|
||||
async Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser);
|
||||
async CancelVibrate(uint64_t[] id, PBrowser browser);
|
||||
|
||||
async EnableNetworkNotifications();
|
||||
async DisableNetworkNotifications();
|
||||
sync GetCurrentNetworkInformation()
|
||||
|
|
|
|||
|
|
@ -45,28 +45,6 @@ Hal()
|
|||
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
|
||||
EnableNetworkNotifications()
|
||||
{
|
||||
|
|
@ -379,36 +357,6 @@ public:
|
|||
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
|
||||
RecvEnableNetworkNotifications() override {
|
||||
// We give all content access to this network-status information.
|
||||
|
|
|
|||
|
|
@ -11,4 +11,4 @@ The in-tree copy is updated by running
|
|||
sh update.sh
|
||||
from within the modules/brotli directory.
|
||||
|
||||
Current version: [commit e61745a6b7add50d380cfd7d3883dd6c62fc2c71].
|
||||
Current version: 1.0.9 Re-release [commit e61745a6b7add50d380cfd7d3883dd6c62fc2c71].
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Script to update the mozilla in-tree copy of the Brotli decompressor.
|
||||
# Script to update the mozilla in-tree copy of the Brotli library.
|
||||
# Run this within the /modules/brotli directory of the source tree.
|
||||
|
||||
MY_TEMP_DIR=`mktemp -d -t brotli_update.XXXXXX` || exit 1
|
||||
GIT=git
|
||||
|
||||
$GIT clone git://github.com/google/brotli.git ${MY_TEMP_DIR}/brotli
|
||||
$GIT -C ${MY_TEMP_DIR}/brotli checkout v1.0.9
|
||||
git clone https://github.com/google/brotli ${MY_TEMP_DIR}/brotli
|
||||
git -C ${MY_TEMP_DIR}/brotli checkout v1.0.9
|
||||
|
||||
COMMIT=$(${GIT} -C ${MY_TEMP_DIR}/brotli rev-parse HEAD)
|
||||
COMMIT=$(git -C ${MY_TEMP_DIR}/brotli rev-parse HEAD)
|
||||
perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[commit ${COMMIT}]/" README.mozilla;
|
||||
|
||||
DIRS="common dec enc include tools"
|
||||
|
|
@ -20,9 +19,7 @@ for d in $DIRS; do
|
|||
done
|
||||
rm -rf ${MY_TEMP_DIR}
|
||||
|
||||
#hg addremove $DIRS
|
||||
|
||||
echo "###"
|
||||
echo "### Updated brotli/dec to $COMMIT."
|
||||
echo "### Updated brotli to $COMMIT."
|
||||
echo "### Remember to verify and commit the changes to source control!"
|
||||
echo "###"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "nsJARInputStream.h"
|
||||
#include "zipstruct.h" // defines ZIP compression codes
|
||||
#include "brotli/decode.h"
|
||||
#include "nsZipArchive.h"
|
||||
|
||||
#include "nsEscape.h"
|
||||
|
|
@ -51,6 +52,13 @@ nsJARInputStream::InitFile(nsJAR *aJar, nsZipItem *item)
|
|||
mOutCrc = crc32(0L, Z_NULL, 0);
|
||||
break;
|
||||
|
||||
case MOZ_JAR_BROTLI:
|
||||
mBrotliState = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
|
||||
mMode = MODE_BROTLI;
|
||||
mInCrc = item->CRC32();
|
||||
mOutCrc = crc32(0L, Z_NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
@ -166,6 +174,7 @@ nsJARInputStream::Available(uint64_t *_retval)
|
|||
break;
|
||||
|
||||
case MODE_INFLATE:
|
||||
case MODE_BROTLI:
|
||||
case MODE_COPY:
|
||||
*_retval = mOutSize - mZs.total_out;
|
||||
break;
|
||||
|
|
@ -195,7 +204,8 @@ MOZ_WIN_MEM_TRY_BEGIN
|
|||
return ReadDirectory(aBuffer, aCount, aBytesRead);
|
||||
|
||||
case MODE_INFLATE:
|
||||
if (mFd) {
|
||||
case MODE_BROTLI:
|
||||
if (mZs.total_out < mOutSize) {
|
||||
rv = ContinueInflate(aBuffer, aCount, aBytesRead);
|
||||
}
|
||||
// be aggressive about releasing the file!
|
||||
|
|
@ -246,6 +256,9 @@ nsJARInputStream::Close()
|
|||
if (mMode == MODE_INFLATE) {
|
||||
inflateEnd(&mZs);
|
||||
}
|
||||
if (mMode == MODE_BROTLI) {
|
||||
BrotliDecoderDestroyInstance(mBrotliState);
|
||||
}
|
||||
mMode = MODE_CLOSED;
|
||||
mFd = nullptr;
|
||||
return NS_OK;
|
||||
|
|
@ -255,6 +268,8 @@ nsresult
|
|||
nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
|
||||
uint32_t* aBytesRead)
|
||||
{
|
||||
bool finished = false;
|
||||
|
||||
// No need to check the args, ::Read did that, but assert them at least
|
||||
NS_ASSERTION(aBuffer,"aBuffer parameter must not be null");
|
||||
NS_ASSERTION(aBytesRead,"aBytesRead parameter must not be null");
|
||||
|
|
@ -266,11 +281,35 @@ nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
|
|||
mZs.avail_out = std::min(aCount, (mOutSize-oldTotalOut));
|
||||
mZs.next_out = (unsigned char*)aBuffer;
|
||||
|
||||
// now inflate
|
||||
int zerr = inflate(&mZs, Z_SYNC_FLUSH);
|
||||
if ((zerr != Z_OK) && (zerr != Z_STREAM_END)) {
|
||||
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: error while inflating";
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
if (mMode == MODE_INFLATE) {
|
||||
// now inflate
|
||||
int zerr = inflate(&mZs, Z_SYNC_FLUSH);
|
||||
if ((zerr != Z_OK) && (zerr != Z_STREAM_END)) {
|
||||
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: error while inflating";
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
}
|
||||
finished = (zerr == Z_STREAM_END);
|
||||
} else {
|
||||
MOZ_ASSERT(mMode == MODE_BROTLI);
|
||||
/* The brotli library wants size_t, but z_stream only contains
|
||||
* unsigned int for avail_* and unsigned long for total_*.
|
||||
* So use temporary stack values. */
|
||||
size_t avail_in = mZs.avail_in;
|
||||
size_t avail_out = mZs.avail_out;
|
||||
size_t total_out = mZs.total_out;
|
||||
BrotliDecoderResult result = BrotliDecoderDecompressStream(
|
||||
mBrotliState,
|
||||
&avail_in, const_cast<const unsigned char**>(&mZs.next_in),
|
||||
&avail_out, &mZs.next_out, &total_out);
|
||||
/* We don't need to update avail_out, it's not used outside this
|
||||
* function. */
|
||||
mZs.total_out = total_out;
|
||||
mZs.avail_in = avail_in;
|
||||
if (result == BROTLI_DECODER_RESULT_ERROR) {
|
||||
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: brotli decompression error";
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
}
|
||||
finished = (result == BROTLI_DECODER_RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
*aBytesRead = (mZs.total_out - oldTotalOut);
|
||||
|
|
@ -280,8 +319,10 @@ nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
|
|||
|
||||
// be aggressive about ending the inflation
|
||||
// for some reason we don't always get Z_STREAM_END
|
||||
if (zerr == Z_STREAM_END || mZs.total_out == mOutSize) {
|
||||
inflateEnd(&mZs);
|
||||
if (finished || mZs.total_out == mOutSize) {
|
||||
if (mMode == MODE_INFLATE) {
|
||||
inflateEnd(&mZs);
|
||||
}
|
||||
|
||||
// stop returning valid data as soon as we know we have a bad CRC
|
||||
if (mOutCrc != mInCrc) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include "nsTArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
struct BrotliDecoderStateStruct;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Class nsJARInputStream declaration. This class defines the type of the
|
||||
* object returned by calls to nsJAR::GetInputStream(filename) for the
|
||||
|
|
@ -20,9 +22,15 @@
|
|||
class nsJARInputStream final : public nsIInputStream
|
||||
{
|
||||
public:
|
||||
nsJARInputStream() :
|
||||
mOutSize(0), mInCrc(0), mOutCrc(0), mNameLen(0),
|
||||
mCurPos(0), mArrPos(0), mMode(MODE_NOTINITED)
|
||||
nsJARInputStream()
|
||||
: mOutSize(0)
|
||||
, mInCrc(0)
|
||||
, mOutCrc(0)
|
||||
, mBrotliState(nullptr)
|
||||
, mNameLen(0)
|
||||
, mCurPos(0)
|
||||
, mArrPos(0)
|
||||
, mMode(MODE_NOTINITED)
|
||||
{
|
||||
memset(&mZs, 0, sizeof(z_stream));
|
||||
}
|
||||
|
|
@ -45,6 +53,7 @@ class nsJARInputStream final : public nsIInputStream
|
|||
uint32_t mInCrc; // CRC as provided by the zipentry
|
||||
uint32_t mOutCrc; // CRC as calculated by me
|
||||
z_stream mZs; // zip data structure
|
||||
BrotliDecoderStateStruct* mBrotliState; // Brotli decoder state
|
||||
|
||||
/* For directory reading */
|
||||
RefPtr<nsJAR> mJar; // string reference to zipreader
|
||||
|
|
@ -59,6 +68,7 @@ class nsJARInputStream final : public nsIInputStream
|
|||
MODE_CLOSED,
|
||||
MODE_DIRECTORY,
|
||||
MODE_INFLATE,
|
||||
MODE_BROTLI,
|
||||
MODE_COPY
|
||||
} JISMode;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* This module implements a simple archive extractor for the PKZIP format.
|
||||
* This module implements a simple archive extractor.
|
||||
*
|
||||
* The underlying nsZipArchive is NOT thread-safe. Do not pass references
|
||||
* or pointers to it across thread boundaries.
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#define READTYPE int32_t
|
||||
#include "zlib.h"
|
||||
#include "brotli/decode.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
|
|
@ -1186,6 +1187,7 @@ nsZipCursor::nsZipCursor(nsZipItem *item, nsZipArchive *aZip, uint8_t* aBuf,
|
|||
: mItem(item)
|
||||
, mBuf(aBuf)
|
||||
, mBufSize(aBufSize)
|
||||
, mBrotliState(nullptr)
|
||||
, mCRC(0)
|
||||
, mDoCRC(doCRC)
|
||||
{
|
||||
|
|
@ -1200,6 +1202,10 @@ nsZipCursor::nsZipCursor(nsZipItem *item, nsZipArchive *aZip, uint8_t* aBuf,
|
|||
|
||||
mZs.avail_in = item->Size();
|
||||
mZs.next_in = (Bytef*)aZip->GetData(item);
|
||||
|
||||
if (mItem->Compression() == MOZ_JAR_BROTLI) {
|
||||
mBrotliState = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (doCRC)
|
||||
mCRC = crc32(0L, Z_NULL, 0);
|
||||
|
|
@ -1210,6 +1216,9 @@ nsZipCursor::~nsZipCursor()
|
|||
if (mItem->Compression() == DEFLATED) {
|
||||
inflateEnd(&mZs);
|
||||
}
|
||||
if (mItem->Compression() == MOZ_JAR_BROTLI) {
|
||||
BrotliDecoderDestroyInstance(mBrotliState);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* nsZipCursor::ReadOrCopy(uint32_t *aBytesRead, bool aCopy) {
|
||||
|
|
@ -1246,6 +1255,29 @@ MOZ_WIN_MEM_TRY_BEGIN
|
|||
*aBytesRead = mZs.next_out - buf;
|
||||
verifyCRC = (zerr == Z_STREAM_END);
|
||||
break;
|
||||
case MOZ_JAR_BROTLI: {
|
||||
buf = mBuf;
|
||||
mZs.next_out = buf;
|
||||
/* The brotli library wants size_t, but z_stream only contains
|
||||
* unsigned int for avail_*. So use temporary stack values. */
|
||||
size_t avail_out = mBufSize;
|
||||
size_t avail_in = mZs.avail_in;
|
||||
BrotliDecoderResult result = BrotliDecoderDecompressStream(
|
||||
mBrotliState,
|
||||
&avail_in, const_cast<const unsigned char**>(&mZs.next_in),
|
||||
&avail_out, &mZs.next_out, nullptr);
|
||||
/* We don't need to update avail_out, it's not used outside this
|
||||
* function. */
|
||||
mZs.avail_in = avail_in;
|
||||
|
||||
if (result == BROTLI_DECODER_RESULT_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*aBytesRead = mZs.next_out - buf;
|
||||
verifyCRC = (result == BROTLI_DECODER_RESULT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -1272,7 +1304,9 @@ nsZipItemPtr_base::nsZipItemPtr_base(nsZipArchive *aZip,
|
|||
return;
|
||||
|
||||
uint32_t size = 0;
|
||||
if (item->Compression() == DEFLATED) {
|
||||
bool compressed = (item->Compression() == DEFLATED) ||
|
||||
(item->Compression() == MOZ_JAR_BROTLI);
|
||||
if (compressed) {
|
||||
size = item->RealSize();
|
||||
mAutoBuf = MakeUniqueFallible<uint8_t[]>(size);
|
||||
if (!mAutoBuf) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
class nsZipFind;
|
||||
struct PRFileDesc;
|
||||
struct BrotliDecoderStateStruct;
|
||||
|
||||
/**
|
||||
* This file defines some of the basic structures used by libjar to
|
||||
|
|
@ -314,6 +315,7 @@ private:
|
|||
uint8_t *mBuf;
|
||||
uint32_t mBufSize;
|
||||
z_stream mZs;
|
||||
BrotliDecoderStateStruct* mBrotliState;
|
||||
uint32_t mCRC;
|
||||
bool mDoCRC;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ typedef struct ZipEnd_
|
|||
#define TOKENIZED 7
|
||||
#define DEFLATED 8
|
||||
#define UNSUPPORTED 0xFF
|
||||
|
||||
/* non-standard extension */
|
||||
#define MOZ_JAR_BROTLI 0x81
|
||||
|
||||
#endif /* _zipstruct_h */
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pref("keyword.enabled", false);
|
|||
pref("general.useragent.locale", "chrome://global/locale/intl.properties");
|
||||
pref("general.useragent.compatMode.gecko", false);
|
||||
pref("general.useragent.compatMode.firefox", false);
|
||||
pref("general.useragent.compatMode.version", "68.9");
|
||||
pref("general.useragent.compatMode.version", "68.0");
|
||||
pref("general.useragent.appVersionIsBuildID", false);
|
||||
|
||||
// This pref exists only for testing purposes. In order to disable all
|
||||
|
|
@ -4746,10 +4746,6 @@ pref("dom.event.handling-user-input-time-limit", 1000);
|
|||
// Whether we should layerize all animated images (if otherwise possible).
|
||||
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
|
||||
pref("dom.abortController.enabled", true);
|
||||
|
||||
|
|
@ -5421,8 +5417,8 @@ pref("osfile.reset_worker_delay", 30000);
|
|||
#endif
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
pref("dom.webkitBlink.dirPicker.enabled", true);
|
||||
pref("dom.webkitBlink.filesystem.enabled", true);
|
||||
pref("dom.webkitBlink.dirPicker.enabled", false);
|
||||
pref("dom.webkitBlink.filesystem.enabled", false);
|
||||
#endif
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ class Jarrer(FileRegistry, BaseFile):
|
|||
dest = Dest(dest)
|
||||
assert isinstance(dest, Dest)
|
||||
|
||||
from mozpack.mozjar import JarWriter, JarReader
|
||||
from mozpack.mozjar import JarWriter, JarReader, JAR_BROTLI
|
||||
try:
|
||||
old_jar = JarReader(fileobj=dest)
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from __future__ import absolute_import
|
|||
|
||||
from io import BytesIO
|
||||
import struct
|
||||
import subprocess
|
||||
import zlib
|
||||
import os
|
||||
from zipfile import (
|
||||
|
|
@ -15,9 +16,11 @@ from zipfile import (
|
|||
from collections import OrderedDict
|
||||
from urlparse import urlparse, ParseResult
|
||||
import mozpack.path as mozpath
|
||||
from mozbuild.util import memoize
|
||||
|
||||
JAR_STORED = ZIP_STORED
|
||||
JAR_DEFLATED = ZIP_DEFLATED
|
||||
JAR_BROTLI = 0x81
|
||||
MAX_WBITS = 15
|
||||
|
||||
|
||||
|
|
@ -262,13 +265,14 @@ class JarFileReader(object):
|
|||
corresponding to the file in the jar archive, data a buffer containing
|
||||
the file data.
|
||||
'''
|
||||
assert header['compression'] in [JAR_DEFLATED, JAR_STORED]
|
||||
assert header['compression'] in [JAR_DEFLATED, JAR_STORED, JAR_BROTLI]
|
||||
self._data = data
|
||||
# Copy some local file header fields.
|
||||
for name in ['filename', 'compressed_size',
|
||||
'uncompressed_size', 'crc32']:
|
||||
setattr(self, name, header[name])
|
||||
self.compressed = header['compression'] == JAR_DEFLATED
|
||||
self.compressed = header['compression'] != JAR_STORED
|
||||
self.compress = header['compression']
|
||||
|
||||
def read(self, length=-1):
|
||||
'''
|
||||
|
|
@ -317,7 +321,11 @@ class JarFileReader(object):
|
|||
if hasattr(self, '_uncompressed_data'):
|
||||
return self._uncompressed_data
|
||||
data = self.compressed_data
|
||||
if self.compressed:
|
||||
if self.compress == JAR_STORED:
|
||||
data = data.tobytes()
|
||||
elif self.compress == JAR_BROTLI:
|
||||
data = Brotli.decompress(data.tobytes())
|
||||
elif self.compress == JAR_DEFLATED:
|
||||
data = zlib.decompress(data.tobytes(), -MAX_WBITS)
|
||||
else:
|
||||
data = data.tobytes()
|
||||
|
|
@ -360,6 +368,13 @@ class JarReader(object):
|
|||
'''
|
||||
del self._data
|
||||
|
||||
@property
|
||||
def compression(self):
|
||||
entries = self.entries
|
||||
if not entries:
|
||||
return JAR_STORED
|
||||
return max(f['compression'] for f in entries.itervalues())
|
||||
|
||||
@property
|
||||
def entries(self):
|
||||
'''
|
||||
|
|
@ -473,6 +488,8 @@ class JarWriter(object):
|
|||
self._data = fileobj
|
||||
else:
|
||||
self._data = open(file, 'wb')
|
||||
if compress is True:
|
||||
compress = JAR_DEFLATED
|
||||
self._compress = compress
|
||||
self._compress_level = compress_level
|
||||
self._contents = OrderedDict()
|
||||
|
|
@ -574,12 +591,13 @@ class JarWriter(object):
|
|||
'''
|
||||
Add a new member to the jar archive, with the given name and the given
|
||||
data.
|
||||
The compress option indicates if the given data should be compressed
|
||||
(True), not compressed (False), or compressed according to the default
|
||||
defined when creating the JarWriter (None).
|
||||
When the data should be compressed (True or None with self.compress ==
|
||||
True), it is only really compressed if the compressed size is smaller
|
||||
than the uncompressed size.
|
||||
The compress option indicates how the given data should be compressed
|
||||
(one of JAR_STORED, JAR_DEFLATE or JAR_BROTLI), or compressed according
|
||||
to the default defined when creating the JarWriter (None). True and
|
||||
False are allowed values for backwards compatibility, mapping,
|
||||
respectively, to JAR_DEFLATE and JAR_STORED.
|
||||
When the data should be compressed, it is only really compressed if
|
||||
the compressed size is smaller than the uncompressed size.
|
||||
The mode option gives the unix permissions that should be stored
|
||||
for the jar entry.
|
||||
If a duplicated member is found skip_duplicates will prevent raising
|
||||
|
|
@ -594,8 +612,12 @@ class JarWriter(object):
|
|||
raise JarWriterError("File %s already in JarWriter" % name)
|
||||
if compress is None:
|
||||
compress = self._compress
|
||||
if (isinstance(data, JarFileReader) and data.compressed == compress) \
|
||||
or (isinstance(data, Deflater) and data.compress == compress):
|
||||
if compress is True:
|
||||
compress = JAR_DEFLATED
|
||||
if compress is False:
|
||||
compress = JAR_STORED
|
||||
if (isinstance(data, (JarFileReader, Deflater)) and \
|
||||
data.compress == compress):
|
||||
deflater = data
|
||||
else:
|
||||
deflater = Deflater(compress, compress_level=self._compress_level)
|
||||
|
|
@ -619,7 +641,7 @@ class JarWriter(object):
|
|||
if deflater.compressed:
|
||||
entry['min_version'] = 20 # Version 2.0 supports deflated streams
|
||||
entry['general_flag'] = 2 # Max compression
|
||||
entry['compression'] = JAR_DEFLATED
|
||||
entry['compression'] = deflater.compress
|
||||
else:
|
||||
entry['min_version'] = 10 # Version 1.0 for stored streams
|
||||
entry['general_flag'] = 0
|
||||
|
|
@ -659,14 +681,21 @@ class Deflater(object):
|
|||
'''
|
||||
def __init__(self, compress=True, compress_level=9):
|
||||
'''
|
||||
Initialize a Deflater. The compress argument determines whether to
|
||||
try to compress at all.
|
||||
Initialize a Deflater. The compress argument determines how to
|
||||
compress.
|
||||
'''
|
||||
self._data = BytesIO()
|
||||
if compress is True:
|
||||
compress = JAR_DEFLATED
|
||||
elif compress is False:
|
||||
compress = JAR_STORED
|
||||
self.compress = compress
|
||||
if compress:
|
||||
self._deflater = zlib.compressobj(compress_level, zlib.DEFLATED,
|
||||
-MAX_WBITS)
|
||||
if compress in (JAR_DEFLATED, JAR_BROTLI):
|
||||
if compress == JAR_DEFLATED:
|
||||
self._deflater = zlib.compressobj(
|
||||
compress_level, zlib.DEFLATED, -MAX_WBITS)
|
||||
else:
|
||||
self._deflater = BrotliCompress()
|
||||
self._deflated = BytesIO()
|
||||
else:
|
||||
self._deflater = None
|
||||
|
|
@ -759,6 +788,46 @@ class Deflater(object):
|
|||
return self._data.getvalue()
|
||||
|
||||
|
||||
class Brotli(object):
|
||||
@staticmethod
|
||||
@memoize
|
||||
def brotli_tool():
|
||||
from buildconfig import topobjdir, substs
|
||||
return os.path.join(topobjdir, 'dist', 'host', 'bin',
|
||||
'brotli' + substs.get('BIN_SUFFIX', ''))
|
||||
|
||||
@staticmethod
|
||||
def run_brotli_tool(args, input):
|
||||
proc = subprocess.Popen([Brotli.brotli_tool()] + args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
(stdout, _) = proc.communicate(input)
|
||||
ret = proc.wait()
|
||||
if ret != 0:
|
||||
raise Exception("Brotli compression failed")
|
||||
return stdout
|
||||
|
||||
@staticmethod
|
||||
def compress(data):
|
||||
return Brotli.run_brotli_tool(['--lgwin=17'], data)
|
||||
|
||||
@staticmethod
|
||||
def decompress(data):
|
||||
return Brotli.run_brotli_tool(['--decompress'], data)
|
||||
|
||||
|
||||
class BrotliCompress(object):
|
||||
def __init__(self):
|
||||
self._buf = BytesIO()
|
||||
|
||||
def compress(self, data):
|
||||
self._buf.write(data)
|
||||
return b''
|
||||
|
||||
def flush(self):
|
||||
return Brotli.compress(self._buf.getvalue())
|
||||
|
||||
|
||||
class JarLog(dict):
|
||||
'''
|
||||
Helper to read the file Gecko generates when setting MOZ_JAR_LOG_FILE.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ from mozpack.chrome.manifest import (
|
|||
Manifest,
|
||||
)
|
||||
from mozpack.errors import errors
|
||||
from mozpack.mozjar import JAR_DEFLATED
|
||||
from mozpack.packager.unpack import UnpackFinder
|
||||
from createprecomplete import generate_precomplete
|
||||
|
||||
|
|
@ -241,16 +242,17 @@ def repack(source, l10n, extra_l10n={}, non_resources=[], non_chrome=set()):
|
|||
finders[base] = UnpackFinder(path)
|
||||
l10n_finder = ComposedFinder(finders)
|
||||
copier = FileCopier()
|
||||
compress = min(app_finder.compressed, JAR_DEFLATED)
|
||||
if app_finder.kind == 'flat':
|
||||
formatter = FlatFormatter(copier)
|
||||
elif app_finder.kind == 'jar':
|
||||
formatter = JarFormatter(copier,
|
||||
optimize=app_finder.optimizedjars,
|
||||
compress=app_finder.compressed)
|
||||
compress=compress)
|
||||
elif app_finder.kind == 'omni':
|
||||
formatter = OmniJarFormatter(copier, app_finder.omnijar,
|
||||
optimize=app_finder.optimizedjars,
|
||||
compress=app_finder.compressed,
|
||||
compress=compress,
|
||||
non_resources=non_resources)
|
||||
|
||||
with errors.accumulate():
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class UnpackFinder(BaseFinder):
|
|||
self.omnijar = None
|
||||
self.jarlogs = {}
|
||||
self.optimizedjars = False
|
||||
self.compressed = True
|
||||
self.compressed = False
|
||||
|
||||
jars = set()
|
||||
|
||||
|
|
@ -146,8 +146,7 @@ class UnpackFinder(BaseFinder):
|
|||
jar = JarReader(fileobj=file.open())
|
||||
if jar.is_optimized:
|
||||
self.optimizedjars = True
|
||||
if not any(f.compressed for f in jar):
|
||||
self.compressed = False
|
||||
self.compressed = max(self.compressed, jar.compression)
|
||||
if jar.last_preloaded:
|
||||
jarlog = jar.entries.keys()
|
||||
self.jarlogs[path] = jarlog[:jarlog.index(jar.last_preloaded) + 1]
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -50,7 +50,7 @@ stage-package: $(MOZ_PKG_MANIFEST) $(MOZ_PKG_MANIFEST_DEPS)
|
|||
) \
|
||||
$(if $(JARLOG_DIR),$(addprefix --jarlog ,$(wildcard $(JARLOG_FILE_AB_CD)))) \
|
||||
$(if $(OPTIMIZEJARS),--optimizejars) \
|
||||
$(if $(DISABLE_JAR_COMPRESSION),--disable-compression) \
|
||||
$(addprefix --compress ,$(JAR_COMPRESSION)) \
|
||||
$(addprefix --unify ,$(UNIFY_DIST)) \
|
||||
$(MOZ_PKG_MANIFEST) '$(DIST)' '$(DIST)'/$(STAGEPATH)$(MOZ_PKG_DIR)$(if $(MOZ_PKG_MANIFEST),,$(_BINPATH)) \
|
||||
$(if $(filter omni,$(MOZ_PACKAGER_FORMAT)),$(if $(NON_OMNIJAR_FILES),--non-resource $(NON_OMNIJAR_FILES)))
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from mozpack.copier import (
|
|||
Jarrer,
|
||||
)
|
||||
from mozpack.errors import errors
|
||||
from mozpack.mozjar import JAR_BROTLI
|
||||
from mozpack.unify import UnifiedBuildFinder
|
||||
import mozpack.path as mozpath
|
||||
import buildconfig
|
||||
|
|
@ -270,9 +271,9 @@ def main():
|
|||
help='Enable jar optimizations')
|
||||
parser.add_argument('--unify', default='',
|
||||
help='Base directory of another build to unify with')
|
||||
parser.add_argument('--disable-compression', action='store_false',
|
||||
dest='compress', default=True,
|
||||
help='Disable jar compression')
|
||||
parser.add_argument('--compress', choices=('none', 'deflate', 'brotli'),
|
||||
default='deflate',
|
||||
help='Use given jar compression (default: deflate)')
|
||||
parser.add_argument('manifest', default=None, nargs='?',
|
||||
help='Manifest file name')
|
||||
parser.add_argument('source', help='Source directory')
|
||||
|
|
@ -290,15 +291,21 @@ def main():
|
|||
for name, value in [split_define(d) for d in args.defines]:
|
||||
defines[name] = value
|
||||
|
||||
compress = {
|
||||
'none': False,
|
||||
'deflate': True,
|
||||
'brotli': JAR_BROTLI,
|
||||
}[args.compress]
|
||||
|
||||
copier = FileCopier()
|
||||
if args.format == 'flat':
|
||||
formatter = FlatFormatter(copier)
|
||||
elif args.format == 'jar':
|
||||
formatter = JarFormatter(copier, compress=args.compress, optimize=args.optimizejars)
|
||||
formatter = JarFormatter(copier, compress=compress, optimize=args.optimizejars)
|
||||
elif args.format == 'omni':
|
||||
formatter = OmniJarFormatter(copier,
|
||||
buildconfig.substs['OMNIJAR_NAME'],
|
||||
compress=args.compress,
|
||||
compress=compress,
|
||||
optimize=args.optimizejars,
|
||||
non_resources=args.non_resource)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ ifneq (android,$(MOZ_WIDGET_TOOLKIT))
|
|||
OPTIMIZEJARS = 1
|
||||
ifneq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
ifdef NIGHTLY_BUILD
|
||||
DISABLE_JAR_COMPRESSION = 1
|
||||
JAR_COMPRESSION ?= none
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue