Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2014-01-09 13:02:29 +01:00
Родитель 49a6202ae8 0569382ec0
Коммит 2aaf3a1659
89 изменённых файлов: 1300 добавлений и 523 удалений

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIPersistentProperties2.h" #include "nsIPersistentProperties2.h"
#include "nsIScrollableFrame.h" #include "nsIScrollableFrame.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsITextControlElement.h"
#include "nsTextFragment.h" #include "nsTextFragment.h"
#include "mozilla/Selection.h" #include "mozilla/Selection.h"
#include "mozilla/MathAlgorithms.h" #include "mozilla/MathAlgorithms.h"
@ -102,8 +103,19 @@ HyperTextAccessible::NativeState()
{ {
uint64_t states = AccessibleWrap::NativeState(); uint64_t states = AccessibleWrap::NativeState();
nsCOMPtr<nsIEditor> editor = GetEditor(); nsCOMPtr<nsITextControlElement> textControl = do_QueryInterface(mContent);
if (editor) { bool editable = !!textControl;
Accessible* hyperText = this;
while (!editable && hyperText) {
if (hyperText->IsHyperText())
editable = hyperText->GetNode()->IsEditable();
if (hyperText->IsDoc())
break;
hyperText = hyperText->Parent();
}
if (editable) {
states |= states::EDITABLE; states |= states::EDITABLE;
} else if (mContent->Tag() == nsGkAtoms::article) { } else if (mContent->Tag() == nsGkAtoms::article) {

Просмотреть файл

@ -733,17 +733,29 @@
states: STATE_PROTECTED, states: STATE_PROTECTED,
extraStates: EXT_STATE_EDITABLE, extraStates: EXT_STATE_EDITABLE,
actions: "activate", actions: "activate",
children: [ ] children: [
{
role: ROLE_TEXT_LEAF
}
]
}; };
testElm("input_password", obj); testElm("input_password", obj);
ok(getAccessible("input_password").firstChild.name != "44",
"text leaf for password shouldn't have its real value as its name!");
obj = { obj = {
role: ROLE_PASSWORD_TEXT, role: ROLE_PASSWORD_TEXT,
states: STATE_PROTECTED | STATE_READONLY, states: STATE_PROTECTED | STATE_READONLY,
actions: "activate", actions: "activate",
children: [ ] children: [
{
role: ROLE_TEXT_LEAF
}
]
}; };
testElm("input_password_readonly", obj); testElm("input_password_readonly", obj);
ok(getAccessible("input_password_readonly").firstChild.name != "44",
"text leaf for password shouldn't have its real value as its name!");
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// HTML:input@type="radio" // HTML:input@type="radio"

Просмотреть файл

@ -378,8 +378,7 @@ let AdbController = {
// Check if we have a remote debugging session going on. If so, we won't // Check if we have a remote debugging session going on. If so, we won't
// disable adb even if the screen is locked. // disable adb even if the screen is locked.
let isDebugging = DebuggerServer._connections && let isDebugging = RemoteDebugger.isDebugging;
Object.keys(DebuggerServer._connections).length > 0;
if (this.DEBUG) { if (this.DEBUG) {
this.debug("isDebugging=" + isDebugging); this.debug("isDebugging=" + isDebugging);
} }
@ -460,6 +459,8 @@ SettingsListener.observe("lockscreen.enabled", false,
AdbController.setLockscreenEnabled.bind(AdbController)); AdbController.setLockscreenEnabled.bind(AdbController));
#endif #endif
// Keep the old setting to not break people that won't have updated
// gaia and gecko.
SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) { SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) {
Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value); Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
// This preference is consulted during startup // This preference is consulted during startup
@ -475,6 +476,30 @@ SettingsListener.observe('devtools.debugger.remote-enabled', false, function(val
#endif #endif
}); });
SettingsListener.observe('debugger.remote-mode', false, function(value) {
if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) {
dump('Illegal value for debugger.remote-mode: ' + value + '\n');
return;
}
Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
value == 'adb-devtools');
// This preference is consulted during startup
Services.prefs.savePrefFile(null);
try {
(value == 'adb-devtools') ? RemoteDebugger.start()
: RemoteDebugger.stop();
} catch(e) {
dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
}
#ifdef MOZ_WIDGET_GONK
AdbController.setRemoteDebuggerState(value != 'disabled');
#endif
});
SettingsListener.observe('debug.log-animations.enabled', false, function(value) { SettingsListener.observe('debug.log-animations.enabled', false, function(value) {
Services.prefs.setBoolPref('layers.offmainthreadcomposition.log-animations', value); Services.prefs.setBoolPref('layers.offmainthreadcomposition.log-animations', value);
}); });

Просмотреть файл

