Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
roytam1 2020-11-16 21:14:10 +08:00
commit 2ffe6398eb
42 changed files with 222 additions and 1023 deletions

View file

@ -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

View file

@ -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
//*****************************************************************************

View file

@ -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)
{

View file

@ -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]

View file

@ -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>

View file

@ -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.

View file

@ -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
{

View file

@ -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.
*/

View file

@ -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

View file

@ -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 += [

View file

@ -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()

View file

@ -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.

View file

@ -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].

View file

@ -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 "###"

View file

@ -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) {

View file

@ -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;

View file

@ -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) {

View file

@ -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;
};

View file

@ -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 */

View file

@ -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

View file

@ -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:

View file

@ -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.

View 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():

View file

@ -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]

View file

@ -1,3 +0,0 @@
@dontcallmedom
@zqzhang
@xinliux

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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)))

View file

@ -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:

View file

@ -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