@ -1031,6 +1031,7 @@ let IndexedDBPromptHelper = {
let RemoteDebugger = { let RemoteDebugger = {
_promptDone: false, _promptDone: false,
_promptAnswer: false, _promptAnswer: false,
_running: false,
prompt: function debugger_prompt() { prompt: function debugger_prompt() {
this._promptDone = false; this._promptDone = false;
@ -1051,8 +1052,21 @@ let RemoteDebugger = {
this._promptDone = true; this._promptDone = true;
}, },
get isDebugging() {
if (!this._running) {
return false;
}
return DebuggerServer._connections &&
Object.keys(DebuggerServer._connections).length > 0;
},
// Start the debugger server. // Start the debugger server.
start: function debugger_start() { start: function debugger_start() {
if (this._running) {
return;
}
if (!DebuggerServer.initialized) { if (!DebuggerServer.initialized) {
// Ask for remote connections. // Ask for remote connections.
DebuggerServer.init(this.prompt.bind(this)); DebuggerServer.init(this.prompt.bind(this));
@ -1088,13 +1102,20 @@ let RemoteDebugger = {
"/data/local/debugger-socket"; "/data/local/debugger-socket";
try { try {
DebuggerServer.openListener(path); DebuggerServer.openListener(path);
this._running = true;
} catch (e) { } catch (e) {
dump('Unable to start debugger server: ' + e + '\n'); dump('Unable to start debugger server: ' + e + '\n');
} }
}, },
stop: function debugger_stop() { stop: function debugger_stop() {
if (!this._running) {
return;
}
if (!DebuggerServer.initialized) { if (!DebuggerServer.initialized) {
// Can this really happen if we are running?
this._running = false;
return; return;
} }
@ -1103,6 +1124,7 @@ let RemoteDebugger = {
} catch (e) { } catch (e) {
dump('Unable to stop debugger server: ' + e + '\n'); dump('Unable to stop debugger server: ' + e + '\n');
} }
this._running = false;
} }
} }

Просмотреть файл

@ -1,4 +1,4 @@
{ {
"revision": "3b850fa17c888bdd31f1a163fd7b92f6f020449d", "revision": "6e971c6a9f947d301a0401fcbc87141b8eba23b6",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

Просмотреть файл

@ -93,7 +93,7 @@ class MachCommands(MachCommandBase):
valgrind, valgrind,
'--error-exitcode=1', '--error-exitcode=1',
'--smc-check=all-non-file', '--smc-check=all-non-file',
'--vex-iropt-register-updates=allregs-at-each-insn', '--vex-iropt-register-updates=allregs-at-mem-access',
'--gen-suppressions=all', '--gen-suppressions=all',
'--num-callers=20', '--num-callers=20',
'--leak-check=full', '--leak-check=full',

Просмотреть файл

@ -738,7 +738,13 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
if (!mUrlString.IsEmpty() && mIsAnchor) { if (!mUrlString.IsEmpty() && mIsAnchor) {
nsAutoString dragData(mUrlString); nsAutoString dragData(mUrlString);
dragData.AppendLiteral("\n"); dragData.AppendLiteral("\n");
dragData += mTitleString; // Remove leading and trailing newlines in the title and replace them with
// space in remaining positions - they confuse PlacesUtils::unwrapNodes
// that expects url\ntitle formatted data for x-moz-url.
nsAutoString title(mTitleString);
title.Trim("\r\n");
title.ReplaceChar("\r\n", ' ');
dragData += title;
AddString(aDataTransfer, NS_LITERAL_STRING(kURLMime), dragData, principal); AddString(aDataTransfer, NS_LITERAL_STRING(kURLMime), dragData, principal);
AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal); AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal);

Просмотреть файл

@ -34,6 +34,7 @@
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsISelection.h" #include "nsISelection.h"
#include "nsITextControlElement.h"
#include "nsFrameSelection.h" #include "nsFrameSelection.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h" #include "nsPIWindowRoot.h"
@ -2795,6 +2796,16 @@ nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
continue; continue;
} }
// Don't scroll vertically by mouse-wheel on a single-line text control.
if (checkIfScrollableY) {
nsIContent* c = scrollFrame->GetContent();
nsCOMPtr<nsITextControlElement> ctrl =
do_QueryInterface(c->IsInAnonymousSubtree() ? c->GetBindingParent() : c);
if (ctrl && ctrl->IsSingleLineTextControl()) {
continue;
}
}
if (!checkIfScrollableX && !checkIfScrollableY) { if (!checkIfScrollableX && !checkIfScrollableY) {
return frameToScroll; return frameToScroll;
} }

Просмотреть файл

@ -87,6 +87,7 @@ skip-if = true # Disabled due to timeouts.
[test_bug944847.html] [test_bug944847.html]
skip-if = toolkit == "gonk" skip-if = toolkit == "gonk"
[test_bug944011.html] [test_bug944011.html]
[test_bug946632.html]
[test_clickevent_on_input.html] [test_clickevent_on_input.html]
[test_continuous_wheel_events.html] [test_continuous_wheel_events.html]
[test_dblclick_explicit_original_target.html] [test_dblclick_explicit_original_target.html]

Просмотреть файл

@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=946632
-->
<head>
<title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
.scrollable {
overflow: scroll;
height: 200px;
width: 200px;
}
input {
font-size: 72px;
height: 20px;
width: 20px;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946632">Mozilla Bug 946632</a>
<p id="display"></p>
<div id="container" class="scrollable">
<input value="value">
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</div>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests, window);
var input = document.querySelector("input");
var container = document.querySelector("#container");
function prepare(check)
{
container.scrollTop = 0;
container.scrollLeft = 0;
input.scrollTop = 0;
input.scrollLeft = 0;
container.style.display='none';
container.getBoundingClientRect();
container.style.display='';
container.getBoundingClientRect();
scrollHandler = function(event) {
window.removeEventListener("scroll", arguments.callee, true);
event.stopPropagation();
check(event)
setTimeout(nextTest,0);
};
window.addEventListener("scroll", scrollHandler, true);
}
var tests = [
{
check: function(event) {
is(event.target, container, "<input> vertical line scroll targets container");
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
is(input.scrollLeft, 0, "<input> horizontal line scroll input.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
}
},
{
check: function(event) {
is(event.target, input, "<input> horizontal line scroll targets <input>");
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
ok(input.scrollLeft > 0, "<input> horizontal line scroll input.scrollLeft");
is(container.scrollTop, 0, "<input> horizontal line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> horizontal line scroll container.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
}
},
{
check: function(event) {
is(event.target, container, "<input> vertical page scroll targets container");
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
is(input.scrollTop, 0, "<input> vertical page scroll input.scrollTop");
is(input.scrollLeft, 0, "<input> vertical page scroll input.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
}
},
{
check: function(event) {
is(event.target, input, "<input> horizontal page scroll targets <input>");
is(input.scrollTop, 0, "<input> horizontal page scroll input.scrollTop");
ok(input.scrollLeft > 0, "<input> horizontal page scroll input.scrollLeft");
is(container.scrollTop, 0, "<input> horizontal page scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> horizontal page scroll container.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
}
},
];
var i = 0;
function nextTest()
{
if (i == tests.length) {
SimpleTest.finish();
return;
}
var test = tests[i];
++i;
prepare(test.check);
test.test();
}
function runTests()
{
nextTest();
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -152,7 +152,13 @@ static const char* GetOmxLibraryName()
return nullptr; return nullptr;
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK) #if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
if (version == 13 || version == 12 || version == 11) { /*
if (version >= 19) {
*/
if (version >= 16) {
return "libomxpluginkk.so";
}
else if (version == 13 || version == 12 || version == 11) {
return "libomxpluginhc.so"; return "libomxpluginhc.so";
} }
else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) { else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) {
@ -180,7 +186,7 @@ static const char* GetOmxLibraryName()
return nullptr; return nullptr;
} }
// Default libomxplugin for non-gingerbread devices // Ice Cream Sandwich and Jellybean
return "libomxplugin.so"; return "libomxplugin.so";
#elif defined(ANDROID) && defined(MOZ_WIDGET_GONK) #elif defined(ANDROID) && defined(MOZ_WIDGET_GONK)

Просмотреть файл

@ -198,6 +198,7 @@ function createDOMDownloadObject(aWindow, aDownload) {
function DOMDownloadImpl() { function DOMDownloadImpl() {
debug("DOMDownloadImpl constructor "); debug("DOMDownloadImpl constructor ");
this.wrappedJSObject = this; this.wrappedJSObject = this;
this.totalBytes = 0; this.totalBytes = 0;
this.currentBytes = 0; this.currentBytes = 0;
@ -205,8 +206,10 @@ function DOMDownloadImpl() {
this.path = null; this.path = null;
this.state = "stopped"; this.state = "stopped";
this.contentType = null; this.contentType = null;
this.startTime = Date.now();
this.error = null; /* fields that require getters/setters */
this._error = null;
this._startTime = new Date();
/* private fields */ /* private fields */
this.id = null; this.id = null;
@ -244,6 +247,27 @@ DOMDownloadImpl.prototype = {
return this.__DOM_IMPL__.getEventHandler("onstatechange"); return this.__DOM_IMPL__.getEventHandler("onstatechange");
}, },
get error() {
return this._error;
},
set error(aError) {
this._error = aError;
},
get startTime() {
return this._startTime;
},
set startTime(aStartTime) {
if (aStartTime instanceof Date) {
this._startTime = aStartTime;
}
else {
this._startTime = new Date(aStartTime);
}
},
_init: function(aWindow, aDownload) { _init: function(aWindow, aDownload) {
this._window = aWindow; this._window = aWindow;
this.id = aDownload.id; this.id = aDownload.id;

Просмотреть файл

@ -24,6 +24,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=938023
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
var index = -1; var index = -1;
var todayDate = new Date();
var baseServeURL = "http://mochi.test:8888/tests/dom/downloads/tests/";
var baseDownloadPath = "/mnt/sdcard/downloads/";
var lastKnownCurrentBytes = 0;
function next() { function next() {
index += 1; index += 1;
@ -38,16 +42,54 @@ function next() {
} }
} }
function checkConsistentDownloadAttributes(download) {
var href = document.getElementById("download1").getAttribute("href");
var expectedServeURL = baseServeURL + href;
var expectedDownloadPath = baseDownloadPath + "test.bin";
// bug 945323: Download path isn't honoring download attribute
todo(download.path === expectedDownloadPath,
"Download path = " + expectedDownloadPath);
ok(download.startTime >= todayDate,
"Download start time should be greater than or equal to today");
is(download.error, null, "Download does not have an error");
is(download.url, expectedServeURL,
"Download URL = " + expectedServeURL);
ok(download.id !== null, "Download id is defined");
is(download.contentType, "application/octet-stream",
"Download content type is application/octet-stream");
}
function downloadChange(evt) { function downloadChange(evt) {
var download = evt.download; var download = evt.download;
if (download.state == "succeeded") { checkConsistentDownloadAttributes(download);
ok(download.totalBytes == 1024, "Download size is 1024 bytes."); is(download.totalBytes, 1024, "Download total size is 1024 bytes");
ok(download.contentType == "application/octet-stream",
"contentType is application/octet-stream."); if (download.state === "succeeded") {
is(download.currentBytes, 1024, "Download current size is 1024 bytes");
SimpleTest.finish(); SimpleTest.finish();
} else if (download.state === "downloading") {
ok(download.currentBytes > lastKnownCurrentBytes,
"Download current size is larger than last download change event");
lastKnownCurrentBytes = download.currentBytes;
} else {
ok(false, "Unexpected download state = " + download.state);
} }
} }
function downloadStart(evt) {
var download = evt.download;
checkConsistentDownloadAttributes(download);
is(download.currentBytes, 0, "Download current size is zero");
is(download.state, "downloading", "Download state is downloading");
download.onstatechange = downloadChange;
}
var steps = [ var steps = [
// Start by setting the pref to true. // Start by setting the pref to true.
function() { function() {
@ -61,11 +103,7 @@ var steps = [
SpecialPowers.pushPermissions([ SpecialPowers.pushPermissions([
{type: "downloads", allow: true, context: document} {type: "downloads", allow: true, context: document}
], function() { ], function() {
navigator.mozDownloadManager.ondownloadstart = navigator.mozDownloadManager.ondownloadstart = downloadStart;
function(evt) {
ok(true, "Download started");
evt.download.addEventListener("statechange", downloadChange);
}
next(); next();
}); });
}, },
@ -82,3 +120,4 @@ next();
</pre> </pre>
</body> </body>
</html> </html>

Просмотреть файл

@ -131,7 +131,7 @@ IndexedDBParent::CloneProtocol(Channel* aChannel,
bool bool
IndexedDBParent::CheckPermissionInternal(const nsAString& aDatabaseName, IndexedDBParent::CheckPermissionInternal(const nsAString& aDatabaseName,
const nsDependentCString& aPermission) const nsACString& aPermission)
{ {
MOZ_ASSERT(!mASCIIOrigin.IsEmpty()); MOZ_ASSERT(!mASCIIOrigin.IsEmpty());
MOZ_ASSERT(mManagerContent || mManagerTab); MOZ_ASSERT(mManagerContent || mManagerTab);

Просмотреть файл

@ -201,7 +201,7 @@ public:
protected: protected:
bool bool
CheckPermissionInternal(const nsAString& aDatabaseName, CheckPermissionInternal(const nsAString& aDatabaseName,
const nsDependentCString& aPermission); const nsACString& aPermission);
virtual void virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;

Просмотреть файл

@ -611,7 +611,7 @@ TabChild::HandlePossibleViewportChange()
// The page must have been refreshed in some way such as a new document or // The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and // new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take. // we have no idea how long painting will take.
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0); metrics, ScreenPoint(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1); metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same // This is the root layer, so the cumulative resolution is the same
// as the resolution. // as the resolution.

Просмотреть файл

@ -754,6 +754,16 @@ static SourceSet *
class GetUserMediaRunnable : public nsRunnable class GetUserMediaRunnable : public nsRunnable
{ {
public: public:
/**
* GetUserMediaRunnable is meant for dispatch off main thread, where it would
* be illegal to free JS callbacks. Therefore, it uses a rather risky strategy
* of holding "already_AddRefed" references to the JS callbacks that must be
* transfered and released in consequent dispatches arriving on main thread.
*
* A special Arm() method must be called before dispatch to enable this
* behavior, because GetUserMediaRunnables are held in other circumstances.
*/
GetUserMediaRunnable( GetUserMediaRunnable(
const MediaStreamConstraintsInternal& aConstraints, const MediaStreamConstraintsInternal& aConstraints,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess, already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
@ -761,8 +771,10 @@ public:
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener, uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs) MediaEnginePrefs &aPrefs)
: mConstraints(aConstraints) : mConstraints(aConstraints)
, mSuccess(aSuccess) , mSuccess(nullptr)
, mError(aError) , mError(nullptr)
, mSuccessHolder(aSuccess)
, mErrorHolder(aError)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
@ -783,8 +795,10 @@ public:
MediaEnginePrefs &aPrefs, MediaEnginePrefs &aPrefs,
MediaEngine* aBackend) MediaEngine* aBackend)
: mConstraints(aConstraints) : mConstraints(aConstraints)
, mSuccess(aSuccess) , mSuccess(nullptr)
, mError(aError) , mError(nullptr)
, mSuccessHolder(aSuccess)
, mErrorHolder(aError)
, mWindowID(aWindowID) , mWindowID(aWindowID)
, mListener(aListener) , mListener(aListener)
, mPrefs(aPrefs) , mPrefs(aPrefs)
@ -800,10 +814,24 @@ public:
} }
} }
/**
* Once "armed", GetUserMediaRunnable will leak its JS callbacks if destroyed.
* Arm() must be called before the runnable can be dispatched or used, and the
* runnable must be dispatched or used once armed. Callbacks get released on
* the main thread at the runnable's completion.
*/
void
Arm() {
mSuccess = mSuccessHolder.forget();
mError = mErrorHolder.forget();
}
NS_IMETHOD NS_IMETHOD
Run() Run()
{ {
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
// Was a backend provided? // Was a backend provided?
if (!mBackendChosen) { if (!mBackendChosen) {
@ -842,8 +870,11 @@ public:
nsresult nsresult
Denied(const nsAString& aErrorMsg) Denied(const nsAString& aErrorMsg)
{ {
// We add a disabled listener to the StreamListeners array until accepted MOZ_ASSERT(mSuccess.mRawPtr);
// If this was the only active MediaStream, remove the window from the list. MOZ_ASSERT(mError.mRawPtr);
// We add a disabled listener to the StreamListeners array until accepted
// If this was the only active MediaStream, remove the window from the list.
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
// This is safe since we're on main-thread, and the window can only // This is safe since we're on main-thread, and the window can only
// be invalidated from the main-thread (see OnNavigation) // be invalidated from the main-thread (see OnNavigation)
@ -886,6 +917,8 @@ public:
nsresult nsresult
SelectDevice() SelectDevice()
{ {
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
if (mConstraints.mPicture || mConstraints.mVideo) { if (mConstraints.mPicture || mConstraints.mVideo) {
ScopedDeletePtr<SourceSet> sources (GetSources(mBackend, ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices)); mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
@ -924,6 +957,8 @@ public:
void void
ProcessGetUserMedia(MediaEngineSource* aAudioSource, MediaEngineSource* aVideoSource) ProcessGetUserMedia(MediaEngineSource* aAudioSource, MediaEngineSource* aVideoSource)
{ {
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
nsresult rv; nsresult rv;
if (aAudioSource) { if (aAudioSource) {
rv = aAudioSource->Allocate(mPrefs); rv = aAudioSource->Allocate(mPrefs);
@ -962,6 +997,8 @@ public:
void void
ProcessGetUserMediaSnapshot(MediaEngineSource* aSource, int aDuration) ProcessGetUserMediaSnapshot(MediaEngineSource* aSource, int aDuration)
{ {
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
nsresult rv = aSource->Allocate(mPrefs); nsresult rv = aSource->Allocate(mPrefs);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_DispatchToMainThread(new ErrorCallbackRunnable( NS_DispatchToMainThread(new ErrorCallbackRunnable(
@ -988,6 +1025,8 @@ private:
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess; already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError; already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccessHolder;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mErrorHolder;
uint64_t mWindowID; uint64_t mWindowID;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<MediaDevice> mAudioDevice; nsRefPtr<MediaDevice> mAudioDevice;
@ -1296,7 +1335,6 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
// Store the WindowID in a hash table and mark as active. The entry is removed // Store the WindowID in a hash table and mark as active. The entry is removed
// when this window is closed or navigated away from. // when this window is closed or navigated away from.
uint64_t windowID = aWindow->WindowID(); uint64_t windowID = aWindow->WindowID();
nsRefPtr<GetUserMediaRunnable> gUMRunnable;
// This is safe since we're on main-thread, and the windowlist can only // This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation) // be invalidated from the main-thread (see OnNavigation)
StreamListeners* listeners = GetActiveWindows()->Get(windowID); StreamListeners* listeners = GetActiveWindows()->Get(windowID);
@ -1340,17 +1378,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
c.mVideo = false; c.mVideo = false;
} }
/** // Pass callbacks and MediaStreamListener along to GetUserMediaRunnable.
* Pass runnables along to GetUserMediaRunnable so it can add the nsRefPtr<GetUserMediaRunnable> runnable;
* MediaStreamListener to the runnable list.
*/
if (c.mFake) { if (c.mFake) {
// Fake stream from default backend. // Fake stream from default backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(), runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault()); onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
} else { } else {
// Stream from default device from WebRTC backend. // Stream from default device from WebRTC backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(), runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs); onError.forget(), windowID, listener, mPrefs);
} }
@ -1363,13 +1399,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK) #if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
if (c.mPicture) { if (c.mPicture) {
// ShowFilePickerForMimeType() must run on the Main Thread! (on Android) // ShowFilePickerForMimeType() must run on the Main Thread! (on Android)
NS_DispatchToMainThread(gUMRunnable); runnable->Arm();
NS_DispatchToMainThread(runnable);
return NS_OK; return NS_OK;
} }
#endif #endif
// XXX No full support for picture in Desktop yet (needs proper UI) // XXX No full support for picture in Desktop yet (needs proper UI)
if (aPrivileged || c.mFake) { if (aPrivileged || c.mFake) {
mMediaThread->Dispatch(gUMRunnable, NS_DISPATCH_NORMAL); runnable->Arm();
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} else { } else {
// Ask for user permission, and dispatch runnable (or not) when a response // Ask for user permission, and dispatch runnable (or not) when a response
// is received via an observer notification. Each call is paired with its // is received via an observer notification. Each call is paired with its
@ -1388,9 +1426,18 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
id.ToProvidedString(buffer); id.ToProvidedString(buffer);
NS_ConvertUTF8toUTF16 callID(buffer); NS_ConvertUTF8toUTF16 callID(buffer);
// Store the current callback. // Store the current unarmed runnable w/callbacks.
mActiveCallbacks.Put(callID, gUMRunnable); mActiveCallbacks.Put(callID, runnable);
// Add a WindowID cross-reference so OnNavigation can tear things down
nsTArray<nsString>* array;
if (!mCallIds.Get(windowID, &array)) {
array = new nsTArray<nsString>();
array->AppendElement(callID);
mCallIds.Put(windowID, array);
} else {
array->AppendElement(callID);
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
nsRefPtr<GetUserMediaRequest> req = new GetUserMediaRequest(aWindow, nsRefPtr<GetUserMediaRequest> req = new GetUserMediaRequest(aWindow,
callID, c); callID, c);
@ -1471,6 +1518,14 @@ MediaManager::OnNavigation(uint64_t aWindowID)
// Invalidate this window. The runnables check this value before making // Invalidate this window. The runnables check this value before making
// a call to content. // a call to content.
nsTArray<nsString>* callIds;
if (mCallIds.Get(aWindowID, &callIds)) {
for (int i = 0, len = callIds->Length(); i < len; ++i) {
mActiveCallbacks.Remove((*callIds)[i]);
}
mCallIds.Remove(aWindowID);
}
// This is safe since we're on main-thread, and the windowlist can only // This is safe since we're on main-thread, and the windowlist can only
// be added to from the main-thread // be added to from the main-thread
StreamListeners* listeners = GetWindowListeners(aWindowID); StreamListeners* listeners = GetWindowListeners(aWindowID);
@ -1606,6 +1661,7 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
GetActiveWindows()->Clear(); GetActiveWindows()->Clear();
mActiveCallbacks.Clear(); mActiveCallbacks.Clear();
mCallIds.Clear();
LOG(("Releasing MediaManager singleton and thread")); LOG(("Releasing MediaManager singleton and thread"));
sSingleton = nullptr; sSingleton = nullptr;
} }
@ -1614,25 +1670,24 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
} else if (!strcmp(aTopic, "getUserMedia:response:allow")) { } else if (!strcmp(aTopic, "getUserMedia:response:allow")) {
nsString key(aData); nsString key(aData);
nsRefPtr<nsRunnable> runnable; nsRefPtr<GetUserMediaRunnable> runnable;
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
return NS_OK; return NS_OK;
} }
mActiveCallbacks.Remove(key); mActiveCallbacks.Remove(key);
runnable->Arm();
if (aSubject) { if (aSubject) {
// A particular device or devices were chosen by the user. // A particular device or devices were chosen by the user.
// NOTE: does not allow setting a device to null; assumes nullptr // NOTE: does not allow setting a device to null; assumes nullptr
GetUserMediaRunnable* gUMRunnable =
static_cast<GetUserMediaRunnable*>(runnable.get());
nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject)); nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
MOZ_ASSERT(array); MOZ_ASSERT(array);
uint32_t len = 0; uint32_t len = 0;
array->Count(&len); array->Count(&len);
MOZ_ASSERT(len); MOZ_ASSERT(len);
if (!len) { if (!len) {
gUMRunnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED")); // neither audio nor video were selected // neither audio nor video were selected
runnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return NS_OK; return NS_OK;
} }
for (uint32_t i = 0; i < len; i++) { for (uint32_t i = 0; i < len; i++) {
@ -1644,9 +1699,9 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
nsString type; nsString type;
device->GetType(type); device->GetType(type);
if (type.EqualsLiteral("video")) { if (type.EqualsLiteral("video")) {
gUMRunnable->SetVideoDevice(static_cast<MediaDevice*>(device.get())); runnable->SetVideoDevice(static_cast<MediaDevice*>(device.get()));
} else if (type.EqualsLiteral("audio")) { } else if (type.EqualsLiteral("audio")) {
gUMRunnable->SetAudioDevice(static_cast<MediaDevice*>(device.get())); runnable->SetAudioDevice(static_cast<MediaDevice*>(device.get()));
} else { } else {
NS_WARNING("Unknown device type in getUserMedia"); NS_WARNING("Unknown device type in getUserMedia");
} }
@ -1670,15 +1725,13 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
} }
nsString key(aData); nsString key(aData);
nsRefPtr<nsRunnable> runnable; nsRefPtr<GetUserMediaRunnable> runnable;
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) { if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
return NS_OK; return NS_OK;
} }
mActiveCallbacks.Remove(key); mActiveCallbacks.Remove(key);
runnable->Arm();
GetUserMediaRunnable* gUMRunnable = runnable->Denied(errorMessage);
static_cast<GetUserMediaRunnable*>(runnable.get());
gUMRunnable->Denied(errorMessage);
return NS_OK; return NS_OK;
} else if (!strcmp(aTopic, "getUserMedia:revoke")) { } else if (!strcmp(aTopic, "getUserMedia:revoke")) {

Просмотреть файл

@ -241,6 +241,7 @@ typedef enum {
} MediaOperation; } MediaOperation;
class MediaManager; class MediaManager;
class GetUserMediaRunnable;
/** /**
* Send an error back to content. The error is the form a string. * Send an error back to content. The error is the form a string.
@ -524,7 +525,8 @@ private:
// ONLY access from MainThread so we don't need to lock // ONLY access from MainThread so we don't need to lock
WindowTable mActiveWindows; WindowTable mActiveWindows;
nsRefPtrHashtable<nsStringHashKey, nsRunnable> mActiveCallbacks; nsRefPtrHashtable<nsStringHashKey, GetUserMediaRunnable> mActiveCallbacks;
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
// Always exists // Always exists
nsCOMPtr<nsIThread> mMediaThread; nsCOMPtr<nsIThread> mMediaThread;

Просмотреть файл

@ -80,6 +80,7 @@ class nsGeolocationRequest
void SendLocation(nsIDOMGeoPosition* location); void SendLocation(nsIDOMGeoPosition* location);
bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;} bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
void SetTimeoutTimer(); void SetTimeoutTimer();
void StopTimeoutTimer();
void NotifyErrorAndShutdown(uint16_t); void NotifyErrorAndShutdown(uint16_t);
nsIPrincipal* GetPrincipal(); nsIPrincipal* GetPrincipal();
@ -348,6 +349,7 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
NS_IMETHODIMP NS_IMETHODIMP
nsGeolocationRequest::Notify(nsITimer* aTimer) nsGeolocationRequest::Notify(nsITimer* aTimer)
{ {
StopTimeoutTimer();
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT); NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
return NS_OK; return NS_OK;
} }
@ -363,10 +365,6 @@ nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
} }
NotifyError(aErrorCode); NotifyError(aErrorCode);
if (!mShutdown) {
SetTimeoutTimer();
}
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -475,10 +473,7 @@ nsGeolocationRequest::Allow()
void void
nsGeolocationRequest::SetTimeoutTimer() nsGeolocationRequest::SetTimeoutTimer()
{ {
if (mTimeoutTimer) { StopTimeoutTimer();
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
int32_t timeout; int32_t timeout;
if (mOptions && (timeout = mOptions->mTimeout) != 0) { if (mOptions && (timeout = mOptions->mTimeout) != 0) {
@ -494,6 +489,15 @@ nsGeolocationRequest::SetTimeoutTimer()
} }
} }
void
nsGeolocationRequest::StopTimeoutTimer()
{
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
}
void void
nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition) nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
{ {
@ -539,12 +543,9 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
callback->HandleEvent(aPosition); callback->HandleEvent(aPosition);
} }
if (!mShutdown) { StopTimeoutTimer();
// For watch requests, the handler may have called clearWatch MOZ_ASSERT(mShutdown || mIsWatchPositionRequest,
MOZ_ASSERT(mIsWatchPositionRequest, "non-shutdown getCurrentPosition request after callback!");
"non-shutdown getCurrentPosition request after callback!");
SetTimeoutTimer();
}
} }
nsIPrincipal* nsIPrincipal*
@ -564,6 +565,16 @@ nsGeolocationRequest::Update(nsIDOMGeoPosition* aPosition)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsGeolocationRequest::LocationUpdatePending()
{
if (!mTimeoutTimer) {
SetTimeoutTimer();
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsGeolocationRequest::NotifyError(uint16_t aErrorCode) nsGeolocationRequest::NotifyError(uint16_t aErrorCode)
{ {
@ -809,6 +820,16 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsGeolocationService::LocationUpdatePending()
{
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
mGeolocators[i]->LocationUpdatePending();
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsGeolocationService::NotifyError(uint16_t aErrorCode) nsGeolocationService::NotifyError(uint16_t aErrorCode)
{ {
@ -1130,6 +1151,17 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
Geolocation::LocationUpdatePending()
{
// this event is only really interesting for watch callbacks
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
mWatchingCallbacks[i]->LocationUpdatePending();
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
Geolocation::NotifyError(uint16_t aErrorCode) Geolocation::NotifyError(uint16_t aErrorCode)
{ {

Просмотреть файл

@ -143,6 +143,9 @@ WifiGeoPositionProvider.prototype = {
LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE")); LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
this.hasSeenWiFi = true; this.hasSeenWiFi = true;
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
.locationUpdatePending();
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri"); let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
function isPublic(ap) { function isPublic(ap) {

Просмотреть файл

@ -24,16 +24,16 @@ class CoreLocationObjects;
class CoreLocationLocationProvider class CoreLocationLocationProvider
: public nsIGeolocationProvider : public nsIGeolocationProvider
, public nsIGeolocationUpdate
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
NS_DECL_NSIGEOLOCATIONPROVIDER NS_DECL_NSIGEOLOCATIONPROVIDER
CoreLocationLocationProvider(); CoreLocationLocationProvider();
static bool IsCoreLocationAvailable(); static bool IsCoreLocationAvailable();
void NotifyError(uint16_t aErrorCode);
void Update(nsIDOMGeoPosition* aSomewhere);
private: private:
virtual ~CoreLocationLocationProvider() {}; virtual ~CoreLocationLocationProvider() {};

Просмотреть файл

@ -218,19 +218,16 @@ CoreLocationLocationProvider::SetHighAccuracy(bool aEnable)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP void
CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere) CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere)
{ {
if (aSomewhere && mCallback) { if (aSomewhere && mCallback) {
mCallback->Update(aSomewhere); mCallback->Update(aSomewhere);
} }
return NS_OK;
} }
NS_IMETHODIMP void
CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode) CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode)
{ {
mCallback->NotifyError(aErrorCode); mCallback->NotifyError(aErrorCode);
return NS_OK;
} }

Просмотреть файл

@ -59,7 +59,7 @@ interface DOMDownload : EventTarget {
// A DOM error object, that will be not null when a download is stopped // A DOM error object, that will be not null when a download is stopped
// because something failed. // because something failed.
readonly attribute DOMError error; readonly attribute DOMError? error;
// Pauses the download. // Pauses the download.
Promise pause(); Promise pause();

Просмотреть файл

@ -502,6 +502,16 @@ _cairo_win32_surface_finish (void *abstract_surface)
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
static void
get_d3d9_dc_and_clear_clip (cairo_win32_surface_t *surface)
{
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
// The DC that we get back from the surface will not have
// a clip so clear surface->clip_region so that we don't think we have
// one when we don't.
_cairo_win32_surface_set_clip_region (surface, NULL);
}
static cairo_status_t static cairo_status_t
_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface, _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
int x, int x,
@ -521,7 +531,7 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
&rectout, &rectin, 0); &rectout, &rectin, 0);
surface->dc = 0; // Don't use the DC when this is locked! surface->dc = 0; // Don't use the DC when this is locked!
if (hr) { if (hr) {
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); get_d3d9_dc_and_clear_clip (surface);
return CAIRO_INT_STATUS_UNSUPPORTED; return CAIRO_INT_STATUS_UNSUPPORTED;
} }
local = cairo_image_surface_create_for_data (rectout.pBits, local = cairo_image_surface_create_for_data (rectout.pBits,
@ -530,12 +540,12 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
rectout.Pitch); rectout.Pitch);
if (local == NULL) { if (local == NULL) {
IDirect3DSurface9_UnlockRect (surface->d3d9surface); IDirect3DSurface9_UnlockRect (surface->d3d9surface);
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); get_d3d9_dc_and_clear_clip (surface);
return CAIRO_INT_STATUS_UNSUPPORTED; return CAIRO_INT_STATUS_UNSUPPORTED;
} }
if (local->base.status) { if (local->base.status) {
IDirect3DSurface9_UnlockRect (surface->d3d9surface); IDirect3DSurface9_UnlockRect (surface->d3d9surface);
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); get_d3d9_dc_and_clear_clip (surface);
return local->base.status; return local->base.status;
} }
@ -709,7 +719,7 @@ _cairo_win32_surface_release_source_image (void *abstract_surf
if (local && local->d3d9surface) { if (local && local->d3d9surface) {
IDirect3DSurface9_UnlockRect (local->d3d9surface); IDirect3DSurface9_UnlockRect (local->d3d9surface);
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); get_d3d9_dc_and_clear_clip (surface);
cairo_surface_destroy ((cairo_surface_t *)image); cairo_surface_destroy ((cairo_surface_t *)image);
} else { } else {
cairo_surface_destroy ((cairo_surface_t *)local); cairo_surface_destroy ((cairo_surface_t *)local);
@ -784,7 +794,7 @@ _cairo_win32_surface_release_dest_image (void *abstract_surfa
if (local->d3d9surface) { if (local->d3d9surface) {
IDirect3DSurface9_UnlockRect (local->d3d9surface); IDirect3DSurface9_UnlockRect (local->d3d9surface);
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); get_d3d9_dc_and_clear_clip (surface);
cairo_surface_destroy ((cairo_surface_t *)image); cairo_surface_destroy ((cairo_surface_t *)image);
} else { } else {

Просмотреть файл

@ -154,8 +154,6 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
if (aOperator == OP_SOURCE) { if (aOperator == OP_SOURCE) {
aTarget->PopClip(); aTarget->PopClip();
} }
aTarget->Flush();
} }
void void
@ -391,6 +389,17 @@ ComputeBufferRect(const nsIntRect& aRequestedRect)
return rect; return rect;
} }
void
RotatedContentBuffer::FlushBuffers()
{
if (mDTBuffer) {
mDTBuffer->Flush();
}
if (mDTBufferOnWhite) {
mDTBufferOnWhite->Flush();
}
}
RotatedContentBuffer::PaintState RotatedContentBuffer::PaintState
RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
uint32_t aFlags) uint32_t aFlags)

Просмотреть файл

@ -75,6 +75,8 @@ public:
BUFFER_WHITE, // The buffer with white background, only valid with component alpha. BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading. BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
}; };
// It is the callers repsonsibility to ensure aTarget is flushed after calling
// this method.
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource, void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
float aOpacity = 1.0, float aOpacity = 1.0,
gfx::CompositionOp aOperator = gfx::OP_OVER, gfx::CompositionOp aOperator = gfx::OP_OVER,
@ -396,6 +398,10 @@ protected:
*/ */
bool EnsureBuffer(); bool EnsureBuffer();
bool EnsureBufferOnWhite(); bool EnsureBufferOnWhite();
// Flush our buffers if they are mapped.
void FlushBuffers();
/** /**
* True if we have a buffer where we can get it (but not necessarily * True if we have a buffer where we can get it (but not necessarily
* mapped currently). * mapped currently).

Просмотреть файл

@ -598,6 +598,8 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
mFrontBufferRect, mFrontBufferRect,
mFrontBufferRotation); mFrontBufferRotation);
UpdateDestinationFrom(frontBuffer, updateRegion); UpdateDestinationFrom(frontBuffer, updateRegion);
// We need to flush our buffers before we unlock our front textures
FlushBuffers();
mFrontClient->Unlock(); mFrontClient->Unlock();
if (mFrontClientOnWhite) { if (mFrontClientOnWhite) {
mFrontClientOnWhite->Unlock(); mFrontClientOnWhite->Unlock();
@ -816,6 +818,9 @@ DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
mFrontBufferRotation); mFrontBufferRotation);
UpdateDestinationFrom(frontBuffer, updateRegion); UpdateDestinationFrom(frontBuffer, updateRegion);
// We need to flush our buffers before we unlock our front textures
FlushBuffers();
mFrontAndBackBufferDiffer = false; mFrontAndBackBufferDiffer = false;
} }

Просмотреть файл

@ -168,10 +168,10 @@ static int32_t gPanRepaintInterval = 250;
static int32_t gFlingRepaintInterval = 75; static int32_t gFlingRepaintInterval = 75;
/** /**
* Minimum amount of speed along an axis before we begin painting far ahead by * Minimum amount of speed along an axis before we switch to "skate" multipliers
* adjusting the displayport. * rather than using the "stationary" multipliers.
*/ */
static float gMinSkateSpeed = 0.7f; static float gMinSkateSpeed = 1.0f;
/** /**
* Duration of a zoom to animation. * Duration of a zoom to animation.
@ -207,22 +207,26 @@ static int gTouchListenerTimeout = 300;
*/ */
static int gNumPaintDurationSamples = 3; static int gNumPaintDurationSamples = 3;
/** The multiplier we apply to a dimension's length if it is skating. That is, /**
* if it's going above sMinSkateSpeed. We prefer to increase the size of the * The multiplier we apply to the displayport size if it is skating (current
* velocity is above gMinSkateSpeed). We prefer to increase the size of the
* Y axis because it is more natural in the case that a user is reading a page * Y axis because it is more natural in the case that a user is reading a page
* that scrolls up/down. Note that one, both or neither of these may be used * that scrolls up/down. Note that one, both or neither of these may be used
* at any instant. * at any instant.
* In general we want g[XY]SkateSizeMultiplier to be smaller than the corresponding
* stationary size multiplier because when panning fast we would like to paint
* less and get faster, more predictable paint times. When panning slowly we
* can afford to paint more even though it's slower.
*/ */
static float gXSkateSizeMultiplier = 3.0f; static float gXSkateSizeMultiplier = 1.5f;
static float gYSkateSizeMultiplier = 3.5f; static float gYSkateSizeMultiplier = 2.5f;
/** The multiplier we apply to a dimension's length if it is stationary. We /**
* prefer to increase the size of the Y axis because it is more natural in the * The multiplier we apply to the displayport size if it is not skating (see
* case that a user is reading a page that scrolls up/down. Note that one, * documentation for gXSkateSizeMultiplier).
* both or neither of these may be used at any instant.
*/ */
static float gXStationarySizeMultiplier = 1.5f; static float gXStationarySizeMultiplier = 3.0f;
static float gYStationarySizeMultiplier = 2.5f; static float gYStationarySizeMultiplier = 3.5f;
/** /**
* The time period in ms that throttles mozbrowserasyncscroll event. * The time period in ms that throttles mozbrowserasyncscroll event.
@ -931,8 +935,8 @@ float AsyncPanZoomController::PanDistance() {
return NS_hypot(mX.PanDistance(), mY.PanDistance()); return NS_hypot(mX.PanDistance(), mY.PanDistance());
} }
const gfx::Point AsyncPanZoomController::GetVelocityVector() { const ScreenPoint AsyncPanZoomController::GetVelocityVector() {
return gfx::Point(mX.GetVelocity(), mY.GetVelocity()); return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
} }
const gfx::Point AsyncPanZoomController::GetAccelerationVector() { const gfx::Point AsyncPanZoomController::GetAccelerationVector() {
@ -1159,103 +1163,65 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale,
mFrameMetrics.mScrollOffset = (mFrameMetrics.mScrollOffset + aFocus) - (aFocus / aScale); mFrameMetrics.mScrollOffset = (mFrameMetrics.mScrollOffset + aFocus) - (aFocus / aScale);
} }
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier, /**
double aEstimatedPaintDuration, * Attempts to enlarge the displayport along a single axis based on the
float aCompositionBounds, * velocity. aOffset and aLength are in/out parameters; they are initially set
float aVelocity, * to the currently visible area and will be transformed to the area we should
float aAcceleration, * be drawing to minimize checkerboarding.
float* aDisplayPortOffset, */
float* aDisplayPortLength) static void
EnlargeDisplayPortAlongAxis(float* aOutOffset, float* aOutLength,
double aEstimatedPaintDurationMillis, float aVelocity,
float aStationarySizeMultiplier, float aSkateSizeMultiplier)
{ {
if (fabsf(aVelocity) > gMinSkateSpeed) { // Scale up the length using the appropriate multiplier and center the
// Enlarge the area we paint. // displayport around the visible area.
*aDisplayPortLength = aCompositionBounds * aSkateSizeMultiplier; float multiplier = (fabsf(aVelocity) < gMinSkateSpeed
// Position the area we paint such that all of the excess that extends past ? aStationarySizeMultiplier
// the screen is on the side towards the velocity. : aSkateSizeMultiplier);
*aDisplayPortOffset = aVelocity > 0 ? 0 : aCompositionBounds - *aDisplayPortLength; float newLength = (*aOutLength) * multiplier;
*aOutOffset -= (newLength - (*aOutLength)) / 2;
*aOutLength = newLength;
// Only compensate for acceleration when we actually have any. Otherwise // Project the displayport out based on the estimated time it will take to paint
// we'll overcompensate when a user is just panning around without flinging. *aOutOffset += (aVelocity * aEstimatedPaintDurationMillis);
if (aAcceleration > 1.01f) {
// Compensate for acceleration and how long we expect a paint to take. We
// try to predict where the viewport will be when painting has finished.
*aDisplayPortOffset +=
fabsf(aAcceleration) * aVelocity * aCompositionBounds * aEstimatedPaintDuration;
// If our velocity is in the negative direction of the axis, we have to
// compensate for the fact that our scroll offset is the top-left position
// of the viewport. In this case, let's make it relative to the
// bottom-right. That way, we'll always be growing the displayport upwards
// and to the left when skating negatively.
*aDisplayPortOffset -= aVelocity < 0 ? aCompositionBounds : 0;
}
return true;
}
return false;
} }
/* static */
const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort( const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics, const FrameMetrics& aFrameMetrics,
const gfx::Point& aVelocity, const ScreenPoint& aVelocity,
const gfx::Point& aAcceleration, const gfx::Point& aAcceleration,
double aEstimatedPaintDuration) double aEstimatedPaintDuration)
{ {
// If we don't get an estimated paint duration, we probably don't have any // convert to milliseconds
// data. In this case, we're dealing with either a stationary frame or a first double estimatedPaintDurationMillis = aEstimatedPaintDuration * 1000;
// paint. In either of these cases, we can just assume it'll take 1 second to
// paint. Getting this correct is not important anyways since it's only really
// useful when accelerating, which can't be happening at this point.
double estimatedPaintDuration =
aEstimatedPaintDuration > EPSILON ? aEstimatedPaintDuration : 1.0;
CSSIntRect compositionBounds = gfx::RoundedIn(aFrameMetrics.mCompositionBounds / aFrameMetrics.mZoom); CSSRect compositionBounds = aFrameMetrics.CalculateCompositedRectInCssPixels();
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
CSSRect displayPort(scrollOffset, compositionBounds.Size());
CSSPoint velocity = aVelocity / aFrameMetrics.mZoom;
// Enlarge the displayport along both axes depending on how fast we're moving
// on that axis and how long it takes to paint. Apply some heuristics to try
// to minimize checkerboarding.
EnlargeDisplayPortAlongAxis(&(displayPort.x), &(displayPort.width),
estimatedPaintDurationMillis, velocity.x,
gXStationarySizeMultiplier, gXSkateSizeMultiplier);
EnlargeDisplayPortAlongAxis(&(displayPort.y), &(displayPort.height),
estimatedPaintDurationMillis, velocity.y,
gYStationarySizeMultiplier, gYSkateSizeMultiplier);
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect(); CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset; displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
CSSRect displayPort = CSSRect(compositionBounds); APZC_LOG_FM(aFrameMetrics,
displayPort.MoveTo(0, 0); "Calculated displayport as (%f %f %f %f) from velocity (%f %f) acceleration (%f %f) paint time %f metrics",
displayPort.Scale(gXStationarySizeMultiplier, gYStationarySizeMultiplier); displayPort.x, displayPort.y, displayPort.width, displayPort.height,
aVelocity.x, aVelocity.y, aAcceleration.x, aAcceleration.y,
(float)estimatedPaintDurationMillis);
// If there's motion along an axis of movement, and it's above a threshold, return displayPort;
// then we want to paint a larger area in the direction of that motion so that
// it's less likely to checkerboard.
bool enlargedX = EnlargeDisplayPortAlongAxis(
gXSkateSizeMultiplier, estimatedPaintDuration,
compositionBounds.width, aVelocity.x, aAcceleration.x,
&displayPort.x, &displayPort.width);
bool enlargedY = EnlargeDisplayPortAlongAxis(
gYSkateSizeMultiplier, estimatedPaintDuration,
compositionBounds.height, aVelocity.y, aAcceleration.y,
&displayPort.y, &displayPort.height);
if (!enlargedX && !enlargedY) {
// Position the x and y such that the screen falls in the middle of the displayport.
displayPort.x = -(displayPort.width - compositionBounds.width) / 2;
displayPort.y = -(displayPort.height - compositionBounds.height) / 2;
} else if (!enlargedX) {
displayPort.width = compositionBounds.width;
} else if (!enlargedY) {
displayPort.height = compositionBounds.height;
}
// If we go over the bounds when trying to predict where we will be when this
// paint finishes, move it back into the range of the CSS content rect.
// FIXME/bug 780395: Generalize this. This code is pretty hacky as it will
// probably not work at all for RTL content. This is not intended to be
// incredibly accurate; it'll just prevent the entire displayport from being
// outside the content rect (which causes bad things to happen).
if (scrollOffset.x + compositionBounds.width > scrollableRect.width) {
scrollOffset.x -= compositionBounds.width + scrollOffset.x - scrollableRect.width;
} else if (scrollOffset.x < scrollableRect.x) {
scrollOffset.x = scrollableRect.x;
}
if (scrollOffset.y + compositionBounds.height > scrollableRect.height) {
scrollOffset.y -= compositionBounds.height + scrollOffset.y - scrollableRect.height;
} else if (scrollOffset.y < scrollableRect.y) {
scrollOffset.y = scrollableRect.y;
}
return displayPort.ForceInside(scrollableRect - scrollOffset);
} }
void AsyncPanZoomController::ScheduleComposite() { void AsyncPanZoomController::ScheduleComposite() {
@ -1598,7 +1564,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
endZoomToMetrics.mScrollOffset = aRect.TopLeft(); endZoomToMetrics.mScrollOffset = aRect.TopLeft();
endZoomToMetrics.mDisplayPort = endZoomToMetrics.mDisplayPort =
CalculatePendingDisplayPort(endZoomToMetrics, CalculatePendingDisplayPort(endZoomToMetrics,
gfx::Point(0,0), ScreenPoint(0,0),
gfx::Point(0,0), gfx::Point(0,0),
0); 0);

Просмотреть файл

@ -229,7 +229,7 @@ public:
*/ */
static const CSSRect CalculatePendingDisplayPort( static const CSSRect CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics, const FrameMetrics& aFrameMetrics,
const gfx::Point& aVelocity, const ScreenPoint& aVelocity,
const gfx::Point& aAcceleration, const gfx::Point& aAcceleration,
double aEstimatedPaintDuration); double aEstimatedPaintDuration);
@ -408,7 +408,7 @@ protected:
/** /**
* Gets a vector of the velocities of each axis. * Gets a vector of the velocities of each axis.
*/ */
const gfx::Point GetVelocityVector(); const ScreenPoint GetVelocityVector();
/** /**
* Gets a vector of the acceleration factors of each axis. * Gets a vector of the acceleration factors of each axis.
@ -439,22 +439,6 @@ protected:
*/ */
void TrackTouch(const MultiTouchInput& aEvent); void TrackTouch(const MultiTouchInput& aEvent);
/**
* Attempts to enlarge the displayport along a single axis. Returns whether or
* not the displayport was enlarged. This will fail in circumstances where the
* velocity along that axis is not high enough to need any changes. The
* displayport metrics are expected to be passed into |aDisplayPortOffset| and
* |aDisplayPortLength|. If enlarged, these will be updated with the new
* metrics.
*/
static bool EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier,
double aEstimatedPaintDuration,
float aCompositionBounds,
float aVelocity,
float aAcceleration,
float* aDisplayPortOffset,
float* aDisplayPortLength);
/** /**
* Utility function to send updated FrameMetrics to Gecko so that it can paint * Utility function to send updated FrameMetrics to Gecko so that it can paint
* the displayport area. Calls into GeckoContentController to do the actual * the displayport area. Calls into GeckoContentController to do the actual

Просмотреть файл

@ -29,111 +29,98 @@ extern PRLogModuleInfo *GetImgLog();
class LogScope { class LogScope {
public: public:
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn) : LogScope(PRLogModuleInfo *aLog, void *from, const char *fn) :
mLog(aLog), mFrom(from), mFunc(fn) mLog(aLog), mFrom(from), mFunc(fn)
{ {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {ENTER}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {ENTER}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc));
mFrom, mFunc.get()));
} }
/* const char * constructor */ /* const char * constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn, LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, const char *paramValue) : const char *paramName, const char *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn) mLog(aLog), mFrom(from), mFunc(fn)
{ {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc,
mFrom, mFunc.get(), paramName, paramValue));
paramName.get(),
paramValue));
} }
/* void ptr constructor */ /* void ptr constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn, LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, const void *paramValue) : const char *paramName, const void *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn) mLog(aLog), mFrom(from), mFunc(fn)
{ {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=%p) {ENTER}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=%p) {ENTER}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc,
mFrom, mFunc.get(), paramName, paramValue));
paramName.get(),
paramValue));
} }
/* int32_t constructor */ /* int32_t constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn, LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, int32_t paramValue) : const char *paramName, int32_t paramValue) :
mLog(aLog), mFrom(from), mFunc(fn) mLog(aLog), mFrom(from), mFunc(fn)
{ {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc,
mFrom, mFunc.get(), paramName, paramValue));
paramName.get(),
paramValue));
} }
/* uint32_t constructor */ /* uint32_t constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn, LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, uint32_t paramValue) : const char *paramName, uint32_t paramValue) :
mLog(aLog), mFrom(from), mFunc(fn) mLog(aLog), mFrom(from), mFunc(fn)
{ {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc,
mFrom, mFunc.get(), paramName, paramValue));
paramName.get(),
paramValue));
} }
~LogScope() { ~LogScope() {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {EXIT}\n", PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {EXIT}\n",
GIVE_ME_MS_NOW(), GIVE_ME_MS_NOW(), mFrom, mFunc));
mFrom, mFunc.get()));
} }
private: private:
PRLogModuleInfo *mLog; PRLogModuleInfo *mLog;
void *mFrom; void *mFrom;
nsAutoCString mFunc; const char *mFunc;
}; };
class LogFunc { class LogFunc {
public: public:
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn) LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn)
{ {
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s\n", PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s\n",
GIVE_ME_MS_NOW(), from, GIVE_ME_MS_NOW(), from, fn));
fn.get()));
} }
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn, LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, const char *paramValue) const char *paramName, const char *paramValue)
{ {
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\")\n", PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\")\n",
GIVE_ME_MS_NOW(), from, GIVE_ME_MS_NOW(), from, fn,
fn.get(), paramName, paramValue));
paramName.get(), paramValue));
} }
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn, LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, const void *paramValue) const char *paramName, const void *paramValue)
{ {
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%p\")\n", PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%p\")\n",
GIVE_ME_MS_NOW(), from, GIVE_ME_MS_NOW(), from, fn,
fn.get(), paramName, paramValue));
paramName.get(), paramValue));
} }
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn, LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &paramName, uint32_t paramValue) const char *paramName, uint32_t paramValue)
{ {
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\")\n", PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\")\n",
GIVE_ME_MS_NOW(), from, GIVE_ME_MS_NOW(), from,
fn.get(), fn,
paramName.get(), paramValue)); paramName, paramValue));
} }
}; };
@ -141,13 +128,11 @@ public:
class LogMessage { class LogMessage {
public: public:
LogMessage(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn, LogMessage(PRLogModuleInfo *aLog, void *from, const char *fn,
const nsDependentCString &msg) const char *msg)
{ {
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s -- %s\n", PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s -- %s\n",
GIVE_ME_MS_NOW(), from, GIVE_ME_MS_NOW(), from, fn, msg));
fn.get(),
msg.get()));
} }
}; };
@ -156,45 +141,22 @@ public:
#define LOG_SCOPE_APPEND_LINE_NUMBER(id) LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__) #define LOG_SCOPE_APPEND_LINE_NUMBER(id) LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
#define LOG_SCOPE(l, s) \ #define LOG_SCOPE(l, s) \
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \ LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s)
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s))
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \ #define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \ LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s, pn, pv)
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#define LOG_FUNC(l, s) \ #define LOG_FUNC(l, s) LogFunc(l, this, s)
LogFunc(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s))
#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) \ #define LOG_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, this, s, pn, pv)
LogFunc(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#define LOG_STATIC_FUNC(l, s) \ #define LOG_STATIC_FUNC(l, s) LogFunc(l, nullptr, s)
LogFunc(l, \
nullptr, \
NS_LITERAL_CSTRING(s))
#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) \ #define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, nullptr, s, pn, pv)
LogFunc(l, \
nullptr, \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#define LOG_MSG(l, s, m) \ #define LOG_MSG(l, s, m) LogMessage(l, this, s, m)
LogMessage(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(m))
#else #else

Просмотреть файл

@ -314,6 +314,12 @@ struct ParamTraits<nsCString> : ParamTraits<nsACString>
typedef nsCString paramType; typedef nsCString paramType;
}; };
template <>
struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString>
{
typedef nsLiteralCString paramType;
};
#ifdef MOZILLA_INTERNAL_API #ifdef MOZILLA_INTERNAL_API
template<> template<>
@ -330,6 +336,12 @@ struct ParamTraits<nsString> : ParamTraits<nsAString>
typedef nsString paramType; typedef nsString paramType;
}; };
template <>
struct ParamTraits<nsLiteralString> : ParamTraits<nsAString>
{
typedef nsLiteralString paramType;
};
template <typename E> template <typename E>
struct ParamTraits<FallibleTArray<E> > struct ParamTraits<FallibleTArray<E> >
{ {

Просмотреть файл

@ -335,6 +335,14 @@ const Class SIMDObject::class_ = {
JSObject * JSObject *
SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global) SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
{ {
// SIMD relies on having the TypedObject module initialized.
// In particular, the self-hosted code for array() wants
// to be able to call GetTypedObjectModule(). It is NOT necessary
// to install the TypedObjectModule global, but at the moment
// those two things are not separable.
if (!global->getOrCreateTypedObjectModule(cx))
return nullptr;
// Create SIMD Object. // Create SIMD Object.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx)); RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if(!objProto) if(!objProto)

Просмотреть файл

@ -947,6 +947,8 @@ SizedTypeRepresentation::initInstance(const JSRuntime *rt,
uint8_t *mem, uint8_t *mem,
size_t length) size_t length)
{ {
JS_ASSERT(length >= 1);
MemoryInitVisitor visitor(rt); MemoryInitVisitor visitor(rt);
// Initialize the 0th instance // Initialize the 0th instance

Просмотреть файл

@ -231,7 +231,8 @@ class SizedTypeRepresentation : public TypeRepresentation {
size_t size() const { return size_; } size_t size() const { return size_; }
size_t alignment() const { return alignment_; } size_t alignment() const { return alignment_; }
// Initializes memory that contains `count` instances of this type // Initializes memory that contains `count` instances of this type.
// `count` must be at least 1.
void initInstance(const JSRuntime *rt, uint8_t *mem, size_t count); void initInstance(const JSRuntime *rt, uint8_t *mem, size_t count);
// Traces memory that contains `count` instances of this type. // Traces memory that contains `count` instances of this type.

Просмотреть файл

@ -2339,7 +2339,8 @@ TypedObject::createZeroed(JSContext *cx,
if (!memory) if (!memory)
return nullptr; return nullptr;
elementTypeRepr->initInstance(cx->runtime(), memory, length); if (length)
elementTypeRepr->initInstance(cx->runtime(), memory, length);
obj->attach(memory); obj->attach(memory);
return obj; return obj;
} }

Просмотреть файл

@ -0,0 +1,10 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var float32x4 = SIMD.float32x4;
float32x4.array(1);

Просмотреть файл

@ -0,0 +1,18 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
// bug 953111
var A = TypedObject.uint8.array();
var a = new A(0);
a.forEach(function(val, i) {});
// bug 951356 (dup, but a dup that is more likely to crash)
var AA = TypedObject.uint8.array(2147483647).array();
var aa = new AA(0);

Просмотреть файл

@ -6686,7 +6686,7 @@ IonBuilder::getElemTryScalarElemOfTypedObject(bool *emitted,
TypeRepresentationSet elemTypeReprs, TypeRepresentationSet elemTypeReprs,
size_t elemSize) size_t elemSize)
{ {
JS_ASSERT(objTypeReprs.kind() == TypeRepresentation::SizedArray); JS_ASSERT(objTypeReprs.allOfArrayKind());
// Must always be loading the same scalar type // Must always be loading the same scalar type
if (!elemTypeReprs.singleton()) if (!elemTypeReprs.singleton())

Просмотреть файл

@ -703,19 +703,21 @@ CodeGeneratorARM::modICommon(MMod *mir, Register lhs, Register rhs, Register out
// the flags necessary for LT to trigger, we don't test X, and take the // the flags necessary for LT to trigger, we don't test X, and take the
// bailout because the EQ flag is set. // bailout because the EQ flag is set.
// if (Y > 0), we don't set EQ, and we don't trigger LT, so we don't take the bailout. // if (Y > 0), we don't set EQ, and we don't trigger LT, so we don't take the bailout.
masm.ma_cmp(rhs, Imm32(0)); if (mir->canBeDivideByZero() || mir->canBeNegativeDividend()) {
masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan); masm.ma_cmp(rhs, Imm32(0));
if (mir->isTruncated()) { masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
// NaN|0 == 0 and (0 % -X)|0 == 0 if (mir->isTruncated()) {
Label skip; // NaN|0 == 0 and (0 % -X)|0 == 0
masm.ma_b(&skip, Assembler::NotEqual); Label skip;
masm.ma_mov(Imm32(0), output); masm.ma_b(&skip, Assembler::NotEqual);
masm.ma_b(&done); masm.ma_mov(Imm32(0), output);
masm.bind(&skip); masm.ma_b(&done);
} else { masm.bind(&skip);
JS_ASSERT(mir->fallible()); } else {
if (!bailoutIf(Assembler::Equal, snapshot)) JS_ASSERT(mir->fallible());
return false; if (!bailoutIf(Assembler::Equal, snapshot))
return false;
}
} }
return true; return true;
@ -740,16 +742,18 @@ CodeGeneratorARM::visitModI(LModI *ins)
masm.ma_smod(lhs, rhs, output); masm.ma_smod(lhs, rhs, output);
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0 // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
if (mir->isTruncated()) { if (mir->canBeNegativeDividend()) {
// -0.0|0 == 0 if (mir->isTruncated()) {
} else { // -0.0|0 == 0
JS_ASSERT(mir->fallible()); } else {
// See if X < 0 JS_ASSERT(mir->fallible());
masm.ma_cmp(output, Imm32(0)); // See if X < 0
masm.ma_b(&done, Assembler::NotEqual); masm.ma_cmp(output, Imm32(0));
masm.ma_cmp(callTemp, Imm32(0)); masm.ma_b(&done, Assembler::NotEqual);
if (!bailoutIf(Assembler::Signed, ins->snapshot())) masm.ma_cmp(callTemp, Imm32(0));
return false; if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
}
} }
masm.bind(&done); masm.bind(&done);
@ -802,16 +806,18 @@ CodeGeneratorARM::visitSoftModI(LSoftModI *ins)
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod)); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0 // If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
if (mir->isTruncated()) { if (mir->canBeNegativeDividend()) {
// -0.0|0 == 0 if (mir->isTruncated()) {
} else { // -0.0|0 == 0
JS_ASSERT(mir->fallible()); } else {
// See if X < 0 JS_ASSERT(mir->fallible());
masm.ma_cmp(r1, Imm32(0)); // See if X < 0
masm.ma_b(&done, Assembler::NotEqual); masm.ma_cmp(r1, Imm32(0));
masm.ma_cmp(callTemp, Imm32(0)); masm.ma_b(&done, Assembler::NotEqual);
if (!bailoutIf(Assembler::Signed, ins->snapshot())) masm.ma_cmp(callTemp, Imm32(0));
return false; if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
}
} }
masm.bind(&done); masm.bind(&done);
return true; return true;
@ -830,12 +836,14 @@ CodeGeneratorARM::visitModPowTwoI(LModPowTwoI *ins)
masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed); masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed);
masm.ma_and(Imm32((1<<ins->shift())-1), out); masm.ma_and(Imm32((1<<ins->shift())-1), out);
masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed); masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed);
if (!mir->isTruncated()) { if (mir->canBeNegativeDividend()) {
JS_ASSERT(mir->fallible()); if (!mir->isTruncated()) {
if (!bailoutIf(Assembler::Zero, ins->snapshot())) JS_ASSERT(mir->fallible());
return false; if (!bailoutIf(Assembler::Zero, ins->snapshot()))
} else { return false;
// -0|0 == 0 } else {
// -0|0 == 0
}
} }
masm.bind(&fin); masm.bind(&fin);
return true; return true;
@ -849,12 +857,14 @@ CodeGeneratorARM::visitModMaskI(LModMaskI *ins)
Register tmp = ToRegister(ins->getTemp(0)); Register tmp = ToRegister(ins->getTemp(0));
MMod *mir = ins->mir(); MMod *mir = ins->mir();
masm.ma_mod_mask(src, dest, tmp, ins->shift()); masm.ma_mod_mask(src, dest, tmp, ins->shift());
if (!mir->isTruncated()) { if (mir->canBeNegativeDividend()) {
JS_ASSERT(mir->fallible()); if (!mir->isTruncated()) {
if (!bailoutIf(Assembler::Zero, ins->snapshot())) JS_ASSERT(mir->fallible());
return false; if (!bailoutIf(Assembler::Zero, ins->snapshot()))
} else { return false;
// -0|0 == 0 } else {
// -0|0 == 0
}
} }
return true; return true;
} }

Просмотреть файл

@ -3209,7 +3209,7 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx)
} }
if (!finished) { if (!finished) {
if (!obj->rollbackProperties(cx, numProperties)) if (!JSObject::rollbackProperties(cx, obj, numProperties))
cx->compartment()->types.setPendingNukeTypes(cx); cx->compartment()->types.setPendingNukeTypes(cx);
} }
} }

Просмотреть файл

@ -416,7 +416,8 @@ class JSObject : public js::ObjectImpl
elements[i].js::HeapSlot::~HeapSlot(); elements[i].js::HeapSlot::~HeapSlot();
} }
bool rollbackProperties(js::ExclusiveContext *cx, uint32_t slotSpan); static bool rollbackProperties(js::ExclusiveContext *cx, js::HandleObject obj,
uint32_t slotSpan);
void nativeSetSlot(uint32_t slot, const js::Value &value) { void nativeSetSlot(uint32_t slot, const js::Value &value) {
JS_ASSERT(isNative()); JS_ASSERT(isNative());

Просмотреть файл

@ -1156,26 +1156,26 @@ JSObject::clear(JSContext *cx, HandleObject obj)
obj->checkShapeConsistency(); obj->checkShapeConsistency();
} }
bool /* static */ bool
JSObject::rollbackProperties(ExclusiveContext *cx, uint32_t slotSpan) JSObject::rollbackProperties(ExclusiveContext *cx, HandleObject obj, uint32_t slotSpan)
{ {
/* /*
* Remove properties from this object until it has a matching slot span. * Remove properties from this object until it has a matching slot span.
* The object cannot have escaped in a way which would prevent safe * The object cannot have escaped in a way which would prevent safe
* removal of the last properties. * removal of the last properties.
*/ */
JS_ASSERT(!inDictionaryMode() && slotSpan <= this->slotSpan()); JS_ASSERT(!obj->inDictionaryMode() && slotSpan <= obj->slotSpan());
while (true) { while (true) {
if (lastProperty()->isEmptyShape()) { if (obj->lastProperty()->isEmptyShape()) {
JS_ASSERT(slotSpan == 0); JS_ASSERT(slotSpan == 0);
break; break;
} else { } else {
uint32_t slot = lastProperty()->slot(); uint32_t slot = obj->lastProperty()->slot();
if (slot < slotSpan) if (slot < slotSpan)
break; break;
JS_ASSERT(getSlot(slot).isUndefined()); JS_ASSERT(obj->getSlot(slot).isUndefined());
} }
if (!removeProperty(cx, lastProperty()->propid())) if (!obj->removeProperty(cx, obj->lastProperty()->propid()))
return false; return false;
} }

Просмотреть файл

@ -47,6 +47,15 @@ XPCStringConvert::ClearZoneCache(JS::Zone *zone)
} }
} }
// static
void
XPCStringConvert::FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars)
{
}
const JSStringFinalizer XPCStringConvert::sLiteralFinalizer =
{ XPCStringConvert::FinalizeLiteral };
// static // static
void void
XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars) XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
@ -74,6 +83,16 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
return true; return true;
} }
if (readable.IsLiteral()) {
JSString *str = JS_NewExternalString(cx,
static_cast<const jschar*>(readable.BeginReading()),
length, &sLiteralFinalizer);
if (!str)
return false;
vp.setString(str);
return true;
}
nsStringBuffer *buf = nsStringBuffer::FromString(readable); nsStringBuffer *buf = nsStringBuffer::FromString(readable);
if (buf) { if (buf) {
bool shared; bool shared;

Просмотреть файл

@ -238,7 +238,9 @@ public:
static void ClearZoneCache(JS::Zone *zone); static void ClearZoneCache(JS::Zone *zone);
private: private:
static const JSStringFinalizer sDOMStringFinalizer; static const JSStringFinalizer sLiteralFinalizer, sDOMStringFinalizer;
static void FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars);
static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars); static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);

Просмотреть файл

@ -376,7 +376,9 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
if (kidContent) { if (kidContent) {
NS_ASSERTION(kidContent->IsNodeOfType(nsINode::eTEXT), NS_ASSERTION(kidContent->IsNodeOfType(nsINode::eTEXT),
"should contain only text nodes"); "should contain only text nodes");
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(mStyleContext); nsStyleContext* parentSC = prevInFlow ? mStyleContext->GetParent() :
mStyleContext;
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(parentSC);
kid->SetStyleContext(sc); kid->SetStyleContext(sc);
} }
} }

Просмотреть файл

@ -1359,8 +1359,9 @@ nsFlexContainerFrame::SanityCheckAnonymousFlexItems() const
"but it isn't"); "but it isn't");
if (child->StyleContext()->GetPseudo() == if (child->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::anonymousFlexItem) { nsCSSAnonBoxes::anonymousFlexItem) {
MOZ_ASSERT(!prevChildWasAnonFlexItem, MOZ_ASSERT(!prevChildWasAnonFlexItem || mChildrenHaveBeenReordered,
"two anon flex items in a row (shouldn't happen)"); "two anon flex items in a row (shouldn't happen, unless our "
"children have been reordered with the 'order' property)");
nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild(); nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild();
MOZ_ASSERT(firstWrappedChild, MOZ_ASSERT(firstWrappedChild,

Просмотреть файл

@ -0,0 +1,22 @@
<style type="text/css">
#descdiv{
overflow: hidden;
height: 60px;
border: 1px solid red;
}
#descdiv p{
height:30px;
margin:0;
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
This causes the text to be drawn even when it's outside of the clip*/
text-shadow: #fff 1px -1px 2px;
}
</style>
<div id="descdiv">
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
</div>

Просмотреть файл

@ -0,0 +1,22 @@
<style type="text/css">
#descdiv{
overflow: hidden;
height: 60px;
border: 1px solid red;
}
#descdiv p{
height:30px;
margin:0;
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
This causes the text to be drawn even when it's outside of the clip*/
text-shadow: #fff 1px -1px 2px;
}
</style>
<div id="descdiv">
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
<p class="um_desc">sed diam nonummy nibh</p>
</div>

Просмотреть файл

@ -1791,5 +1791,6 @@ fuzzy-if(OSX==10.6,2,30) == 933264-1.html 933264-1-ref.html
== 941940-1.html 941940-1-ref.html == 941940-1.html 941940-1-ref.html
== 942017.html 942017-ref.html == 942017.html 942017-ref.html
== 942672-1.html 942672-1-ref.html == 942672-1.html 942672-1-ref.html
== 953334-win32-clipping.html 953334-win32-clipping-ref.html
== 956513-1.svg 956513-1-ref.svg == 956513-1.svg 956513-1-ref.svg
== 944291-1.html 944291-1-ref.html == 944291-1.html 944291-1-ref.html

Просмотреть файл

@ -0,0 +1,15 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
</head>
<body>
a ab bx x
</body>
</html>

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that we gracefully handle cases where two anonymous flex items become adjacent due to "order" reordering</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#flex-items">
<link rel="match" href="flexbox-anonymous-items-1-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
}
</style>
</head>
<body>
<div class="flexContainer">
a a
<div style="order: 1">x x</div>
b b
</div>
</body>
</html>

Просмотреть файл

@ -1,3 +1,6 @@
# Tests for handling anonymous flex items
== flexbox-anonymous-items-1.html flexbox-anonymous-items-1-ref.html
# Tests for alignment of flex lines (align-content property) # Tests for alignment of flex lines (align-content property)
== flexbox-align-content-horiz-1a.xhtml flexbox-align-content-horiz-1-ref.xhtml == flexbox-align-content-horiz-1a.xhtml flexbox-align-content-horiz-1-ref.xhtml
== flexbox-align-content-horiz-1b.xhtml flexbox-align-content-horiz-1-ref.xhtml == flexbox-align-content-horiz-1b.xhtml flexbox-align-content-horiz-1-ref.xhtml

Просмотреть файл

@ -23,6 +23,9 @@
#include "android/log.h" #include "android/log.h"
#define MAX_DECODER_NAME_LEN 256
#define AVC_MIME_TYPE "video/avc"
#if !defined(MOZ_ANDROID_FROYO) #if !defined(MOZ_ANDROID_FROYO)
#define DEFAULT_STAGEFRIGHT_FLAGS OMXCodec::kClientNeedsFramebuffer #define DEFAULT_STAGEFRIGHT_FLAGS OMXCodec::kClientNeedsFramebuffer
#else #else
@ -239,7 +242,13 @@ static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost)
#endif #endif
} }
static bool enum ColorFormatSupport {
ColorFormatNotSupported = 0,
ColorFormatSupportOK,
ColorFormatSupportPreferred,
};
static ColorFormatSupport
IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat) IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
{ {
switch (aColorFormat) { switch (aColorFormat) {
@ -250,15 +259,19 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
LOG("Colour format %#x supported natively.", aColorFormat); LOG("Colour format %#x supported natively.", aColorFormat);
return true; // Prefer natively supported colour formats over formats that need another
// slow software conversion.
return ColorFormatSupportPreferred;
default: default:
break; break;
} }
// These formats are okay if we can't find a better one; Android provides a
// software conversion to a sane colour format.
#if !defined(MOZ_ANDROID_HC) #if !defined(MOZ_ANDROID_HC)
if (ColorConverter(aColorFormat, OMX_COLOR_Format16bitRGB565).isValid()) { if (ColorConverter(aColorFormat, OMX_COLOR_Format16bitRGB565).isValid()) {
LOG("Colour format %#x supported by Android ColorConverter.", aColorFormat); LOG("Colour format %#x supported by Android ColorConverter.", aColorFormat);
return true; return ColorFormatSupportOK;
} }
#endif #endif
@ -268,12 +281,64 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
if (yuvConverter.isLoaded() && if (yuvConverter.isLoaded() &&
yuvConverter.getDecoderOutputFormat() == aColorFormat) { yuvConverter.getDecoderOutputFormat() == aColorFormat) {
LOG("Colour format %#x supported by Android I420ColorConverter.", aColorFormat); LOG("Colour format %#x supported by Android I420ColorConverter.", aColorFormat);
return true; return ColorFormatSupportOK;
} }
#endif #endif
return ColorFormatNotSupported;
}
#if defined(MOZ_ANDROID_KK)
/**
* Look for a decoder that supports a colour format that we support.
*/
static bool
FindPreferredDecoderAndColorFormat(const sp<IOMX>& aOmx,
char *aDecoderName,
size_t aDecoderLen,
OMX_COLOR_FORMATTYPE *aColorFormat)
{
Vector<CodecCapabilities> codecs;
// Get all AVC decoder/colour format pairs that this device supports.
QueryCodecs(aOmx, AVC_MIME_TYPE, true /* queryDecoders */, &codecs);
// We assume that faster (hardware accelerated) decoders come first in the
// list, so we choose the first decoder with a colour format we can use.
for (uint32_t i = 0; i < codecs.size(); i++) {
const CodecCapabilities &caps = codecs[i];
const Vector<OMX_U32> &colors = caps.mColorFormats;
bool found = false;
for (uint32_t j = 0; j < colors.size(); j++) {
OMX_COLOR_FORMATTYPE color = (OMX_COLOR_FORMATTYPE)colors[j];
LOG("Decoder %s can output colour format %#x.\n",
caps.mComponentName.string(), color);
ColorFormatSupport supported = IsColorFormatSupported(color);
if (supported) {
strncpy(aDecoderName, caps.mComponentName.string(), aDecoderLen);
*aColorFormat = (OMX_COLOR_FORMATTYPE)color;
found = true;
}
if (supported == ColorFormatSupportPreferred) {
// The colour format is natively supported -- that's as good as we're
// going to get.
break;
}
}
if (found) {
return true;
}
}
return false; return false;
} }
#endif
static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost, static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
const sp<IOMX>& aOmx, const sp<IOMX>& aOmx,
@ -281,10 +346,29 @@ static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
{ {
uint32_t flags = GetVideoCreationFlags(aPluginHost); uint32_t flags = GetVideoCreationFlags(aPluginHost);
char decoderName[MAX_DECODER_NAME_LEN] = "";
sp<MetaData> videoFormat = aVideoTrack->getFormat();
#if defined(MOZ_ANDROID_KK)
OMX_COLOR_FORMATTYPE colorFormat = (OMX_COLOR_FORMATTYPE)0;
if (FindPreferredDecoderAndColorFormat(aOmx,
decoderName, sizeof(decoderName),
&colorFormat)) {
// We found a colour format that we can handle. Tell OMXCodec to use it in
// case it isn't the default.
videoFormat->setInt32(kKeyColorFormat, colorFormat);
LOG("Found compatible decoder %s with colour format %#x.\n",
decoderName, colorFormat);
}
#endif
if (flags == DEFAULT_STAGEFRIGHT_FLAGS) { if (flags == DEFAULT_STAGEFRIGHT_FLAGS) {
// Let Stagefright choose hardware or software decoder. // Let Stagefright choose hardware or software decoder.
sp<MediaSource> videoSource = OMXCodec::Create(aOmx, aVideoTrack->getFormat(), sp<MediaSource> videoSource = OMXCodec::Create(aOmx, videoFormat,
false, aVideoTrack, nullptr, flags); false, aVideoTrack,
decoderName[0] ? decoderName : nullptr,
flags);
if (videoSource == nullptr) if (videoSource == nullptr)
return nullptr; return nullptr;

Просмотреть файл

@ -21,7 +21,8 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <utils/Log.h> #include <cutils/log.h>
#include <utils/VectorImpl.h> #include <utils/VectorImpl.h>
#include <utils/TypeHelpers.h> #include <utils/TypeHelpers.h>
@ -43,11 +44,11 @@ class Vector : private VectorImpl
{ {
public: public:
typedef TYPE value_type; typedef TYPE value_type;
/*! /*!
* Constructors and destructors * Constructors and destructors
*/ */
Vector(); Vector();
Vector(const Vector<TYPE>& rhs); Vector(const Vector<TYPE>& rhs);
explicit Vector(const SortedVector<TYPE>& rhs); explicit Vector(const SortedVector<TYPE>& rhs);
@ -55,7 +56,7 @@ public:
/*! copy operator */ /*! copy operator */
const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const; const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const Vector<TYPE>& rhs); Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const; const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs); Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
@ -66,29 +67,35 @@ public:
inline void clear() { VectorImpl::clear(); } inline void clear() { VectorImpl::clear(); }
/*! /*!
* vector stats * vector stats
*/ */
//! returns number of items in the vector //! returns number of items in the vector
inline size_t size() const { return VectorImpl::size(); } inline size_t size() const { return VectorImpl::size(); }
//! returns wether or not the vector is empty //! returns whether or not the vector is empty
inline bool isEmpty() const { return VectorImpl::isEmpty(); } inline bool isEmpty() const { return VectorImpl::isEmpty(); }
//! returns how many items can be stored without reallocating the backing store //! returns how many items can be stored without reallocating the backing store
inline size_t capacity() const { return VectorImpl::capacity(); } inline size_t capacity() const { return VectorImpl::capacity(); }
//! setst the capacity. capacity can never be reduced less than size() //! sets the capacity. capacity can never be reduced less than size()
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
/*! /*!
* set the size of the vector. items are appended with the default
* constructor, or removed from the end as needed.
*/
inline ssize_t resize(size_t size) { return VectorImpl::resize(size); }
/*!
* C-style array access * C-style array access
*/ */
//! read-only C-style access //! read-only C-style access
inline const TYPE* array() const; inline const TYPE* array() const;
//! read-write C-style access //! read-write C-style access
TYPE* editArray(); TYPE* editArray();
/*! /*!
* accessors * accessors
*/ */
@ -98,22 +105,20 @@ public:
inline const TYPE& itemAt(size_t index) const; inline const TYPE& itemAt(size_t index) const;
//! stack-usage of the vector. returns the top of the stack (last element) //! stack-usage of the vector. returns the top of the stack (last element)
const TYPE& top() const; const TYPE& top() const;
//! same as operator [], but allows to access the vector backward (from the end) with a negative index
const TYPE& mirrorItemAt(ssize_t index) const;
/*! /*!
* modifing the array * modifying the array
*/ */
//! copy-on write support, grants write access to an item //! copy-on write support, grants write access to an item
TYPE& editItemAt(size_t index); TYPE& editItemAt(size_t index);
//! grants right acces to the top of the stack (last element) //! grants right access to the top of the stack (last element)
TYPE& editTop(); TYPE& editTop();
/*! /*!
* append/insert another vector * append/insert another vector
*/ */
//! insert another vector at a given index //! insert another vector at a given index
ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index); ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index);
@ -127,10 +132,10 @@ public:
//! append an array at the end of this vector //! append an array at the end of this vector
ssize_t appendArray(const TYPE* array, size_t length); ssize_t appendArray(const TYPE* array, size_t length);
/*! /*!
* add/insert/replace items * add/insert/replace items
*/ */
//! insert one or several items initialized with their default constructor //! insert one or several items initialized with their default constructor
inline ssize_t insertAt(size_t index, size_t numItems = 1); inline ssize_t insertAt(size_t index, size_t numItems = 1);
//! insert one or several items initialized from a prototype item //! insert one or several items initialized from a prototype item
@ -144,7 +149,7 @@ public:
//! same as push() but returns the index the item was added at (or an error) //! same as push() but returns the index the item was added at (or an error)
inline ssize_t add(); inline ssize_t add();
//! same as push() but returns the index the item was added at (or an error) //! same as push() but returns the index the item was added at (or an error)
ssize_t add(const TYPE& item); ssize_t add(const TYPE& item);
//! replace an item with a new one initialized with its default constructor //! replace an item with a new one initialized with its default constructor
inline ssize_t replaceAt(size_t index); inline ssize_t replaceAt(size_t index);
//! replace an item with a new one //! replace an item with a new one
@ -162,10 +167,10 @@ public:
/*! /*!
* sort (stable) the array * sort (stable) the array
*/ */
typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs); typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state); typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
inline status_t sort(compar_t cmp); inline status_t sort(compar_t cmp);
inline status_t sort(compar_r_t cmp, void* state); inline status_t sort(compar_r_t cmp, void* state);
@ -186,10 +191,11 @@ public:
inline const_iterator end() const { return array() + size(); } inline const_iterator end() const { return array() + size(); }
inline void reserve(size_t n) { setCapacity(n); } inline void reserve(size_t n) { setCapacity(n); }
inline bool empty() const{ return isEmpty(); } inline bool empty() const{ return isEmpty(); }
inline void push_back(const TYPE& item) { insertAt(item, size()); } inline void push_back(const TYPE& item) { insertAt(item, size(), 1); }
inline void push_front(const TYPE& item) { insertAt(item, 0); } inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
inline iterator erase(iterator pos) { inline iterator erase(iterator pos) {
return begin() + removeItemsAt(pos-array()); ssize_t index = removeItemsAt(pos-array());
return begin() + index;
} }
protected: protected:
@ -201,6 +207,9 @@ protected:
virtual void do_move_backward(void* dest, const void* from, size_t num) const; virtual void do_move_backward(void* dest, const void* from, size_t num) const;
}; };
// Vector<T> can be trivially moved using memcpy() because moving does not
// require any change to the underlying SharedBuffer contents or reference count.
template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// No user serviceable parts from here... // No user serviceable parts from here...
@ -234,7 +243,7 @@ Vector<TYPE>::~Vector() {
template<class TYPE> inline template<class TYPE> inline
Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) { Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
VectorImpl::operator = (rhs); VectorImpl::operator = (rhs);
return *this; return *this;
} }
template<class TYPE> inline template<class TYPE> inline
@ -252,7 +261,7 @@ Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
template<class TYPE> inline template<class TYPE> inline
const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const { const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
VectorImpl::operator = (rhs); VectorImpl::operator = (rhs);
return *this; return *this;
} }
template<class TYPE> inline template<class TYPE> inline
@ -268,8 +277,9 @@ TYPE* Vector<TYPE>::editArray() {
template<class TYPE> inline template<class TYPE> inline
const TYPE& Vector<TYPE>::operator[](size_t index) const { const TYPE& Vector<TYPE>::operator[](size_t index) const {
LOG_FATAL_IF( index>=size(), LOG_FATAL_IF(index>=size(),
"itemAt: index %d is past size %d", (int)index, (int)size() ); "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
int(index), int(size()));
return *(array() + index); return *(array() + index);
} }
@ -278,14 +288,6 @@ const TYPE& Vector<TYPE>::itemAt(size_t index) const {
return operator[](index); return operator[](index);
} }
template<class TYPE> inline
const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
"mirrorItemAt: index %d is past size %d",
(int)index, (int)size() );
return *(array() + ((index<0) ? (size()-index) : index));
}
template<class TYPE> inline template<class TYPE> inline
const TYPE& Vector<TYPE>::top() const { const TYPE& Vector<TYPE>::top() const {
return *(array() + size() - 1); return *(array() + size() - 1);
@ -419,3 +421,4 @@ void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) co
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#endif // ANDROID_VECTOR_H #endif // ANDROID_VECTOR_H

Просмотреть файл

@ -53,24 +53,25 @@ public:
/*! must be called from subclasses destructor */ /*! must be called from subclasses destructor */
void finish_vector(); void finish_vector();
VectorImpl& operator = (const VectorImpl& rhs); VectorImpl& operator = (const VectorImpl& rhs);
/*! C-style array access */ /*! C-style array access */
inline const void* arrayImpl() const { return mStorage; } inline const void* arrayImpl() const { return mStorage; }
void* editArrayImpl(); void* editArrayImpl();
/*! vector stats */ /*! vector stats */
inline size_t size() const { return mCount; } inline size_t size() const { return mCount; }
inline bool isEmpty() const { return mCount == 0; } inline bool isEmpty() const { return mCount == 0; }
size_t capacity() const; size_t capacity() const;
ssize_t setCapacity(size_t size); ssize_t setCapacity(size_t size);
ssize_t resize(size_t size);
/*! append/insert another vector or array */ /*! append/insert another vector or array */
ssize_t insertVectorAt(const VectorImpl& vector, size_t index); ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
ssize_t appendVector(const VectorImpl& vector); ssize_t appendVector(const VectorImpl& vector);
ssize_t insertArrayAt(const void* array, size_t index, size_t length); ssize_t insertArrayAt(const void* array, size_t index, size_t length);
ssize_t appendArray(const void* array, size_t length); ssize_t appendArray(const void* array, size_t length);
/*! add/insert/replace items */ /*! add/insert/replace items */
ssize_t insertAt(size_t where, size_t numItems = 1); ssize_t insertAt(size_t where, size_t numItems = 1);
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
@ -105,16 +106,6 @@ protected:
virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
// take care of FBC...
virtual void reservedVectorImpl1();
virtual void reservedVectorImpl2();
virtual void reservedVectorImpl3();
virtual void reservedVectorImpl4();
virtual void reservedVectorImpl5();
virtual void reservedVectorImpl6();
virtual void reservedVectorImpl7();
virtual void reservedVectorImpl8();
private: private:
void* _grow(size_t where, size_t amount); void* _grow(size_t where, size_t amount);
void _shrink(size_t where, size_t amount); void _shrink(size_t where, size_t amount);
@ -143,8 +134,8 @@ public:
SortedVectorImpl(size_t itemSize, uint32_t flags); SortedVectorImpl(size_t itemSize, uint32_t flags);
SortedVectorImpl(const VectorImpl& rhs); SortedVectorImpl(const VectorImpl& rhs);
virtual ~SortedVectorImpl(); virtual ~SortedVectorImpl();
SortedVectorImpl& operator = (const SortedVectorImpl& rhs); SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
//! finds the index of an item //! finds the index of an item
ssize_t indexOf(const void* item) const; ssize_t indexOf(const void* item) const;
@ -158,23 +149,13 @@ public:
//! merges a vector into this one //! merges a vector into this one
ssize_t merge(const VectorImpl& vector); ssize_t merge(const VectorImpl& vector);
ssize_t merge(const SortedVectorImpl& vector); ssize_t merge(const SortedVectorImpl& vector);
//! removes an item //! removes an item
ssize_t remove(const void* item); ssize_t remove(const void* item);
protected: protected:
virtual int do_compare(const void* lhs, const void* rhs) const = 0; virtual int do_compare(const void* lhs, const void* rhs) const = 0;
// take care of FBC...
virtual void reservedSortedVectorImpl1();
virtual void reservedSortedVectorImpl2();
virtual void reservedSortedVectorImpl3();
virtual void reservedSortedVectorImpl4();
virtual void reservedSortedVectorImpl5();
virtual void reservedSortedVectorImpl6();
virtual void reservedSortedVectorImpl7();
virtual void reservedSortedVectorImpl8();
private: private:
ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
@ -200,3 +181,4 @@ private:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#endif // ANDROID_VECTOR_IMPL_H #endif // ANDROID_VECTOR_IMPL_H

Просмотреть файл

@ -0,0 +1,31 @@
# Copyright 2012 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Don't use STL wrappers; this isn't Gecko code
STL_FLAGS =
# must link statically with the CRT; this isn't Gecko code
USE_STATIC_LIBS = 1
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS += \
-L$(DEPTH)/media/omx-plugin/lib/ics/libutils \
-lutils \
-L$(DEPTH)/media/omx-plugin/lib/ics/libstagefright \
-lstagefright \
-L$(DEPTH)/media/omx-plugin/lib/ics/libvideoeditorplayer \
-lvideoeditorplayer \
$(NULL)

Просмотреть файл

@ -0,0 +1,8 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#define MOZ_STAGEFRIGHT_OFF_T off64_t
#define MOZ_ANDROID_KK
#include "../OmxPlugin.cpp"

Просмотреть файл

@ -0,0 +1,20 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
SOURCES += [
'OmxPluginKitKat.cpp',
]
LIBRARY_NAME = 'omxpluginkk'
FORCE_SHARED_LIB = True
LOCAL_INCLUDES += [
'../../../content/media/plugins',
'../include/ics',
'../include/ics/media/stagefright/openmax',
]

Просмотреть файл

@ -61,6 +61,12 @@ MetaData::findInt32(uint32_t key, int32_t *value)
return false; return false;
} }
MOZ_EXPORT bool
MetaData::setInt32(uint32_t, int32_t)
{
return false;
}
MOZ_EXPORT bool MOZ_EXPORT bool
MetaData::findInt64(uint32_t key, int64_t *value) MetaData::findInt64(uint32_t key, int64_t *value)
{ {
@ -176,4 +182,12 @@ ColorConverter::convert(const void *srcBits,
{ {
return 0; return 0;
} }
MOZ_EXPORT status_t QueryCodecs(const sp<IOMX> &omx,
const char *mimeType, bool queryDecoders,
Vector<CodecCapabilities> *results)
{
return 0;
}
} }

Просмотреть файл

@ -7,6 +7,7 @@
#include "utils/RefBase.h" #include "utils/RefBase.h"
#include "utils/String16.h" #include "utils/String16.h"
#include "utils/String8.h" #include "utils/String8.h"
#include "utils/Vector.h"
namespace android { namespace android {
MOZ_EXPORT RefBase::RefBase() : mRefs(0) MOZ_EXPORT RefBase::RefBase() : mRefs(0)
@ -54,7 +55,30 @@ MOZ_EXPORT String8::String8()
{ {
} }
MOZ_EXPORT String8::String8(const String8 &)
{
}
MOZ_EXPORT String8::~String8() MOZ_EXPORT String8::~String8()
{ {
} }
MOZ_EXPORT VectorImpl::VectorImpl(size_t, uint32_t)
: mFlags(0), mItemSize(0)
{
}
MOZ_EXPORT VectorImpl::VectorImpl(const VectorImpl &)
: mFlags(0), mItemSize(0)
{
}
MOZ_EXPORT VectorImpl::~VectorImpl()
{
}
MOZ_EXPORT void VectorImpl::finish_vector()
{
}
} }

Просмотреть файл

@ -47,6 +47,7 @@
@BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginkk@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginfroyo@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@omxpluginfroyo@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@

Просмотреть файл

@ -1381,6 +1381,9 @@ nsHttpConnection::OnSocketReadable()
PRIntervalTime now = PR_IntervalNow(); PRIntervalTime now = PR_IntervalNow();
PRIntervalTime delta = now - mLastReadTime; PRIntervalTime delta = now - mLastReadTime;
// Reset mResponseTimeoutEnabled to stop response timeout checks.
mResponseTimeoutEnabled = false;
if (mKeepAliveMask && (delta >= mMaxHangTime)) { if (mKeepAliveMask && (delta >= mMaxHangTime)) {
LOG(("max hang time exceeded!\n")); LOG(("max hang time exceeded!\n"));
// give the handler a chance to create a new persistent connection to // give the handler a chance to create a new persistent connection to

Просмотреть файл

@ -23,7 +23,8 @@ XCODE_APP_STORE = 'macappstore://itunes.apple.com/app/id497799835?mt=12'
XCODE_LEGACY = 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg' XCODE_LEGACY = 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg'
HOMEBREW_AUTOCONF213 = 'https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb' HOMEBREW_AUTOCONF213 = 'https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb'
MACPORTS_URL = {'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg', MACPORTS_URL = {'9': 'https://distfiles.macports.org/MacPorts/MacPorts-2.2.1-10.9-Mavericks.pkg',
'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg',
'7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg', '7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg',
'6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',} '6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',}

Просмотреть файл

@ -209,3 +209,8 @@ class WaitUntilTest(MarionetteTestCase):
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt) self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
self.assertEqual(self.clock.ticks, 2) self.assertEqual(self.clock.ticks, 2)
def test_timeout_elapsed_duration(self):
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 2 seconds"):
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)

Просмотреть файл

@ -40,7 +40,7 @@ class Wait(object):
# every 5 seconds. # every 5 seconds.
wait = Wait(marionette, timeout=30, interval=5, wait = Wait(marionette, timeout=30, interval=5,
ignored_exceptions=errors.NoSuchWindowException) ignored_exceptions=errors.NoSuchWindowException)
window = wait.until(lambda marionette: marionette.switch_to_window(42)) window = wait.until(lambda m: m.switch_to_window(42))
:param marionette: The input value to be provided to :param marionette: The input value to be provided to
conditions, usually a Marionette instance. conditions, usually a Marionette instance.
@ -78,7 +78,6 @@ class Wait(object):
exceptions.append(ignored_exceptions) exceptions.append(ignored_exceptions)
self.exceptions = tuple(set(exceptions)) self.exceptions = tuple(set(exceptions))
def until(self, condition, is_true=None): def until(self, condition, is_true=None):
"""Repeatedly runs condition until its return value evaluates to true, """Repeatedly runs condition until its return value evaluates to true,
or its timeout expires or the predicate evaluates to true. or its timeout expires or the predicate evaluates to true.
@ -109,6 +108,7 @@ class Wait(object):
rv = None rv = None
last_exc = None last_exc = None
until = is_true or until_pred until = is_true or until_pred
start = self.clock.now
while not until(self.clock, self.end): while not until(self.clock, self.end):
try: try:
@ -130,7 +130,8 @@ class Wait(object):
if last_exc is not None: if last_exc is not None:
raise last_exc raise last_exc
raise errors.TimeoutException raise errors.TimeoutException(
"Timed out after %s seconds" % (self.clock.now - start))
def until_pred(clock, end): def until_pred(clock, end):
return clock.now >= end return clock.now >= end

Просмотреть файл

@ -187,6 +187,8 @@
"dom/tests/mochitest/geolocation/test_mozsettings.html": "mozSettings is undefined", "dom/tests/mochitest/geolocation/test_mozsettings.html": "mozSettings is undefined",
"dom/tests/mochitest/geolocation/test_mozsettingsWatch.html": "mozSettings is undefined", "dom/tests/mochitest/geolocation/test_mozsettingsWatch.html": "mozSettings is undefined",
"dom/tests/mochitest/geolocation/test_shutdown.html": "TIMED_OUT", "dom/tests/mochitest/geolocation/test_shutdown.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_timeoutWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_timerRestartWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_windowClose.html": "TIMED_OUT", "dom/tests/mochitest/geolocation/test_windowClose.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html": "TIMED_OUT", "dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html": "TIMED_OUT",
"dom/tests/mochitest/localstorage/test_bug624047.html": "TIMED_OUT", "dom/tests/mochitest/localstorage/test_bug624047.html": "TIMED_OUT",

Просмотреть файл

@ -1093,7 +1093,7 @@ nsDownloadManager::GetDownloadFromDB(const nsACString& aGUID, nsDownload **retVa
MOZ_ASSERT(!FindDownload(aGUID), MOZ_ASSERT(!FindDownload(aGUID),
"If it is a current download, you should not call this method!"); "If it is a current download, you should not call this method!");
nsDependentCString query = NS_LITERAL_CSTRING( NS_NAMED_LITERAL_CSTRING(query,
"SELECT id, state, startTime, source, target, tempPath, name, referrer, " "SELECT id, state, startTime, source, target, tempPath, name, referrer, "
"entityID, currBytes, maxBytes, mimeType, preferredAction, " "entityID, currBytes, maxBytes, mimeType, preferredAction, "
"preferredApplication, autoResume, guid " "preferredApplication, autoResume, guid "

Просмотреть файл

@ -408,7 +408,8 @@ INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is only enabled o
endif endif
ifdef MOZ_OMX_PLUGIN ifdef MOZ_OMX_PLUGIN
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginfroyo.so DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so \
libomxpluginhc.so libomxpluginfroyo.so libomxpluginkk.so
endif endif
SO_LIBRARIES := $(filter %.so,$(DIST_FILES)) SO_LIBRARIES := $(filter %.so,$(DIST_FILES))

Просмотреть файл

@ -87,6 +87,7 @@ if CONFIG['MOZ_OMX_PLUGIN']:
'media/omx-plugin/froyo', 'media/omx-plugin/froyo',
'media/omx-plugin/lib/hc/libstagefright', 'media/omx-plugin/lib/hc/libstagefright',
'media/omx-plugin/hc', 'media/omx-plugin/hc',
'media/omx-plugin/kk',
]) ])
if CONFIG['ENABLE_TESTS']: if CONFIG['ENABLE_TESTS']:

Просмотреть файл

@ -109,7 +109,6 @@ protected:
// to 3%-4%). See bmo bug 395397. // to 3%-4%). See bmo bug 395397.
static const uint32_t kHadMoreEventsCountMax = 3; static const uint32_t kHadMoreEventsCountMax = 3;
int32_t mRecursionDepth;
int32_t mNativeEventCallbackDepth; int32_t mNativeEventCallbackDepth;
// Can be set from different threads, so must be modified atomically // Can be set from different threads, so must be modified atomically
int32_t mNativeEventScheduledDepth; int32_t mNativeEventScheduledDepth;

Просмотреть файл

@ -210,7 +210,6 @@ nsAppShell::nsAppShell()
, mTerminated(false) , mTerminated(false)
, mSkippedNativeCallback(false) , mSkippedNativeCallback(false)
, mHadMoreEventsCount(0) , mHadMoreEventsCount(0)
, mRecursionDepth(0)
, mNativeEventCallbackDepth(0) , mNativeEventCallbackDepth(0)
, mNativeEventScheduledDepth(0) , mNativeEventScheduledDepth(0)
{ {
@ -712,11 +711,14 @@ nsAppShell::ProcessNextNativeEvent(bool aMayWait)
bool bool
nsAppShell::InGeckoMainEventLoop() nsAppShell::InGeckoMainEventLoop()
{ {
if ((gXULModalLevel > 0) || (mRecursionDepth > 0)) if (gXULModalLevel > 0)
return false; return false;
if (mNativeEventCallbackDepth <= 0) if (mNativeEventCallbackDepth <= 0)
return false; return false;
return true;
bool isProcessingEvents = false;
NS_GetCurrentThread()->GetIsProcessingEvents(&isProcessingEvents);
return !isProcessingEvents;
} }
// Run // Run
@ -818,8 +820,6 @@ nsAppShell::OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait,
{ {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
mRecursionDepth = aRecursionDepth;
NS_ASSERTION(mAutoreleasePools, NS_ASSERTION(mAutoreleasePools,
"No stack on which to store autorelease pool"); "No stack on which to store autorelease pool");
@ -845,8 +845,6 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
{ {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
mRecursionDepth = aRecursionDepth;
CFIndex count = ::CFArrayGetCount(mAutoreleasePools); CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
NS_ASSERTION(mAutoreleasePools && count, NS_ASSERTION(mAutoreleasePools && count,

Просмотреть файл

@ -66,11 +66,21 @@ stack_callback(void *pc, void *sp, void *closure)
} }
#ifdef DEBUG #ifdef DEBUG
#include "nsCocoaFeatures.h" #define MAC_OS_X_VERSION_10_7_HEX 0x00001070
static int32_t OSXVersion()
{
static int32_t gOSXVersion = 0x0;
if (gOSXVersion == 0x0) {
OSErr err = ::Gestalt(gestaltSystemVersion, (SInt32*)&gOSXVersion);
MOZ_ASSERT(err == noErr);
}
return gOSXVersion;
}
static bool OnLionOrLater() static bool OnLionOrLater()
{ {
return nsCocoaFeatures::OnLionOrLater(); return (OSXVersion() >= MAC_OS_X_VERSION_10_7_HEX);
} }
#endif #endif

Просмотреть файл

@ -1892,8 +1892,7 @@ nsLocalFile::Launch()
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
rv = mimeService->GetTypeFromFile(this, type); rv = mimeService->GetTypeFromFile(this, type);
nsDependentCString fileUri = NS_LITERAL_CSTRING("file://"); nsAutoCString fileUri = NS_LITERAL_CSTRING("file://") + mPath;
fileUri.Append(mPath);
return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE; return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
#elif defined(MOZ_WIDGET_COCOA) #elif defined(MOZ_WIDGET_COCOA)
CFURLRef url; CFURLRef url;

Просмотреть файл

@ -23,6 +23,7 @@ EXPORTS += [
'nsSubstringTuple.h', 'nsSubstringTuple.h',
'nsTDependentString.h', 'nsTDependentString.h',
'nsTDependentSubstring.h', 'nsTDependentSubstring.h',
'nsTLiteralString.h',
'nsTPromiseFlatString.h', 'nsTPromiseFlatString.h',
'nsTString.h', 'nsTString.h',
'nsTSubstring.h', 'nsTSubstring.h',

Просмотреть файл

@ -16,14 +16,6 @@
#include "nsStringIterator.h" #include "nsStringIterator.h"
#endif #endif
// If some platform(s) can't handle our template that matches literal strings,
// then we'll disable it on those platforms.
#ifndef NS_DISABLE_LITERAL_TEMPLATE
# if (defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x560)) || (defined(__HP_aCC) && (__HP_aCC <= 012100))
# define NS_DISABLE_LITERAL_TEMPLATE
# endif
#endif /* !NS_DISABLE_LITERAL_TEMPLATE */
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>

Просмотреть файл

@ -10,46 +10,32 @@
#include "nscore.h" #include "nscore.h"
#endif #endif
#ifndef nsDependentString_h___ #ifndef nsString_h___
#include "nsDependentString.h" #include "nsString.h"
#endif #endif
// declare nsLiteralString
#include "string-template-def-unichar.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
// declare nsLiteralCString
#include "string-template-def-char.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
#include "mozilla/Char16.h" #include "mozilla/Char16.h"
namespace mozilla { #define NS_MULTILINE_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(s))
namespace internal { #define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(s)
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsLiteralString n(s)
// This is the same as sizeof(c) - 1, except it won't compile if c isn't a #define NS_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(MOZ_UTF16(s)))
// string literal. This ensures that NS_LITERAL_CSTRING doesn't compile if you #define NS_LITERAL_STRING_INIT(n,s) n(MOZ_UTF16(s))
// pass it a char* (or something else for that matter). #define NS_NAMED_LITERAL_STRING(n,s) const nsLiteralString n(MOZ_UTF16(s))
template<int n>
inline uint32_t LiteralStringLength(const char (&c)[n])
{
return n - 1;
}
template<int n> #define NS_LITERAL_CSTRING(s) static_cast<const nsLiteralCString&>(nsLiteralCString(s))
inline uint32_t LiteralWStringLength(const char16_t (&c)[n]) #define NS_LITERAL_CSTRING_INIT(n,s) n(s)
{ #define NS_NAMED_LITERAL_CSTRING(n,s) const nsLiteralCString n(s)
return n - 1;
}
} // namespace internal
} // namespace mozilla
#define NS_MULTILINE_LITERAL_STRING(s) nsDependentString(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
#define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsDependentString n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
typedef nsDependentString nsLiteralString;
#define NS_LITERAL_STRING(s) static_cast<const nsAFlatString&>(NS_MULTILINE_LITERAL_STRING(MOZ_UTF16(s)))
#define NS_LITERAL_STRING_INIT(n,s) NS_MULTILINE_LITERAL_STRING_INIT(n, MOZ_UTF16(s))
#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n, MOZ_UTF16(s))
#define NS_LITERAL_CSTRING(s) static_cast<const nsDependentCString&>(nsDependentCString(s, mozilla::internal::LiteralStringLength(s)))
#define NS_LITERAL_CSTRING_INIT(n,s) n(s, mozilla::internal::LiteralStringLength(s))
#define NS_NAMED_LITERAL_CSTRING(n,s) const nsDependentCString n(s, mozilla::internal::LiteralStringLength(s))
typedef nsDependentCString nsLiteralCString;
#endif /* !defined(nsLiteralString_h___) */ #endif /* !defined(nsLiteralString_h___) */

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
/**
* nsTLiteralString_CharT
*
* Stores a null-terminated, immutable sequence of characters.
*
* Subclass of nsTString that restricts string value to a literal
* character sequence. This class does not own its data. The data is
* assumed to be permanent. In practice this is true because this code
* is only usable by and for libxul.
*/
class nsTLiteralString_CharT : public nsTString_CharT
{
public:
typedef nsTLiteralString_CharT self_type;
public:
/**
* constructor
*/
template<size_type N>
nsTLiteralString_CharT( const char_type (&str)[N] )
: string_type(const_cast<char_type*>(str), N - 1, F_TERMINATED | F_LITERAL)
{
}
private:
// NOT TO BE IMPLEMENTED
template<size_type N>
nsTLiteralString_CharT( char_type (&str)[N] ) MOZ_DELETE;
};

Просмотреть файл

@ -214,11 +214,21 @@ class nsTSubstring_CharT
return mLength; return mLength;
} }
uint32_t Flags() const
{
return mFlags;
}
bool IsEmpty() const bool IsEmpty() const
{ {
return mLength == 0; return mLength == 0;
} }
bool IsLiteral() const
{
return (mFlags & F_LITERAL) != 0;
}
bool IsVoid() const bool IsVoid() const
{ {
return (mFlags & F_VOIDED) != 0; return (mFlags & F_VOIDED) != 0;
@ -297,24 +307,11 @@ class nsTSubstring_CharT
// non-constant char array variable. Use EqualsASCII for them. // non-constant char array variable. Use EqualsASCII for them.
// The template trick to acquire the array length at compile time without // The template trick to acquire the array length at compile time without
// using a macro is due to Corey Kosak, with much thanks. // using a macro is due to Corey Kosak, with much thanks.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline bool EqualsLiteral( const char* str ) const
{
return EqualsASCII(str);
}
#else
template<int N> template<int N>
inline bool EqualsLiteral( const char (&str)[N] ) const inline bool EqualsLiteral( const char (&str)[N] ) const
{ {
return EqualsASCII(str, N-1); return EqualsASCII(str, N-1);
} }
template<int N>
inline bool EqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return EqualsASCII(s, N-1);
}
#endif
// The LowerCaseEquals methods compare the ASCII-lowercase version of // The LowerCaseEquals methods compare the ASCII-lowercase version of
// this string (lowercasing only ASCII uppercase characters) to some // this string (lowercasing only ASCII uppercase characters) to some
@ -330,24 +327,11 @@ class nsTSubstring_CharT
// explicit size. Do not attempt to use it with a regular char* // explicit size. Do not attempt to use it with a regular char*
// pointer, or with a non-constant char array variable. Use // pointer, or with a non-constant char array variable. Use
// LowerCaseEqualsASCII for them. // LowerCaseEqualsASCII for them.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline bool LowerCaseEqualsLiteral( const char* str ) const
{
return LowerCaseEqualsASCII(str);
}
#else
template<int N> template<int N>
inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const
{ {
return LowerCaseEqualsASCII(str, N-1); return LowerCaseEqualsASCII(str, N-1);
} }
template<int N>
inline bool LowerCaseEqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return LowerCaseEqualsASCII(s, N-1);
}
#endif
/** /**
* assignment * assignment
@ -406,16 +390,13 @@ class nsTSubstring_CharT
// non-constant char array variable. Use AssignASCII for those. // non-constant char array variable. Use AssignASCII for those.
// There are not fallible version of these methods because they only really // There are not fallible version of these methods because they only really
// apply to small allocations that we wouldn't want to check anyway. // apply to small allocations that we wouldn't want to check anyway.
#ifdef NS_DISABLE_LITERAL_TEMPLATE template<int N>
void AssignLiteral( const char* str ) void AssignLiteral( const char_type (&str)[N] )
{ AssignASCII(str); } { AssignLiteral(str, N - 1); }
#else #ifdef CharT_is_PRUnichar
template<int N> template<int N>
void AssignLiteral( const char (&str)[N] ) void AssignLiteral( const char (&str)[N] )
{ AssignASCII(str, N-1); } { AssignASCII(str, N-1); }
template<int N>
void AssignLiteral( char (&str)[N] )
{ AssignASCII(str, N-1); }
#endif #endif
self_type& operator=( char_type c ) { Assign(c); return *this; } self_type& operator=( char_type c ) { Assign(c); return *this; }
@ -440,6 +421,12 @@ class nsTSubstring_CharT
void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) ); void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
// ReplaceLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use Replace or ReplaceASCII for those.
template<int N>
void ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type (&str)[N] ) { ReplaceLiteral(cutStart, cutLength, str, N - 1); }
void Append( char_type c ) { Replace(mLength, 0, c); } void Append( char_type c ) { Replace(mLength, 0, c); }
void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); } void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
@ -496,17 +483,13 @@ class nsTSubstring_CharT
// AppendLiteral must ONLY be applied to an actual literal string. // AppendLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char // Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use AppendASCII for those. // array variable. Use Append or AppendASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE template<int N>
void AppendLiteral( const char* str ) void AppendLiteral( const char_type (&str)[N] ) { ReplaceLiteral(mLength, 0, str, N - 1); }
{ AppendASCII(str); } #ifdef CharT_is_PRUnichar
#else
template<int N> template<int N>
void AppendLiteral( const char (&str)[N] ) void AppendLiteral( const char (&str)[N] )
{ AppendASCII(str, N-1); } { AppendASCII(str, N-1); }
template<int N>
void AppendLiteral( char (&str)[N] )
{ AppendASCII(str, N-1); }
#endif #endif
self_type& operator+=( char_type c ) { Append(c); return *this; } self_type& operator+=( char_type c ) { Append(c); return *this; }
@ -526,6 +509,12 @@ class nsTSubstring_CharT
void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); } void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); } void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
// InsertLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use Insert for those.
template<int N>
void InsertLiteral( const char_type (&str)[N], index_type pos ) { ReplaceLiteral(pos, 0, str, N - 1); }
void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); } void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
@ -845,6 +834,9 @@ class nsTSubstring_CharT
mFlags = dataFlags | (mFlags & 0xFFFF0000); mFlags = dataFlags | (mFlags & 0xFFFF0000);
} }
void NS_FASTCALL AssignLiteral( const char_type* data, size_type length );
void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
static int AppendFunc( void* arg, const char* s, uint32_t len); static int AppendFunc( void* arg, const char* s, uint32_t len);
public: public:
@ -865,6 +857,7 @@ class nsTSubstring_CharT
F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
F_LITERAL = 1 << 5, // mData points to a string literal; F_TERMINATED will also be set
// class flags are in the upper 16-bits // class flags are in the upper 16-bits
F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString

Просмотреть файл

@ -17,6 +17,7 @@
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator #define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
#define nsTDependentString_CharT nsDependentCString #define nsTDependentString_CharT nsDependentCString
#define nsTDependentSubstring_CharT nsDependentCSubstring #define nsTDependentSubstring_CharT nsDependentCSubstring
#define nsTLiteralString_CharT nsLiteralCString
#define nsTXPIDLString_CharT nsXPIDLCString #define nsTXPIDLString_CharT nsXPIDLCString
#define nsTGetterCopies_CharT nsCGetterCopies #define nsTGetterCopies_CharT nsCGetterCopies
#define nsTAdoptingString_CharT nsAdoptingCString #define nsTAdoptingString_CharT nsAdoptingCString

Просмотреть файл

@ -17,6 +17,7 @@
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator #define nsTDefaultStringComparator_CharT nsDefaultStringComparator
#define nsTDependentString_CharT nsDependentString #define nsTDependentString_CharT nsDependentString
#define nsTDependentSubstring_CharT nsDependentSubstring #define nsTDependentSubstring_CharT nsDependentSubstring
#define nsTLiteralString_CharT nsLiteralString
#define nsTXPIDLString_CharT nsXPIDLString #define nsTXPIDLString_CharT nsXPIDLString
#define nsTGetterCopies_CharT nsGetterCopies #define nsTGetterCopies_CharT nsGetterCopies
#define nsTAdoptingString_CharT nsAdoptingString #define nsTAdoptingString_CharT nsAdoptingString

Просмотреть файл

@ -18,6 +18,7 @@
#undef nsTDefaultStringComparator_CharT #undef nsTDefaultStringComparator_CharT
#undef nsTDependentString_CharT #undef nsTDependentString_CharT
#undef nsTDependentSubstring_CharT #undef nsTDependentSubstring_CharT
#undef nsTLiteralString_CharT
#undef nsTXPIDLString_CharT #undef nsTXPIDLString_CharT
#undef nsTGetterCopies_CharT #undef nsTGetterCopies_CharT
#undef nsTAdoptingString_CharT #undef nsTAdoptingString_CharT

Просмотреть файл

@ -7,6 +7,8 @@
void void
nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos ) nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
{ {
NS_ABORT_IF_FALSE(str.Flags() & F_TERMINATED, "Unterminated flat string");
// If we currently own a buffer, release it. // If we currently own a buffer, release it.
Finalize(); Finalize();
@ -18,5 +20,5 @@ nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos; mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
mLength = strLength - startPos; mLength = strLength - startPos;
SetDataFlags(F_TERMINATED); SetDataFlags(str.Flags() & (F_TERMINATED | F_LITERAL));
} }

Просмотреть файл

@ -11,7 +11,8 @@ nsTPromiseFlatString_CharT::Init(const substring_type& str)
{ {
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data())); mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data()));
mLength = str.Length(); mLength = str.Length();
mFlags = F_TERMINATED; // does not promote F_VOIDED mFlags = str.mFlags & (F_TERMINATED | F_LITERAL);
// does not promote F_VOIDED
} }
else else
{ {

Просмотреть файл

@ -351,6 +351,15 @@ nsTSubstring_CharT::AssignASCII( const char* data, size_type length, const falli
return true; return true;
} }
void
nsTSubstring_CharT::AssignLiteral( const char_type* data, size_type length )
{
::ReleaseData(mData, mFlags);
mData = const_cast<char_type*>(data);
mLength = length;
SetDataFlags(F_TERMINATED | F_LITERAL);
}
void void
nsTSubstring_CharT::Assign( const self_type& str ) nsTSubstring_CharT::Assign( const self_type& str )
{ {
@ -391,6 +400,13 @@ nsTSubstring_CharT::Assign( const self_type& str, const fallible_t& )
nsStringBuffer::FromData(mData)->AddRef(); nsStringBuffer::FromData(mData)->AddRef();
return true; return true;
} }
else if (str.mFlags & F_LITERAL)
{
NS_ABORT_IF_FALSE(str.mFlags & F_TERMINATED, "Unterminated literal");
AssignLiteral(str.mData, str.mLength);
return true;
}
// else, treat this like an ordinary assignment. // else, treat this like an ordinary assignment.
return Assign(str.Data(), str.Length(), fallible_t()); return Assign(str.Data(), str.Length(), fallible_t());
@ -536,6 +552,17 @@ nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const sub
tuple.WriteTo(mData + cutStart, length); tuple.WriteTo(mData + cutStart, length);
} }
void
nsTSubstring_CharT::ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
{
cutStart = XPCOM_MIN(cutStart, Length());
if (!cutStart && cutLength == Length())
AssignLiteral(data, length);
else if (ReplacePrep(cutStart, cutLength, length) && length > 0)
char_traits::copy(mData + cutStart, data, length);
}
void void
nsTSubstring_CharT::SetCapacity( size_type capacity ) nsTSubstring_CharT::SetCapacity( size_type capacity )
{ {

Просмотреть файл

@ -17,7 +17,7 @@ interface nsIGeolocationPrompt;
* Interface provides a way for a geolocation provider to * Interface provides a way for a geolocation provider to
* notify the system that a new location is available. * notify the system that a new location is available.
*/ */
[scriptable, uuid(f00ff730-acff-4e8c-9991-0d4c84ba0e10)] [scriptable, uuid(643dc5e9-b911-4b2c-8d44-603162696baf)]
interface nsIGeolocationUpdate : nsISupports { interface nsIGeolocationUpdate : nsISupports {
/** /**
@ -27,6 +27,13 @@ interface nsIGeolocationUpdate : nsISupports {
*/ */
void update(in nsIDOMGeoPosition position); void update(in nsIDOMGeoPosition position);
/**
* Notify the geolocation service that the location has
* potentially changed, and thus a new position is in the
* process of being acquired.
*/
void locationUpdatePending();
/** /**
* Notify the geolocation service of an error. * Notify the geolocation service of an error.
* This must be called on the main thread. * This must be called on the main thread.

Просмотреть файл

@ -462,6 +462,17 @@ LazyIdleThread::ProcessNextEvent(bool aMayWait,
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
NS_IMETHODIMP
LazyIdleThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (mThread) {
return mThread->GetIsProcessingEvents(aIsProcessing);
}
*aIsProcessing = false;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
LazyIdleThread::Notify(nsITimer* aTimer) LazyIdleThread::Notify(nsITimer* aTimer)
{ {

Просмотреть файл

@ -17,7 +17,7 @@
* *
* See nsIThreadManager for the API used to create and locate threads. * See nsIThreadManager for the API used to create and locate threads.
*/ */
[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)] [scriptable, uuid(4df07d3a-e759-4256-ba4e-7e2265354ec3)]
interface nsIThread : nsIEventTarget interface nsIThread : nsIEventTarget
{ {
/** /**
@ -82,4 +82,10 @@ interface nsIThread : nsIEventTarget
* not the current thread. * not the current thread.
*/ */
boolean processNextEvent(in boolean mayWait); boolean processNextEvent(in boolean mayWait);
/**
* true if we're processing runnables or thread observers and if this is the
* current thread.
*/
readonly attribute boolean isProcessingEvents;
}; };

Просмотреть файл

@ -304,6 +304,7 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize)
, mThread(nullptr) , mThread(nullptr)
, mRunningEvent(0) , mRunningEvent(0)
, mStackSize(aStackSize) , mStackSize(aStackSize)
, mProcessingEvent(0)
, mShutdownContext(nullptr) , mShutdownContext(nullptr)
, mShutdownRequired(false) , mShutdownRequired(false)
, mEventsAreDoomed(false) , mEventsAreDoomed(false)
@ -596,6 +597,8 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
} }
} }
++mProcessingEvent;
bool notifyMainThreadObserver = bool notifyMainThreadObserver =
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver; (MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
if (notifyMainThreadObserver) if (notifyMainThreadObserver)
@ -650,9 +653,22 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
if (notifyMainThreadObserver && sMainThreadObserver) if (notifyMainThreadObserver && sMainThreadObserver)
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result); sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);
--mProcessingEvent;
return rv; return rv;
} }
NS_IMETHODIMP
nsThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
return NS_ERROR_NOT_SAME_THREAD;
}
*aIsProcessing = mProcessingEvent != 0;
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsISupportsPriority // nsISupportsPriority

Просмотреть файл

@ -150,6 +150,8 @@ protected:
uint32_t mRunningEvent; // counter uint32_t mRunningEvent; // counter
uint32_t mStackSize; uint32_t mStackSize;
uint32_t mProcessingEvent;
struct nsThreadShutdownContext *mShutdownContext; struct nsThreadShutdownContext *mShutdownContext;
bool mShutdownRequired; bool mShutdownRequired;