Bug 725095 - Merge off-main-thread compositor from Maple. IGNORE BAD COMMIT MESSAGES

This commit is contained in:
Kartikaya Gupta 2012-03-14 11:18:15 -04:00
commit a96a6f4142
240 changed files with 3620 additions and 10691 deletions

View File

@ -78,3 +78,4 @@ bbc7014db2de49e2301680d2a86be8a53108a88a AURORA_BASE_20120131
0000000000000000000000000000000000000000 AURORA_BASE_20120131
0000000000000000000000000000000000000000 AURORA_BASE_20120131
bbc7014db2de49e2301680d2a86be8a53108a88a AURORA_BASE_20120131
b6627f28b7ec17e1b46a594df0f780d3a40847e4 FIREFOX_AURORA_13_BASE

View File

@ -41,6 +41,9 @@
#include "nsAccessible.h"
#include "mozilla/dom/Element.h"
#include "nsBindingManager.h"
using namespace mozilla;
////////////////////////////////////////////////////////////////////////////////
// AccIterator
@ -129,17 +132,21 @@ RelatedAccIterator::Next()
// Return related accessible for the given attribute and if the provider
// content is in the same binding in the case of XBL usage.
if (provider->mRelAttr == mRelAttr &&
(!mBindingParent ||
mBindingParent == provider->mContent->GetBindingParent())) {
nsAccessible* related = mDocument->GetAccessible(provider->mContent);
if (related)
return related;
if (provider->mRelAttr == mRelAttr) {
nsIContent* bindingParent = provider->mContent->GetBindingParent();
bool inScope = mBindingParent == bindingParent ||
mBindingParent == provider->mContent;
// If the document content is pointed by relation then return the document
// itself.
if (provider->mContent == mDocument->GetContent())
return mDocument;
if (inScope) {
nsAccessible* related = mDocument->GetAccessible(provider->mContent);
if (related)
return related;
// If the document content is pointed by relation then return the document
// itself.
if (provider->mContent == mDocument->GetContent())
return mDocument;
}
}
}
@ -271,18 +278,10 @@ XULDescriptionIterator::Next()
////////////////////////////////////////////////////////////////////////////////
IDRefsIterator::IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr) :
mCurrIdx(0)
mCurrIdx(0), mContent(aContent)
{
if (!aContent->IsInDoc() ||
!aContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs))
return;
if (aContent->IsInAnonymousSubtree()) {
mXBLDocument = do_QueryInterface(aContent->OwnerDoc());
mBindingParent = do_QueryInterface(aContent->GetBindingParent());
} else {
mDocument = aContent->OwnerDoc();
}
if (mContent->IsInDoc())
mContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
}
const nsDependentSubstring
@ -324,20 +323,45 @@ IDRefsIterator::NextElem()
nsIContent*
IDRefsIterator::GetElem(const nsDependentSubstring& aID)
{
if (mXBLDocument) {
// If content is anonymous subtree then use "anonid" attribute to get
// elements, otherwise search elements in DOM by ID attribute.
nsCOMPtr<nsIDOMElement> refElm;
mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
NS_LITERAL_STRING("anonid"),
aID,
getter_AddRefs(refElm));
nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
return refContent;
// Get elements in DOM tree by ID attribute if this is an explicit content.
// In case of bound element check its anonymous subtree.
if (!mContent->IsInAnonymousSubtree()) {
dom::Element* refElm = mContent->OwnerDoc()->GetElementById(aID);
if (refElm || !mContent->OwnerDoc()->BindingManager()->GetBinding(mContent))
return refElm;
}
return mDocument->GetElementById(aID);
// If content is in anonymous subtree or an element having anonymous subtree
// then use "anonid" attribute to get elements in anonymous subtree.
nsCOMPtr<nsIDOMElement> refDOMElm;
nsCOMPtr<nsIDOMDocumentXBL> xblDocument =
do_QueryInterface(mContent->OwnerDoc());
// Check inside the binding the element is contained in.
nsIContent* bindingParent = mContent->GetBindingParent();
if (bindingParent) {
nsCOMPtr<nsIDOMElement> bindingParentElm = do_QueryInterface(bindingParent);
xblDocument->GetAnonymousElementByAttribute(bindingParentElm,
NS_LITERAL_STRING("anonid"),
aID,
getter_AddRefs(refDOMElm));
nsCOMPtr<dom::Element> refElm = do_QueryInterface(refDOMElm);
if (refElm)
return refElm;
}
// Check inside the binding of the element.
if (mContent->OwnerDoc()->BindingManager()->GetBinding(mContent)) {
nsCOMPtr<nsIDOMElement> elm = do_QueryInterface(mContent);
xblDocument->GetAnonymousElementByAttribute(elm,
NS_LITERAL_STRING("anonid"),
aID,
getter_AddRefs(refDOMElm));
nsCOMPtr<dom::Element> refElm = do_QueryInterface(refDOMElm);
return refElm;
}
return nsnull;
}
nsAccessible*

View File

@ -291,11 +291,8 @@ private:
IDRefsIterator operator = (const IDRefsIterator&);
nsString mIDs;
nsIContent* mContent;
nsAString::index_type mCurrIdx;
nsIDocument* mDocument;
nsCOMPtr<nsIDOMDocumentXBL> mXBLDocument;
nsCOMPtr<nsIDOMElement> mBindingParent;
};
/**

View File

@ -54,13 +54,6 @@
using namespace mozilla::a11y;
enum {
IA2AlphaShift = 24,
IA2RedShift = 16,
IA2GreenShift = 8,
IA2BlueShift = 0
};
// IUnknown
STDMETHODIMP
@ -130,110 +123,40 @@ __try {
}
STDMETHODIMP
CAccessibleComponent::get_foreground(IA2Color *aForeground)
CAccessibleComponent::get_foreground(IA2Color* aForeground)
{
__try {
return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("color"), aForeground);
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
if (acc->IsDefunct())
return E_FAIL;
nsIFrame* frame = acc->GetFrame();
if (frame)
*aForeground = frame->GetStyleColor()->mColor;
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
STDMETHODIMP
CAccessibleComponent::get_background(IA2Color *aBackground)
CAccessibleComponent::get_background(IA2Color* aBackground)
{
__try {
return GetARGBValueFromCSSProperty(NS_LITERAL_STRING("background-color"),
aBackground);
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
HRESULT
CAccessibleComponent::GetARGBValueFromCSSProperty(const nsAString& aPropName,
IA2Color *aColorValue)
{
__try {
*aColorValue = 0;
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
if (acc->IsDefunct())
return E_FAIL;
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
nsWinUtils::GetComputedStyleDeclaration(acc->GetContent());
NS_ENSURE_STATE(styleDecl);
nsIFrame* frame = acc->GetFrame();
if (frame)
*aBackground = frame->GetStyleBackground()->mBackgroundColor;
nsCOMPtr<nsIDOMCSSValue> cssGenericValue;
styleDecl->GetPropertyCSSValue(aPropName, getter_AddRefs(cssGenericValue));
nsCOMPtr<nsIDOMCSSPrimitiveValue> cssValue =
do_QueryInterface(cssGenericValue);
if (!cssValue)
return E_FAIL;
nsCOMPtr<nsIDOMRGBColor> rgbColor;
nsresult rv = cssValue->GetRGBColorValue(getter_AddRefs(rgbColor));
if (NS_FAILED(rv) || !rgbColor)
return GetHRESULT(rv);
nsCOMPtr<nsIDOMNSRGBAColor> rgbaColor(do_QueryInterface(rgbColor));
if (!rgbaColor)
return GetHRESULT(rv);
// get alpha
nsCOMPtr<nsIDOMCSSPrimitiveValue> alphaValue;
rv = rgbaColor->GetAlpha(getter_AddRefs(alphaValue));
if (NS_FAILED(rv) || !alphaValue)
return GetHRESULT(rv);
float alpha = 0.0;
rv = alphaValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &alpha);
if (NS_FAILED(rv))
return GetHRESULT(rv);
// get red
nsCOMPtr<nsIDOMCSSPrimitiveValue> redValue;
rv = rgbaColor->GetRed(getter_AddRefs(redValue));
if (NS_FAILED(rv) || !redValue)
return GetHRESULT(rv);
float red = 0.0;
rv = redValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &red);
if (NS_FAILED(rv))
return GetHRESULT(rv);
// get green
nsCOMPtr<nsIDOMCSSPrimitiveValue> greenValue;
rv = rgbaColor->GetGreen(getter_AddRefs(greenValue));
if (NS_FAILED(rv) || !greenValue)
return GetHRESULT(rv);
float green = 0.0;
rv = greenValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &green);
if (NS_FAILED(rv))
return GetHRESULT(rv);
// get blue
nsCOMPtr<nsIDOMCSSPrimitiveValue> blueValue;
rv = rgbaColor->GetBlue(getter_AddRefs(blueValue));
if (NS_FAILED(rv) || !blueValue)
return GetHRESULT(rv);
float blue = 0.0;
rv = blueValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_NUMBER, &blue);
if (NS_FAILED(rv))
return GetHRESULT(rv);
// compose ARGB value
*aColorValue = (((IA2Color) blue) << IA2BlueShift) |
(((IA2Color) green) << IA2GreenShift) |
(((IA2Color) red) << IA2RedShift) |
(((IA2Color) (alpha * 0xff)) << IA2AlphaShift);
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}

View File

@ -65,14 +65,6 @@ public:
// nsISupports
NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
protected:
/**
* Return ARGB value for CSS property like 'color' or 'background-color'.
*/
HRESULT GetARGBValueFromCSSProperty(const nsAString& aPropName,
IA2Color *aColorValue);
};
#endif

View File

@ -78,7 +78,7 @@ function testRelation(aIdentifier, aRelType, aRelatedIdentifiers)
}
}
ok(isFound, relatedIds[idx] + " is not a target of" + relDescr);
ok(isFound, prettyName(relatedIds[idx]) + " is not a target of" + relDescr);
}
// Check if all obtained targets are given related accessibles.

View File

@ -46,11 +46,13 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_bindings.xhtml \
test_embeds.xul \
test_general.html \
test_general.xul \
test_tabbrowser.xul \
test_tree.xul \
test_ui_modalprompt.html \
test_update.html \
$(NULL)

View File

@ -0,0 +1,103 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Accessible relations for bindings</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
.button {
-moz-binding: url('#custombutton');
}
.button2 {
-moz-binding: url('#custombutton2');
}
</style>
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="custombutton">
<content aria-labelledby="button.label label">
<label xmlns="http://www.w3.org/1999/xhtml" anonid="button.label">
anon label
</label>
<button xmlns="http://www.w3.org/1999/xhtml" anonid="button.button"
aria-labelledby="button.label label">
a button
</button>
<div xmlns="http://www.w3.org/1999/xhtml"
anonid="button.button2" class="button2"
aria-labelledby="button.label"></div>
<div xmlns="http://www.w3.org/1999/xhtml"
anonid="button.button3" class="button2"></div>
</content>
</binding>
<binding id="custombutton2">
<content aria-labelledby="button2.label">
<label xmlns="http://www.w3.org/1999/xhtml" anonid="button2.label">
nested anon label
</label>
</content>
</binding>
</bindings>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../relations.js"></script>
<script type="application/javascript">
function doTests()
{
var button = document.getElementById("button");
var anonLabel = document.
getAnonymousElementByAttribute(button, "anonid", "button.label");
var anonButton = document.
getAnonymousElementByAttribute(button, "anonid", "button.button");
var anonButton2 = document.
getAnonymousElementByAttribute(button, "anonid", "button.button2");
var anonButton3 = document.
getAnonymousElementByAttribute(button, "anonid", "button.button3");
var anonAnonLabel = document.
getAnonymousElementByAttribute(anonButton3, "anonid", "button2.label");
testRelation("label", RELATION_LABEL_FOR, button);
testRelation(anonLabel, RELATION_LABEL_FOR, [button, anonButton, anonButton2]);
testRelation(button, RELATION_LABELLED_BY, [anonLabel, "label"]);
testRelation(anonButton, RELATION_LABELLED_BY, anonLabel);
testRelation(anonButton2, RELATION_LABELLED_BY, anonLabel);
testRelation(anonButton3, RELATION_LABELLED_BY, anonAnonLabel);
testRelation(anonAnonLabel, RELATION_LABEL_FOR, anonButton3);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=421242"
title="Allow relations in anonymous content for binding parent">
Mozilla Bug 421242
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="eventdump"></div>
<label id="label">explicit label</label>
<div id="button" class="button"></div>
</body>
</html>

View File

@ -0,0 +1,95 @@
<html>
<head>
<title>Modal prompts</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../relations.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript"
src="../browser.js"></script>
<script type="application/javascript">
function showAlert()
{
this.eventSeq = [
{
type: EVENT_SHOW,
match: function(aEvent)
{
return aEvent.accessible.role == ROLE_DIALOG;
}
}
];
this.invoke = function showAlert_invoke()
{
window.setTimeout(
function()
{
currentTabDocument().defaultView.alert("hello");
}, 0);
}
this.check = function showAlert_finalCheck(aEvent)
{
var dialog = aEvent.accessible.DOMNode;
var info = dialog.ui.infoBody;
testRelation(info, RELATION_DESCRIPTION_FOR, dialog);
testRelation(dialog, RELATION_DESCRIBED_BY, info);
}
this.getID = function showAlert_getID()
{
return "show alert";
}
}
//gA11yEventDumpToConsole = true; // debug
var gQueue = null;
function doTests()
{
gQueue = new eventQueue();
gQueue.push(new showAlert());
gQueue.onFinish = function()
{
synthesizeKey("VK_RETURN", {}, browserWindow());
closeBrowserWindow();
}
gQueue.invoke(); // will call SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
openBrowserWindow(doTests);
</script>
</head>
<body id="body">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=661293"
title="The tabmodalprompt dialog's prompt label doesn't get the text properly associated for accessibility">
Mozilla Bug 661293
</a>
<br>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -2,41 +2,33 @@ function test() {
waitForExplicitFinish();
var pageInfo;
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function () {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
pageInfo = BrowserPageInfo();
gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
Services.obs.addObserver(observer, "page-info-dialog-loaded", false);
pageInfo = BrowserPageInfo();
}, true);
content.location =
"https://example.com/browser/browser/base/content/test/feed_tab.html";
function observer(win, topic, data) {
if (topic != "page-info-dialog-loaded")
return;
Services.obs.removeObserver(observer, topic);
Services.obs.removeObserver(observer, "page-info-dialog-loaded");
handlePageInfo();
}
function $(aId) { return pageInfo.document.getElementById(aId) };
function handlePageInfo() {
var feedTab = $("feedTab");
var feedListbox = $("feedListbox");
ok(feedListbox, "Feed list is null (feeds tab is broken)");
ok(pageInfo.document.getElementById("feedTab"), "Feed tab");
let feedListbox = pageInfo.document.getElementById("feedListbox");
ok(feedListbox, "Feed list");
var feedRowsNum = feedListbox.getRowCount();
ok(feedRowsNum == 3, "Number of feeds listed: " +
feedRowsNum + ", should be 3");
is(feedRowsNum, 3, "Number of feeds listed");
for (var i = 0; i < feedRowsNum; i++) {
let feedItem = feedListbox.getItemAtIndex(i);
ok(feedItem.getAttribute("name") == (i+1),
"Name given: " + feedItem.getAttribute("name") + ", should be " + (i+1));
is(feedItem.getAttribute("name"), i + 1, "Feed name");
}
pageInfo.close();

View File

@ -1 +1 @@
13.0a1
14.0a1

View File

@ -66,6 +66,21 @@
-moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
}
#navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme),
#navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme) {
border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
}
#navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme):not([focused]):hover,
#navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme):not([focused]):hover {
border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
}
#navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme)[focused],
#navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme)[focused] {
border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
}
#sidebar-splitter {
border: 0;
-moz-border-end: 1px solid #A9B7C9;

View File

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
13.0a1
14.0a1

View File

@ -276,12 +276,13 @@ var TestRequests = [
// Aborted requests.
new AbortedRequest(false),
new AbortedRequest(true, -1),
new AbortedRequest(true, 0),
new AbortedRequest(true, 1000),
new AbortedRequest(true, 5000),
];
var MainThreadTestRequests = [
new AbortedRequest(true, 0),
new AbortedRequest(true, 1000),
// Synchronous requests.
SyncRequestSettingTimeoutAfterOpen,
SyncRequestSettingTimeoutBeforeOpen

View File

@ -326,10 +326,48 @@ is(e.view, window, "view should be window");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
// UIEvent
// StorageEvent
try {
e = new UIEvent();
e = new StorageEvent();
} catch(exp) {
ex = true;
}
ok(ex, "First parameter is required!");
ex = false;
e = new StorageEvent("hello");
ok(e.type, "hello", "Wrong event type!");
ok(!e.isTrusted, "Event shouldn't be trusted!");
ok(!e.bubbles, "Event shouldn't bubble!");
ok(!e.cancelable, "Event shouldn't be cancelable!");
is(e.key, "", "key should be ''");
is(e.oldValue, null, "oldValue should be null");
is(e.newValue, null, "newValue should be null");
is(e.url, "", "url should be ''");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
e = new StorageEvent("hello",
{ bubbles: true, cancelable: true, key: "key",
oldValue: "oldValue", newValue: "newValue", url: "url",
storageArea: localStorage });
ok(e.type, "hello", "Wrong event type!");
ok(!e.isTrusted, "Event shouldn't be trusted!");
ok(e.bubbles, "Event should bubble!");
ok(e.cancelable, "Event should be cancelable!");
is(e.key, "key", "Wrong value");
is(e.oldValue, "oldValue", "Wrong value");
is(e.newValue, "newValue", "Wrong value");
is(e.url, "url", "Wrong value");
is(e.storageArea, localStorage, "Wrong value");
document.dispatchEvent(e);
is(receivedEvent, e, "Wrong event!");
// MouseEvent
try {
e = new MouseEvent();
} catch(exp) {
ex = true;
}

View File

@ -567,6 +567,13 @@ Navigator::JavaEnabled(bool* aReturn)
return NS_OK;
}
NS_IMETHODIMP
Navigator::TaintEnabled(bool *aReturn)
{
*aReturn = false;
return NS_OK;
}
void
Navigator::RefreshMIMEArray()
{

View File

@ -1422,9 +1422,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(GeoPositionCoords, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(GeoPositionAddress, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -4020,10 +4017,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionCoords)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(GeoPositionAddress, nsIDOMGeoPositionAddress)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionAddress)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
DOM_CLASSINFO_MAP_END

View File

@ -422,7 +422,6 @@ DOMCI_CLASS(MessageEvent)
DOMCI_CLASS(GeoGeolocation)
DOMCI_CLASS(GeoPosition)
DOMCI_CLASS(GeoPositionCoords)
DOMCI_CLASS(GeoPositionAddress)
DOMCI_CLASS(GeoPositionError)
DOMCI_CLASS(MozBatteryManager)

View File

@ -3161,6 +3161,44 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
if (cs) {
cs->LogStringMessage(msg.get());
}
NS_NAMED_MULTILINE_LITERAL_STRING(kJSONFmt,
NS_LL("{ \"duration\": %llu, ")
NS_LL("\"suspected\": %lu, ")
NS_LL("\"visited\": { ")
NS_LL("\"RCed\": %lu, ")
NS_LL("\"GCed\": %lu }, ")
NS_LL("\"collected\": { ")
NS_LL("\"RCed\": %lu, ")
NS_LL("\"GCed\": %lu }, ")
NS_LL("\"waiting_for_gc\": %lu, ")
NS_LL("\"forced_gc\": %d, ")
NS_LL("\"forget_skippable\": { ")
NS_LL("\"times_before_cc\": %lu, ")
NS_LL("\"min\": %lu, ")
NS_LL("\"max\": %lu, ")
NS_LL("\"avg\": %lu, ")
NS_LL("\"total\": %lu, ")
NS_LL("\"removed\": %lu } ")
NS_LL("}"));
nsString json;
json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(),
(now - start) / PR_USEC_PER_MSEC, suspected,
ccResults.mVisitedRefCounted, ccResults.mVisitedGCed,
ccResults.mFreedRefCounted, ccResults.mFreedGCed,
sCCollectedWaitingForGC,
ccResults.mForcedGC,
sForgetSkippableBeforeCC,
sMinForgetSkippableTime / PR_USEC_PER_MSEC,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC,
(sTotalForgetSkippableTime / cleanups) /
PR_USEC_PER_MSEC,
sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
sRemovedPurples));
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
if (observerService) {
observerService->NotifyObservers(nsnull, "cycle-collection-statistics", json.get());
}
}
sMinForgetSkippableTime = PR_UINT32_MAX;
sMaxForgetSkippableTime = 0;
@ -3417,12 +3455,39 @@ nsJSContext::GC(js::gcreason::Reason aReason)
PokeGC(aReason);
}
class NotifyGCEndRunnable : public nsRunnable
{
nsString mMessage;
public:
NotifyGCEndRunnable(const nsString& aMessage) : mMessage(aMessage) {}
NS_DECL_NSIRUNNABLE
};
NS_IMETHODIMP
NotifyGCEndRunnable::Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
if (!observerService) {
return NS_OK;
}
const jschar oomMsg[3] = { '{', '}', 0 };
const jschar *toSend = mMessage.get() ? mMessage.get() : oomMsg;
observerService->NotifyObservers(nsnull, "garbage-collection-statistics", toSend);
return NS_OK;
}
static void
DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescription &aDesc)
{
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
if (aDesc.logMessage && sPostGCEventsToConsole) {
if (aProgress == js::GC_CYCLE_END && sPostGCEventsToConsole) {
PRTime now = PR_Now();
PRTime delta = 0;
if (sFirstCollectionTime) {
@ -3432,10 +3497,11 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
}
NS_NAMED_LITERAL_STRING(kFmt, "GC(T+%.1f) %s");
nsString msg;
nsString msg, gcstats;
gcstats.Adopt(aDesc.formatMessage(aRt));
msg.Adopt(nsTextFormatter::smprintf(kFmt.get(),
double(delta) / PR_USEC_PER_SEC,
aDesc.logMessage));
gcstats.get()));
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(msg.get());
@ -3463,6 +3529,11 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
sCCollectedWaitingForGC = 0;
sCleanupSinceLastGC = false;
nsString json;
json.Adopt(aDesc.formatJSON(aRt));
nsRefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
NS_DispatchToMainThread(notify);
if (aDesc.isCompartment) {
// If this is a compartment GC, restart it. We still want
// a full GC to happen. Compartment GCs usually happen as a

View File

@ -53,7 +53,7 @@ nsWindowMemoryReporter::Init()
NS_RegisterMemoryMultiReporter(new nsWindowMemoryReporter());
}
static bool
static void
AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
{
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
@ -71,21 +71,19 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
}
}
if (!uri) {
return false;
if (uri) {
nsCString spec;
uri->GetSpec(spec);
// A hack: replace forward slashes with '\\' so they aren't
// treated as path separators. Users of the reporters
// (such as about:memory) have to undo this change.
spec.ReplaceChar('/', '\\');
aStr += spec;
} else {
aStr += NS_LITERAL_CSTRING("[system]");
}
nsCString spec;
uri->GetSpec(spec);
// A hack: replace forward slashes with '\\' so they aren't
// treated as path separators. Users of the reporters
// (such as about:memory) have to undo this change.
spec.ReplaceChar('/', '\\');
aStr += spec;
return true;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
@ -104,99 +102,68 @@ CollectWindowReports(nsGlobalWindow *aWindow,
// cached) yet held alive by either a website or our code. The
// latter case may be a memory leak, but not necessarily.
//
// For inner windows we show how much memory the window and its
// document etc use, and we report those per URI, where the URI is
// the document URI, if available, or the codebase of the principal
// in the window. In the case where we're unable to find a URI we're
// dealing with a chrome window with no document in it (or
// somesuch), and for that we make the URI be the string "[system]".
// For each window we show how much memory the window and its
// document, etc, use, and we report those per URI, where the URI is
// the document URI, if available, or the codebase of the principal in
// the window. In the case where we're unable to find a URI we're
// dealing with a chrome window with no document in it (or somesuch),
// and for that we make the URI be the string "[system]".
//
// For outer windows we simply group them all together and just show
// the combined count and amount of memory used, which is generally
// a constant amount per window (since all the actual data lives in
// the inner window).
// Outer windows are lumped in with inner windows, because the amount
// of memory used by outer windows is small.
//
// The path we give to the reporter callback for inner windows are
// as follows:
// The path we give to the reporter callback for "active" and "cached"
// windows (both inner and outer) is as follows:
//
// explicit/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
// explicit/window-objects/top(<top-outer-uri>, id=<top-outer-id>)/<category>/window(<window-uri>)/...
//
// The path we give for "other" windows is as follows:
//
// explicit/window-objects/top(none)/window(<window-uri>)/...
//
// Where:
// - <category> is active, cached, or other, as described above.
// - <category> is "active" or "cached", as described above.
// - <top-outer-id> is the window id (nsPIDOMWindow::WindowID()) of
// the top outer window (i.e. tab, or top level chrome window).
// - <top-inner-id> is the window id of the top window's inner
// window.
// - <id> is the window id of the inner window in question.
// - <uri> is the URI per above description.
// - <top-inner-uri> is the URI of the top outer window. Excepting
// special windows (such as browser.xul or hiddenWindow.html) it's
// what the address bar shows for the tab.
// - <window-uri> is the URI of aWindow.
//
// Exposing the window ids is done to get logical grouping in
// about:memory, and also for debuggability since one can get to the
// nsGlobalWindow for a window id by calling the static method
// nsGlobalWindow::GetInnerWindowWithId(id) (or
// GetOuterWindowWithId(id) in a debugger.
//
// For outer windows we simply use:
//
// explicit/window-objects/<category>/outer-windows
//
// Which gives us simple counts of how many outer windows (and their
// combined sizes) per category.
// Exposing the top-outer-id ensures that each tab gets its own
// sub-tree, even if multiple tabs are showing the same URI.
nsCAutoString windowPath("explicit/window-objects/");
nsIDocShell *docShell = aWindow->GetDocShell();
nsGlobalWindow *top = aWindow->GetTop();
nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
aWindow->SizeOfIncludingThis(&windowSizes);
if (docShell && aWindow->IsFrozen()) {
windowPath += NS_LITERAL_CSTRING("cached/");
} else if (docShell) {
windowPath += NS_LITERAL_CSTRING("active/");
windowPath += NS_LITERAL_CSTRING("top(");
if (top) {
AppendWindowURI(top, windowPath);
windowPath += NS_LITERAL_CSTRING(", id=");
windowPath.AppendInt(top->WindowID());
} else {
windowPath += NS_LITERAL_CSTRING("other/");
windowPath += NS_LITERAL_CSTRING("none");
}
windowPath += NS_LITERAL_CSTRING(")/");
nsIDocShell *docShell = aWindow->GetDocShell();
if (docShell) {
MOZ_ASSERT(top, "'cached' or 'active' window lacks a top window");
windowPath += aWindow->IsFrozen() ? NS_LITERAL_CSTRING("cached/")
: NS_LITERAL_CSTRING("active/");
} else {
MOZ_ASSERT(!top, "'other' window has a top window");
}
if (aWindow->IsInnerWindow()) {
windowPath += NS_LITERAL_CSTRING("top=");
windowPath += NS_LITERAL_CSTRING("window(");
AppendWindowURI(aWindow, windowPath);
windowPath += NS_LITERAL_CSTRING(")");
if (top) {
windowPath.AppendInt(top->WindowID());
nsGlobalWindow *topInner = top->GetCurrentInnerWindowInternal();
if (topInner) {
windowPath += NS_LITERAL_CSTRING(" (inner=");
windowPath.AppendInt(topInner->WindowID());
windowPath += NS_LITERAL_CSTRING(")");
}
} else {
windowPath += NS_LITERAL_CSTRING("none");
}
windowPath += NS_LITERAL_CSTRING("/inner-window(id=");
windowPath.AppendInt(aWindow->WindowID());
windowPath += NS_LITERAL_CSTRING(", uri=");
if (!AppendWindowURI(aWindow, windowPath)) {
windowPath += NS_LITERAL_CSTRING("[system]");
}
windowPath += NS_LITERAL_CSTRING(")");
} else {
// Combine all outer windows per section (active/cached/other) as
// they basically never contain anything of interest, and are
// always pretty much the same size.
windowPath += NS_LITERAL_CSTRING("outer-windows");
}
#define REPORT(_path1, _path2, _amount, _desc) \
#define REPORT(_pathTail, _amount, _desc) \
do { \
if (_amount > 0) { \
nsCAutoString path(_path1); \
path += _path2; \
nsCAutoString path(windowPath); \
path += _pathTail; \
nsresult rv; \
rv = aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP,\
nsIMemoryReporter::UNITS_BYTES, _amount, \
@ -205,24 +172,27 @@ CollectWindowReports(nsGlobalWindow *aWindow,
} \
} while (0)
REPORT(windowPath, "/dom", windowSizes.mDOM,
nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
aWindow->SizeOfIncludingThis(&windowSizes);
REPORT("/dom", windowSizes.mDOM,
"Memory used by a window and the DOM within it.");
aWindowTotalSizes->mDOM += windowSizes.mDOM;
REPORT(windowPath, "/style-sheets", windowSizes.mStyleSheets,
REPORT("/style-sheets", windowSizes.mStyleSheets,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
REPORT(windowPath, "/layout/arenas", windowSizes.mLayoutArenas,
REPORT("/layout/arenas", windowSizes.mLayoutArenas,
"Memory used by layout PresShell, PresContext, and other related "
"areas within a window.");
aWindowTotalSizes->mLayoutArenas += windowSizes.mLayoutArenas;
REPORT(windowPath, "/layout/style-sets", windowSizes.mLayoutStyleSets,
REPORT("/layout/style-sets", windowSizes.mLayoutStyleSets,
"Memory used by style sets within a window.");
aWindowTotalSizes->mLayoutStyleSets += windowSizes.mLayoutStyleSets;
REPORT(windowPath, "/layout/text-runs", windowSizes.mLayoutTextRuns,
REPORT("/layout/text-runs", windowSizes.mLayoutTextRuns,
"Memory used for text-runs (glyph layout) in the PresShell's frame "
"tree, within a window.");
aWindowTotalSizes->mLayoutTextRuns += windowSizes.mLayoutTextRuns;

View File

@ -25,7 +25,7 @@ const STORE_NAME = "contacts";
function ContactDB(aGlobal) {
debug("Constructor");
this._indexedDB = aGlobal.mozIndexedDB;
this._global = aGlobal;
}
ContactDB.prototype = {
@ -54,7 +54,7 @@ ContactDB.prototype = {
let self = this;
debug("try to open database:" + DB_NAME + " " + DB_VERSION);
let request = this._indexedDB.open(DB_NAME, DB_VERSION);
let request = this._global.mozIndexedDB.open(DB_NAME, DB_VERSION);
request.onsuccess = function (event) {
debug("Opened database:", DB_NAME, DB_VERSION);
self.db = event.target.result;
@ -116,6 +116,14 @@ ContactDB.prototype = {
objectStore.createIndex("email", "properties.email", { unique: false, multiEntry: true });
objectStore.createIndex("note", "properties.note", { unique: false, multiEntry: true });
objectStore.createIndex("nicknameLowerCase", "search.nickname", { unique: false, multiEntry: true });
objectStore.createIndex("nameLowerCase", "search.name", { unique: false, multiEntry: true });
objectStore.createIndex("familyNameLowerCase", "search.familyName", { unique: false, multiEntry: true });
objectStore.createIndex("givenNameLowerCase", "search.givenName", { unique: false, multiEntry: true });
objectStore.createIndex("telLowerCase", "search.tel", { unique: false, multiEntry: true });
objectStore.createIndex("emailLowerCase", "search.email", { unique: false, multiEntry: true });
objectStore.createIndex("noteLowerCase", "search.note", { unique: false, multiEntry: true });
debug("Created object stores and indexes");
},
@ -123,7 +131,7 @@ ContactDB.prototype = {
* Start a new transaction.
*
* @param txn_type
* Type of transaction (e.g. IDBTransaction.READ_WRITE)
* Type of transaction (e.g. "readwrite")
* @param callback
* Function to call when the transaction is available. It will
* be invoked with the transaction and the 'contacts' object store.
@ -171,7 +179,6 @@ ContactDB.prototype = {
}, failureCb);
},
// Todo: add searchfields. "Tom" should be a result with T, t, To, to...
makeImport: function makeImport(aContact) {
let contact = {};
contact.properties = {
@ -197,9 +204,33 @@ ContactDB.prototype = {
genderIdentity: null
};
contact.search = {
name: [],
honorificPrefix: [],
givenName: [],
additionalName: [],
familyName: [],
honorificSuffix: [],
nickname: [],
email: [],
category: [],
tel: [],
org: [],
note: [],
impp: []
};
for (let field in aContact.properties) {
contact.properties[field] = aContact.properties[field];
// Add search fields
if (aContact.properties[field] && contact.search[field]) {
for (let i = 0; i <= aContact.properties[field].length; i++) {
if (aContact.properties[field][i])
contact.search[field].push(aContact.properties[field][i].toLowerCase());
}
}
}
debug("contact:" + JSON.stringify(contact));
contact.updated = aContact.updated;
contact.published = aContact.published;
@ -208,7 +239,6 @@ ContactDB.prototype = {
return contact;
},
// Needed to remove searchfields
makeExport: function makeExport(aRecord) {
let contact = {};
contact.properties = aRecord.properties;
@ -234,7 +264,7 @@ ContactDB.prototype = {
saveContact: function saveContact(aContact, successCb, errorCb) {
let contact = this.makeImport(aContact);
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
this.newTxn("readwrite", function (txn, store) {
debug("Going to update" + JSON.stringify(contact));
// Look up the existing record and compare the update timestamp.
@ -263,14 +293,14 @@ ContactDB.prototype = {
},
removeContact: function removeContact(aId, aSuccessCb, aErrorCb) {
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
this.newTxn("readwrite", function (txn, store) {
debug("Going to delete" + aId);
store.delete(aId);
}, aSuccessCb, aErrorCb);
},
clear: function clear(aSuccessCb, aErrorCb) {
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
this.newTxn("readwrite", function (txn, store) {
debug("Going to clear all!");
store.clear();
}, aSuccessCb, aErrorCb);
@ -297,11 +327,9 @@ ContactDB.prototype = {
debug("ContactDB:find val:" + aOptions.filterValue + " by: " + aOptions.filterBy + " op: " + aOptions.filterOp + "\n");
let self = this;
this.newTxn(Ci.nsIIDBTransaction.READ_ONLY, function (txn, store) {
if (aOptions && aOptions.filterOp == "equals") {
this.newTxn("readonly", function (txn, store) {
if (aOptions && (aOptions.filterOp == "equals" || aOptions.filterOp == "contains")) {
self._findWithIndex(txn, store, aOptions);
} else if (aOptions && aOptions.filterBy) {
self._findWithSearch(txn, store, aOptions);
} else {
self._findAll(txn, store, aOptions);
}
@ -334,10 +362,17 @@ ContactDB.prototype = {
if (key == "id") {
// store.get would return an object and not an array
request = store.getAll(options.filterValue);
} else {
} else if (options.filterOp == "equals") {
debug("Getting index: " + key);
// case sensitive
let index = store.index(key);
request = index.getAll(options.filterValue, options.filterLimit);
} else {
// not case sensitive
let tmp = options.filterValue.toLowerCase();
let range = this._global.IDBKeyRange.bound(tmp, tmp + "\uFFFF");
let index = store.index(key + "LowerCase");
request = index.getAll(range, options.filterLimit);
}
if (!txn.result)
txn.result = {};
@ -350,52 +385,6 @@ ContactDB.prototype = {
}
},
// Will be replaced by _findWithIndex once all searchfields are added.
_findWithSearch: function _findWithSearch(txn, store, options) {
debug("_findWithSearch:" + options.filterValue + options.filterOp)
store.getAll().onsuccess = function (event) {
debug("Request successful." + event.target.result);
txn.result = event.target.result.filter(function (record) {
let properties = record.properties;
for (let i = 0; i < options.filterBy.length; i++) {
let field = options.filterBy[i];
if (!properties[field])
continue;
let value = '';
switch (field) {
case "name":
case "familyName":
case "givenName":
case "nickname":
case "email":
case "tel":
case "note":
value = [f for each (f in [properties[field]])].join("\n") || '';
break;
default:
value = properties[field];
debug("unknown field: " + field);
}
let match = false;
switch (options.filterOp) {
case "icontains":
match = value.toLowerCase().indexOf(options.filterValue.toLowerCase()) != -1;
break;
case "contains":
match = value.indexOf(options.filterValue) != -1;
break;
case "equals":
match = value == options.filterValue;
break
}
if (match)
return true;
}
return false;
}).map(this.makeExport.bind(this));
}.bind(this);
},
_findAll: function _findAll(txn, store, options) {
debug("ContactDB:_findAll: " + JSON.stringify(options));
if (!txn.result)

View File

@ -46,7 +46,7 @@ var adr2 = {
var properties1 = {
name: "Testname1",
familyName: "TestFamilyName",
familyName: ["TestFamilyName","Wagner"],
givenName: ["Test1","Test2"],
nickname: "nicktest",
tel: ["123456"],
@ -211,6 +211,66 @@ var steps = [
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving by substring");
var options = {filterBy: ["name"],
filterOp: "contains",
filterValue: properties1.name.substring(0,3)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving by substring2");
var options = {filterBy: ["givenName"],
filterOp: "contains",
filterValue: properties1.givenName[0].substring(0,3)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving by substring3");
var options = {filterBy: ["name", "givenName"],
filterOp: "contains",
filterValue: properties1.givenName[0].substring(0,3)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving by substring3, Testing multi entry");
var options = {filterBy: ["name", "givenName", "familyName"],
filterOp: "contains",
filterValue: properties1.familyName[1].substring(0,3).toLowerCase()};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({});
@ -306,7 +366,7 @@ var steps = [
function () {
ok(true, "Searching contacts by query");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterOp: "contains",
filterValue: properties1.name[0].substring(0,4)};
req = mozContacts.find(options);
req.onsuccess = function () {
@ -321,7 +381,7 @@ var steps = [
function () {
ok(true, "Searching contacts by query");
var options = {filterBy: ["nickname", "email"],
filterOp: "icontains",
filterOp: "contains",
filterValue: properties1.nickname};
req = mozContacts.find(options);
req.onsuccess = function () {
@ -429,7 +489,7 @@ var steps = [
function () {
console.log("Searching contacts by query1");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterOp: "contains",
filterValue: properties1.name[0].substring(0, 4)}
req = mozContacts.find(options)
req.onsuccess = function () {
@ -444,7 +504,7 @@ var steps = [
function () {
ok(true, "Searching contacts by query2");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterOp: "contains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find(options);
req.onsuccess = function () {
@ -538,9 +598,9 @@ var steps = [
function () {
ok(true, "Retrieving all contacts2");
var options = {filterBy: ["name"],
filterOp: "icontains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find({});
filterOp: "contains",
filterValue: properties1.name[0].substring(0, 4)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 100, "100 Entries.");
checkContacts(createResult1, req.result[99]);
@ -548,6 +608,20 @@ var steps = [
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts3");
var options = {filterBy: ["name", "givenName", "tel", "email", "note"],
filterOp: "contains",
filterValue: properties1.name[0].substring(0, 4),
filterLimit: 15 };
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 15, "15 Entries.");
checkContacts(createResult1, req.result[10]);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear();
@ -588,7 +662,7 @@ var steps = [
function () {
ok(true, "Retrieving all contacts");
var options = {filterBy: ["name"],
filterOp: "icontains",
filterOp: "contains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find({});
req.onsuccess = function () {

View File

@ -463,7 +463,7 @@ IDBCursor::GetDirection(nsAString& aDirection)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
switch(mDirection) {
switch (mDirection) {
case NEXT:
aDirection.AssignLiteral("next");
break;

View File

@ -532,7 +532,7 @@ IDBTransaction::GetMode(nsAString& aMode)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
switch(mMode) {
switch (mMode) {
case READ_ONLY:
aMode.AssignLiteral("readonly");
break;

View File

@ -39,7 +39,7 @@
#include "domstubs.idl"
[scriptable, uuid(e610c037-db58-4cd7-8ed3-0d7f1422b4d3)]
[scriptable, uuid(e0737ed5-89c5-4fe3-891e-a75bf3a1bb55)]
interface nsIDOMNavigator : nsISupports
{
readonly attribute DOMString appCodeName;
@ -62,6 +62,7 @@ interface nsIDOMNavigator : nsISupports
readonly attribute nsIDOMMozPowerManager mozPower;
boolean javaEnabled();
boolean taintEnabled();
/**
* Pulse the device's vibrator, if it has one. If the device does not have a

View File

@ -49,7 +49,6 @@ GRE_MODULE = 1
XPIDLSRCS = \
nsIDOMGeoGeolocation.idl \
nsIDOMGeoPosition.idl \
nsIDOMGeoPositionAddress.idl \
nsIDOMGeoPositionCoords.idl \
nsIDOMGeoPositionCallback.idl \
nsIDOMGeoPositionError.idl \

View File

@ -37,13 +37,10 @@
#include "domstubs.idl"
#include "nsIDOMGeoPositionCoords.idl"
#include "nsIDOMGeoPositionAddress.idl"
[scriptable, uuid(23E5269F-4DD7-41C4-B52A-75918694C2DE)]
[scriptable, uuid(dd9f7e81-0f74-4fb5-b361-37019bf60c3f)]
interface nsIDOMGeoPosition : nsISupports
{
readonly attribute DOMTimeStamp timestamp;
readonly attribute nsIDOMGeoPositionCoords coords;
readonly attribute nsIDOMGeoPositionAddress address;
};

View File

@ -753,6 +753,16 @@ ContentChild::RecvDeviceMotionChanged(const long int& type,
return true;
}
bool
ContentChild::RecvNeedsCalibration()
{
nsCOMPtr<nsIDeviceMotionUpdate> dmu =
do_GetService(NS_DEVICE_MOTION_CONTRACTID);
if (dmu)
dmu->NeedsCalibration();
return true;
}
bool
ContentChild::RecvScreenSizeChanged(const gfxIntSize& size)
{

View File

@ -162,6 +162,8 @@ public:
const double& x, const double& y,
const double& z);
virtual bool RecvNeedsCalibration();
virtual bool RecvScreenSizeChanged(const gfxIntSize &size);
virtual bool RecvFlushMemory(const nsString& reason);

View File

@ -1291,6 +1291,12 @@ ContentParent::OnMotionChange(nsIDeviceMotionData *aDeviceData) {
return NS_OK;
}
NS_IMETHODIMP
ContentParent::NeedsCalibration() {
unused << SendNeedsCalibration();
return NS_OK;
}
} // namespace dom
} // namespace mozilla

View File

@ -134,6 +134,7 @@ child:
AddPermission(Permission permission);
DeviceMotionChanged(long type, double x, double y, double z);
NeedsCalibration();
ScreenSizeChanged(gfxIntSize size);

View File

@ -40,100 +40,6 @@
#include "nsGeoPosition.h"
#include "nsDOMClassInfoID.h"
////////////////////////////////////////////////////
// nsGeoPositionAddress
////////////////////////////////////////////////////
nsGeoPositionAddress::nsGeoPositionAddress(const nsAString &aStreetNumber,
const nsAString &aStreet,
const nsAString &aPremises,
const nsAString &aCity,
const nsAString &aCounty,
const nsAString &aRegion,
const nsAString &aCountry,
const nsAString &aPostalCode)
: mStreetNumber(aStreetNumber)
, mStreet(aStreet)
, mPremises(aPremises)
, mCity(aCity)
, mCounty(aCounty)
, mRegion(aRegion)
, mCountry(aCountry)
, mPostalCode(aPostalCode)
{
}
nsGeoPositionAddress::~nsGeoPositionAddress()
{
}
DOMCI_DATA(GeoPositionAddress, nsGeoPositionAddress)
NS_INTERFACE_MAP_BEGIN(nsGeoPositionAddress)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPositionAddress)
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionAddress)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPositionAddress)
NS_INTERFACE_MAP_END
NS_IMPL_THREADSAFE_ADDREF(nsGeoPositionAddress)
NS_IMPL_THREADSAFE_RELEASE(nsGeoPositionAddress)
NS_IMETHODIMP
nsGeoPositionAddress::GetStreetNumber(nsAString & aStreetNumber)
{
aStreetNumber = mStreetNumber;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetStreet(nsAString & aStreet)
{
aStreet = mStreet;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetPremises(nsAString & aPremises)
{
aPremises = mPremises;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetCity(nsAString & aCity)
{
aCity = mCity;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetCounty(nsAString & aCounty)
{
aCounty = mCounty;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetRegion(nsAString & aRegion)
{
aRegion = mRegion;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetCountry(nsAString & aCountry)
{
aCountry = mCountry;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionAddress::GetPostalCode(nsAString & aPostalCode)
{
aPostalCode = mPostalCode;
return NS_OK;
}
////////////////////////////////////////////////////
// nsGeoPositionCoords
////////////////////////////////////////////////////
@ -239,11 +145,9 @@ nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
}
nsGeoPosition::nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
nsIDOMGeoPositionAddress *aAddress,
DOMTimeStamp aTimestamp) :
mTimestamp(aTimestamp),
mCoords(aCoords),
mAddress(aAddress)
mCoords(aCoords)
{
}
@ -275,11 +179,3 @@ nsGeoPosition::GetCoords(nsIDOMGeoPositionCoords * *aCoords)
NS_IF_ADDREF(*aCoords = mCoords);
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetAddress(nsIDOMGeoPositionAddress** aAddress)
{
NS_IF_ADDREF(*aAddress = mAddress);
return NS_OK;
}

View File

@ -43,42 +43,10 @@
#include "nsAutoPtr.h"
#include "nsIClassInfo.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMGeoPositionAddress.h"
#include "nsIDOMGeoPositionCoords.h"
#include "nsIDOMGeoPosition.h"
#include "nsString.h"
////////////////////////////////////////////////////
// nsGeoPositionAddress
////////////////////////////////////////////////////
class nsGeoPositionAddress : public nsIDOMGeoPositionAddress
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMGEOPOSITIONADDRESS
nsGeoPositionAddress( const nsAString &aStreetNumber,
const nsAString &aStreet,
const nsAString &aPremises,
const nsAString &aCity,
const nsAString &aCounty,
const nsAString &aRegion,
const nsAString &aCountry,
const nsAString &aPostalCode);
~nsGeoPositionAddress();
private:
const nsString mStreetNumber;
const nsString mStreet;
const nsString mPremises;
const nsString mCity;
const nsString mCounty;
const nsString mRegion;
const nsString mCountry;
const nsString mPostalCode;
};
////////////////////////////////////////////////////
// nsGeoPositionCoords
////////////////////////////////////////////////////
@ -122,18 +90,12 @@ public:
long long aTimestamp);
nsGeoPosition(nsIDOMGeoPositionCoords *aCoords,
nsIDOMGeoPositionAddress *aAddress,
DOMTimeStamp aTimestamp);
void SetAddress(nsIDOMGeoPositionAddress *address) {
mAddress = address;
}
private:
~nsGeoPosition();
long long mTimestamp;
nsRefPtr<nsIDOMGeoPositionCoords> mCoords;
nsRefPtr<nsIDOMGeoPositionAddress> mAddress;
};
#endif /* nsGeoPosition_h */

View File

@ -41,98 +41,11 @@
#include "nsGeoPosition.h"
#include "nsIDOMGeoPosition.h"
typedef nsIDOMGeoPositionAddress *GeoPositionAddress;
typedef nsGeoPositionCoords *GeoPositionCoords;
typedef nsIDOMGeoPosition *GeoPosition;
namespace IPC {
template <>
struct ParamTraits<GeoPositionAddress>
{
typedef GeoPositionAddress paramType;
// Function to serialize a geo position address
static void Write(Message *aMsg, const paramType& aParam)
{
bool isNull = !aParam;
WriteParam(aMsg, isNull);
// If it is null, then we are done
if (isNull) return;
nsString addressLine;
aParam->GetStreetNumber(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetStreet(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetPremises(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetCity(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetCounty(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetRegion(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetCountry(addressLine);
WriteParam(aMsg, addressLine);
aParam->GetPostalCode(addressLine);
WriteParam(aMsg, addressLine);
}
// Function to de-serialize a geoposition
static bool Read(const Message* aMsg, void **aIter, paramType* aResult)
{
// Check if it is the null pointer we have transfered
bool isNull;
if (!ReadParam(aMsg, aIter, &isNull)) return false;
if (isNull) {
*aResult = 0;
return true;
}
// We need somewhere to store the address before we create the object
nsString streetNumber;
nsString street;
nsString premises;
nsString city;
nsString county;
nsString region;
nsString country;
nsString postalCode;
// It's not important to us where it fails, but rather if it fails
if (!(ReadParam(aMsg, aIter, &streetNumber) &&
ReadParam(aMsg, aIter, &street ) &&
ReadParam(aMsg, aIter, &premises ) &&
ReadParam(aMsg, aIter, &city ) &&
ReadParam(aMsg, aIter, &county ) &&
ReadParam(aMsg, aIter, &region ) &&
ReadParam(aMsg, aIter, &country ) &&
ReadParam(aMsg, aIter, &postalCode ))) return false;
// We now have all the data
*aResult = new nsGeoPositionAddress(streetNumber, /* aStreetNumber */
street, /* aStreet */
premises, /* aPremises */
city, /* aCity */
county, /* aCounty */
region, /* aRegion */
country, /* aCountry */
postalCode /* aPostalCode */
);
return true;
}
} ;
template <>
struct ParamTraits<GeoPositionCoords>
{
@ -235,11 +148,6 @@ struct ParamTraits<GeoPosition>
aParam->GetCoords(getter_AddRefs(coords));
GeoPositionCoords simpleCoords = static_cast<GeoPositionCoords>(coords.get());
WriteParam(aMsg, simpleCoords);
nsCOMPtr<nsIDOMGeoPositionAddress> address;
aParam->GetAddress(getter_AddRefs(address));
GeoPositionAddress simpleAddress = address.get();
WriteParam(aMsg, simpleAddress);
}
// Function to de-serialize a geoposition
@ -256,20 +164,17 @@ struct ParamTraits<GeoPosition>
DOMTimeStamp timeStamp;
GeoPositionCoords coords = nsnull;
GeoPositionAddress address;
// It's not important to us where it fails, but rather if it fails
if (!( ReadParam(aMsg, aIter, &timeStamp)
&& ReadParam(aMsg, aIter, &coords )
&& ReadParam(aMsg, aIter, &address ))) {
&& ReadParam(aMsg, aIter, &coords ))) {
// note it is fine to do "delete nsnull" in case coords hasn't
// been allocated and we will never have a case where address
// gets allocated and we end here
// been allocated
delete coords;
return false;
}
*aResult = new nsGeoPosition(coords, address, timeStamp);
*aResult = new nsGeoPosition(coords, timeStamp);
return true;
};

View File

@ -87,6 +87,9 @@ EXPORTS = \
nsDeviceMotion.h \
$(NULL)
# We fire the nsDOMDeviceAcceleration
LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
include $(topsrcdir)/config/config.mk
# we don't want the shared lib, but we want to force the creation of a static lib.

View File

@ -59,6 +59,7 @@ CPPSRCS = \
$(NULL)
LOCAL_INCLUDES += -I$(topsrcdir)/dom/src/geolocation \
-I$(topsrcdir)/content/events/src
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -49,9 +49,13 @@ LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
# We fire the nsDOMDeviceAcceleration
LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
include $(topsrcdir)/config/config.mk
CMMSRCS = \
smslib.mm \
nsDeviceMotionSystem.mm \
$(NULL)

View File

@ -42,8 +42,9 @@
#include <sys/resource.h>
#include <sys/vm.h>
#define MODEL_NAME_LENGTH 64
static char gModelName[MODEL_NAME_LENGTH];
#import "smslib.h"
#define MEAN_GRAVITY 9.80665
#define DEFAULT_SENSOR_POLL 100
nsDeviceMotionSystem::nsDeviceMotionSystem()
{
@ -53,24 +54,6 @@ nsDeviceMotionSystem::~nsDeviceMotionSystem()
{
}
// Data format returned from IOConnectMethodStructureIStructureO.
// I am not sure what the other bits in this structure are,
// or if there are any, but this has to be 40 bytes long or
// the call to read fails.
//
// Since we make the SmsData struct larger than any members we plan to access we
// keep track of the the size of the part of the struct we plan to access for
// use in bounds checking.
#define SMSDATA_PADDING_SIZE 34
typedef struct
{
PRInt16 x;
PRInt16 y;
PRInt16 z;
PRInt8 unknown[SMSDATA_PADDING_SIZE];
} SmsData;
#define SMSDATA_USED_SIZE (sizeof(SmsData) - SMSDATA_PADDING_SIZE)
void
nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
{
@ -79,129 +62,35 @@ nsDeviceMotionSystem::UpdateHandler(nsITimer *aTimer, void *aClosure)
NS_ERROR("no self");
return;
}
sms_acceleration accel;
smsGetData(&accel);
size_t bufferLen = sizeof(SmsData);
void * input = malloc(bufferLen);
void * output = malloc(bufferLen);
if (!input || !output)
return;
memset(input, 0, bufferLen);
memset(output, 0, bufferLen);
size_t structureOutputSize = bufferLen;
#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
kern_return_t result = ::IOConnectMethodStructureIStructureO(self->mSmsConnection,
5, /* Magic number for SMCMotionSensor */
bufferLen,
(IOByteCount*)&structureOutputSize,
input,
output);
#else
kern_return_t result = ::IOConnectCallStructMethod((mach_port_t)self->mSmsConnection,
5, /* Magic number for SMCMotionSensor */
input,
bufferLen,
output,
&structureOutputSize);
#endif
if ((result != kIOReturnSuccess) || (structureOutputSize < SMSDATA_USED_SIZE)) {
free(input);
free(output);
return;
}
SmsData *data = (SmsData*) output;
float xf, yf, zf;
// we want to normalize the return result from the chip to
// something between -1 and 1 where 0 is the balance point.
const int normalizeFactor = 250.5;
if (!strcmp(gModelName, "MacBookPro5,1")) {
xf = ((float)data->x) / normalizeFactor;
yf = (((float)data->y) / normalizeFactor) * -1;
zf = ((float)data->z) / normalizeFactor;
}
else if (!strcmp(gModelName, "MacBookPro5,3")) {
xf = ((float)data->y) / normalizeFactor;
yf = (((float)data->x) / normalizeFactor) * -1;
zf = (((float)data->z) / normalizeFactor) * -1;
}
else
{
xf = (((float)data->x) / normalizeFactor) * -1;
yf = ((float)data->y) / normalizeFactor;
zf = ((float)data->z) / normalizeFactor;
}
free(input);
free(output);
self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, xf, yf, zf );
self->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION,
accel.x * MEAN_GRAVITY,
accel.y * MEAN_GRAVITY,
accel.z * MEAN_GRAVITY);
}
void nsDeviceMotionSystem::Startup()
{
// we can fail, and that just means the caller will not see any changes.
mach_port_t port;
kern_return_t result = ::IOMasterPort(MACH_PORT_NULL, &port);
if (result != kIOReturnSuccess)
return;
CFMutableDictionaryRef dict = ::IOServiceMatching("SMCMotionSensor");
if (!dict)
return;
io_iterator_t iter;
result = ::IOServiceGetMatchingServices(port, dict, &iter);
if (result != kIOReturnSuccess)
return;
io_object_t device = ::IOIteratorNext(iter);
::IOObjectRelease(iter);
if (!device)
return;
result = ::IOServiceOpen(device, mach_task_self(), 0, &mSmsConnection);
::IOObjectRelease(device);
if (result != kIOReturnSuccess)
return;
mach_port_deallocate(mach_task_self(), port);
/* get the version of the hardware we are running on. */
int mib[2];
size_t len = MODEL_NAME_LENGTH;
mib[0] = CTL_HW;
mib[1] = HW_MODEL;
sysctl(mib, 2, gModelName, &len, NULL, 0);
smsStartup(nil, nil);
smsLoadCalibration();
mUpdateTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mUpdateTimer)
mUpdateTimer->InitWithFuncCallback(UpdateHandler,
this,
mUpdateInterval,
DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK);
}
void nsDeviceMotionSystem::Shutdown()
{
if (mSmsConnection)
::IOServiceClose(mSmsConnection);
if (mUpdateTimer) {
mUpdateTimer->Cancel();
mUpdateTimer = nsnull;
}
smsShutdown();
}

159
dom/system/cocoa/smslib.h Normal file
View File

@ -0,0 +1,159 @@
/*
* smslib.h
*
* SMSLib Sudden Motion Sensor Access Library
* Copyright (c) 2010 Suitable Systems
* All rights reserved.
*
* Developed by: Daniel Griscom
* Suitable Systems
* http://www.suitable.com
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal with the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the names of Suitable Systems nor the names of its
* contributors may be used to endorse or promote products derived from
* this Software without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
*
* For more information about SMSLib, see
* <http://www.suitable.com/tools/smslib.html>
* or contact
* Daniel Griscom
* Suitable Systems
* 1 Centre Street, Suite 204
* Wakefield, MA 01880
* (781) 665-0053
*
*/
#import <Foundation/Foundation.h>
#define SMSLIB_VERSION "1.8"
#pragma mark Structure definitions
// Structure for specifying a 3-axis acceleration. 0.0 means "zero gravities",
// 1.0 means "one gravity".
typedef struct sms_acceleration {
float x; // Right-left acceleration (positive is rightwards)
float y; // Front-rear acceleration (positive is rearwards)
float z; // Up-down acceleration (positive is upwards)
} sms_acceleration;
// Structure for specifying a calibration.
typedef struct sms_calibration {
float zeros[3]; // Zero points for three axes (X, Y, Z)
float onegs[3]; // One gravity values for three axes
} sms_calibration;
#pragma mark Return value definitions
// These are the return values for accelStartup(), giving the
// various stages where the most successful attempt at accessing
// the accelerometer failed. The higher the value, the further along the
// software progressed before failing. The options are:
// - Didn't match model name
#define SMS_FAIL_MODEL (-7)
// - Failure getting dictionary matching desired services
#define SMS_FAIL_DICTIONARY (-6)
// - Failure getting list of services
#define SMS_FAIL_LIST_SERVICES (-5)
// - Failure if list of services is empty. The process generally fails
// here if run on a machine without a Sudden Motion Sensor.
#define SMS_FAIL_NO_SERVICES (-4)
// - Failure if error opening device.
#define SMS_FAIL_OPENING (-3)
// - Failure if opened, but didn't get a connection
#define SMS_FAIL_CONNECTION (-2)
// - Failure if couldn't access connction using given function and size. This
// is where the process would probably fail with a change in Apple's API.
// Driver problems often also cause failures here.
#define SMS_FAIL_ACCESS (-1)
// - Success!
#define SMS_SUCCESS (0)
#pragma mark Function declarations
// This starts up the accelerometer code, trying each possible sensor
// specification. Note that for logging purposes it
// takes an object and a selector; the object's selector is then invoked
// with a single NSString as argument giving progress messages. Example
// logging method:
// - (void)logMessage: (NSString *)theString
// which would be used in accelStartup's invocation thusly:
// result = accelStartup(self, @selector(logMessage:));
// If the object is nil, then no logging is done. Sets calibation from built-in
// value table. Returns ACCEL_SUCCESS for success, and other (negative)
// values for various failures (returns value indicating result of
// most successful trial).
int smsStartup(id logObject, SEL logSelector);
// This starts up the library in debug mode, ignoring the actual hardware.
// Returned data is in the form of 1Hz sine waves, with the X, Y and Z
// axes 120 degrees out of phase; "calibrated" data has range +/- (1.0/5);
// "uncalibrated" data has range +/- (256/5). X and Y axes centered on 0.0,
// Z axes centered on 1 (calibrated) or 256 (uncalibrated).
// Don't use smsGetBufferLength or smsGetBufferData. Always returns SMS_SUCCESS.
int smsDebugStartup(id logObject, SEL logSelector);
// Returns the current calibration values.
void smsGetCalibration(sms_calibration *calibrationRecord);
// Sets the calibration, but does NOT store it as a preference. If the argument
// is nil then the current calibration is set from the built-in value table.
void smsSetCalibration(sms_calibration *calibrationRecord);
// Stores the current calibration values as a stored preference.
void smsStoreCalibration(void);
// Loads the stored preference values into the current calibration.
// Returns YES if successful.
BOOL smsLoadCalibration(void);
// Deletes any stored calibration, and then takes the current calibration values
// from the built-in value table.
void smsDeleteCalibration(void);
// Fills in the accel record with calibrated acceleration data. Takes
// 1-2ms to return a value. Returns 0 if success, error number if failure.
int smsGetData(sms_acceleration *accel);
// Fills in the accel record with uncalibrated acceleration data.
// Returns 0 if success, error number if failure.
int smsGetUncalibratedData(sms_acceleration *accel);
// Returns the length of a raw block of data for the current type of sensor.
int smsGetBufferLength(void);
// Takes a pointer to accelGetRawLength() bytes; sets those bytes
// to return value from sensor. Make darn sure the buffer length is right!
void smsGetBufferData(char *buffer);
// This returns an NSString describing the current calibration in
// human-readable form. Also include a description of the machine.
NSString *smsGetCalibrationDescription(void);
// Shuts down the accelerometer.
void smsShutdown(void);

937
dom/system/cocoa/smslib.mm Normal file
View File

@ -0,0 +1,937 @@
/*
* smslib.m
*
* SMSLib Sudden Motion Sensor Access Library
* Copyright (c) 2010 Suitable Systems
* All rights reserved.
*
* Developed by: Daniel Griscom
* Suitable Systems
* http://www.suitable.com
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal with the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the names of Suitable Systems nor the names of its
* contributors may be used to endorse or promote products derived from
* this Software without specific prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
*
* For more information about SMSLib, see
* <http://www.suitable.com/tools/smslib.html>
* or contact
* Daniel Griscom
* Suitable Systems
* 1 Centre Street, Suite 204
* Wakefield, MA 01880
* (781) 665-0053
*
*/
#import <IOKit/IOKitLib.h>
#import <sys/sysctl.h>
#import <math.h>
#import "smslib.h"
#pragma mark Internal structures
// Represents a single axis of a type of sensor.
typedef struct axisStruct {
int enabled; // Non-zero if axis is valid in this sensor
int index; // Location in struct of first byte
int size; // Number of bytes
float zerog; // Value meaning "zero g"
float oneg; // Change in value meaning "increase of one g"
// (can be negative if axis sensor reversed)
} axisStruct;
// Represents the configuration of a type of sensor.
typedef struct sensorSpec {
char *model; // Prefix of model to be tested
char *name; // Name of device to be read
unsigned int function; // Kernel function index
int recordSize; // Size of record to be sent/received
axisStruct axes[3]; // Description of three axes (X, Y, Z)
} sensorSpec;
// Configuration of all known types of sensors. The configurations are
// tried in order until one succeeds in returning data.
// All default values are set here, but each axis' zerog and oneg values
// may be changed to saved (calibrated) values.
//
// These values came from SeisMaCalibrate calibration reports. In general I've
// found the following:
// - All Intel-based SMSs have 250 counts per g, centered on 0, but the signs
// are different (and in one case two axes are swapped)
// - PowerBooks and iBooks all have sensors centered on 0, and reading
// 50-53 steps per gravity (but with differing polarities!)
// - PowerBooks and iBooks of the same model all have the same axis polarities
// - PowerBook and iBook access methods are model- and OS version-specific
//
// So, the sequence of tests is:
// - Try model-specific access methods. Note that the test is for a match to the
// beginning of the model name, e.g. the record with model name "MacBook"
// matches computer models "MacBookPro1,2" and "MacBook1,1" (and ""
// matches any model).
// - If no model-specific record's access fails, then try each model-independent
// access method in order, stopping when one works.
static const sensorSpec sensors[] = {
// ****** Model-dependent methods ******
// The PowerBook5,6 is one of the G4 models that seems to lose
// SMS access until the next reboot.
{"PowerBook5,6", "IOI2CMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, -51.5},
{1, 2, 1, 0, -51.5}
}
},
// The PowerBook5,7 is one of the G4 models that seems to lose
// SMS access until the next reboot.
{"PowerBook5,7", "IOI2CMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, 51.5}
}
},
// Access seems to be reliable on the PowerBook5,8
{"PowerBook5,8", "PMUMotionSensor", 21, 60, {
{1, 0, 1, 0, -51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, -51.5}
}
},
// Access seems to be reliable on the PowerBook5,9
{"PowerBook5,9", "PMUMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, -51.5},
{1, 2, 1, 0, -51.5}
}
},
// The PowerBook6,7 is one of the G4 models that seems to lose
// SMS access until the next reboot.
{"PowerBook6,7", "IOI2CMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, 51.5}
}
},
// The PowerBook6,8 is one of the G4 models that seems to lose
// SMS access until the next reboot.
{"PowerBook6,8", "IOI2CMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, 51.5}
}
},
// MacBook Pro Core 2 Duo 17". Note the reversed Y and Z axes.
{"MacBookPro2,1", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, 251},
{1, 2, 2, 0, -251},
{1, 4, 2, 0, -251}
}
},
// MacBook Pro Core 2 Duo 15" AND 17" with LED backlight, introduced June '07.
// NOTE! The 17" machines have the signs of their X and Y axes reversed
// from this calibration, but there's no clear way to discriminate between
// the two machines.
{"MacBookPro3,1", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, -251},
{1, 2, 2, 0, 251},
{1, 4, 2, 0, -251}
}
},
// ... specs?
{"MacBook5,2", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, -251},
{1, 2, 2, 0, 251},
{1, 4, 2, 0, -251}
}
},
// ... specs?
{"MacBookPro5,1", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, -251},
{1, 2, 2, 0, -251},
{1, 4, 2, 0, 251}
}
},
// ... specs?
{"MacBookPro5,2", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, -251},
{1, 2, 2, 0, -251},
{1, 4, 2, 0, 251}
}
},
// This is speculative, based on a single user's report. Looks like the X and Y axes
// are swapped. This is true for no other known Appple laptop.
{"MacBookPro5,3", "SMCMotionSensor", 5, 40, {
{1, 2, 2, 0, -251},
{1, 0, 2, 0, -251},
{1, 4, 2, 0, -251}
}
},
// ... specs?
{"MacBookPro5,4", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, -251},
{1, 2, 2, 0, -251},
{1, 4, 2, 0, 251}
}
},
// ****** Model-independent methods ******
// Seen once with PowerBook6,8 under system 10.3.9; I suspect
// other G4-based 10.3.* systems might use this
{"", "IOI2CMotionSensor", 24, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, 51.5}
}
},
// PowerBook5,6 , PowerBook5,7 , PowerBook6,7 , PowerBook6,8
// under OS X 10.4.*
{"", "IOI2CMotionSensor", 21, 60, {
{1, 0, 1, 0, 51.5},
{1, 1, 1, 0, 51.5},
{1, 2, 1, 0, 51.5}
}
},
// PowerBook5,8 , PowerBook5,9 under OS X 10.4.*
{"", "PMUMotionSensor", 21, 60, {
// Each has two out of three gains negative, but it's different
// for the different models. So, this will be right in two out
// of three axis for either model.
{1, 0, 1, 0, -51.5},
{1, 1, 1, -6, -51.5},
{1, 2, 1, 0, -51.5}
}
},
// All MacBook, MacBookPro models. Hardware (at least on early MacBookPro 15")
// is Kionix KXM52-1050 three-axis accelerometer chip. Data is at
// http://kionix.com/Product-Index/product-index.htm. Specific MB and MBP models
// that use this are:
// MacBook1,1
// MacBook2,1
// MacBook3,1
// MacBook4,1
// MacBook5,1
// MacBook6,1
// MacBookAir1,1
// MacBookPro1,1
// MacBookPro1,2
// MacBookPro4,1
// MacBookPro5,5
{"", "SMCMotionSensor", 5, 40, {
{1, 0, 2, 0, 251},
{1, 2, 2, 0, 251},
{1, 4, 2, 0, 251}
}
}
};
#define SENSOR_COUNT (sizeof(sensors)/sizeof(sensorSpec))
#pragma mark Internal prototypes
static int getData(sms_acceleration *accel, int calibrated, id logObject, SEL logSelector);
static float getAxis(int which, int calibrated);
static int signExtend(int value, int size);
static NSString *getModelName(void);
static NSString *getOSVersion(void);
static BOOL loadCalibration(void);
static void storeCalibration(void);
static void defaultCalibration(void);
static void deleteCalibration(void);
static int prefIntRead(NSString *prefName, BOOL *success);
static void prefIntWrite(NSString *prefName, int prefValue);
static float prefFloatRead(NSString *prefName, BOOL *success);
static void prefFloatWrite(NSString *prefName, float prefValue);
static void prefDelete(NSString *prefName);
static void prefSynchronize(void);
// static long getMicroseconds(void);
float fakeData(NSTimeInterval time);
#pragma mark Static variables
static int debugging = NO; // True if debugging (synthetic data)
static io_connect_t connection; // Connection for reading accel values
static int running = NO; // True if we successfully started
static int sensorNum = 0; // The current index into sensors[]
static char *serviceName; // The name of the current service
static char *iRecord, *oRecord; // Pointers to read/write records for sensor
static int recordSize; // Size of read/write records
static unsigned int function; // Which kernel function should be used
static float zeros[3]; // X, Y and Z zero calibration values
static float onegs[3]; // X, Y and Z one-g calibration values
#pragma mark Defines
// Pattern for building axis letter from axis number
#define INT_TO_AXIS(a) (a == 0 ? @"X" : a == 1 ? @"Y" : @"Z")
// Name of configuration for given axis' zero (axis specified by integer)
#define ZERO_NAME(a) [NSString stringWithFormat:@"%@-Axis-Zero", INT_TO_AXIS(a)]
// Name of configuration for given axis' oneg (axis specified by integer)
#define ONEG_NAME(a) [NSString stringWithFormat:@"%@-Axis-One-g", INT_TO_AXIS(a)]
// Name of "Is calibrated" preference
#define CALIBRATED_NAME (@"Calibrated")
// Application domain for SeisMac library
#define APP_ID ((CFStringRef)@"com.suitable.SeisMacLib")
// These #defines make the accelStartup code a LOT easier to read.
#define LOG(message) \
if (logObject) { \
[logObject performSelector:logSelector withObject:message]; \
}
#define LOG_ARG(format, var1) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1]]; \
}
#define LOG_2ARG(format, var1, var2) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2]]; \
}
#define LOG_3ARG(format, var1, var2, var3) \
if (logObject) { \
[logObject performSelector:logSelector \
withObject:[NSString stringWithFormat:format, var1, var2, var3]]; \
}
#pragma mark Function definitions
// This starts up the accelerometer code, trying each possible sensor
// specification. Note that for logging purposes it
// takes an object and a selector; the object's selector is then invoked
// with a single NSString as argument giving progress messages. Example
// logging method:
// - (void)logMessage: (NSString *)theString
// which would be used in accelStartup's invocation thusly:
// result = accelStartup(self, @selector(logMessage:));
// If the object is nil, then no logging is done. Sets calibation from built-in
// value table. Returns ACCEL_SUCCESS for success, and other (negative)
// values for various failures (returns value indicating result of
// most successful trial).
int smsStartup(id logObject, SEL logSelector) {
io_iterator_t iterator;
io_object_t device;
kern_return_t result;
sms_acceleration accel;
int failure_result = SMS_FAIL_MODEL;
running = NO;
debugging = NO;
NSString *modelName = getModelName();
LOG_ARG(@"Machine model: %@\n", modelName);
LOG_ARG(@"OS X version: %@\n", getOSVersion());
LOG_ARG(@"Accelerometer library version: %s\n", SMSLIB_VERSION);
for (sensorNum = 0; sensorNum < SENSOR_COUNT; sensorNum++) {
// Set up all specs for this type of sensor
serviceName = sensors[sensorNum].name;
recordSize = sensors[sensorNum].recordSize;
function = sensors[sensorNum].function;
LOG_3ARG(@"Trying service \"%s\" with selector %d and %d byte record:\n",
serviceName, function, recordSize);
NSString *targetName = [NSString stringWithCString:sensors[sensorNum].model
encoding:NSMacOSRomanStringEncoding];
LOG_ARG(@" Comparing model name to target \"%@\": ", targetName);
if ([targetName length] == 0 || [modelName hasPrefix:targetName]) {
LOG(@"success.\n");
} else {
LOG(@"failure.\n");
// Don't need to increment failure_result.
continue;
}
LOG(@" Fetching dictionary for service: ");
CFMutableDictionaryRef dict = IOServiceMatching(serviceName);
if (dict) {
LOG(@"success.\n");
} else {
LOG(@"failure.\n");
if (failure_result < SMS_FAIL_DICTIONARY) {
failure_result = SMS_FAIL_DICTIONARY;
}
continue;
}
LOG(@" Getting list of matching services: ");
result = IOServiceGetMatchingServices(kIOMasterPortDefault,
dict,
&iterator);
if (result == KERN_SUCCESS) {
LOG(@"success.\n");
} else {
LOG_ARG(@"failure, with return value 0x%x.\n", result);
if (failure_result < SMS_FAIL_LIST_SERVICES) {
failure_result = SMS_FAIL_LIST_SERVICES;
}
continue;
}
LOG(@" Getting first device in list: ");
device = IOIteratorNext(iterator);
if (device == 0) {
LOG(@"failure.\n");
if (failure_result < SMS_FAIL_NO_SERVICES) {
failure_result = SMS_FAIL_NO_SERVICES;
}
continue;
} else {
LOG(@"success.\n");
LOG(@" Opening device: ");
}
result = IOServiceOpen(device, mach_task_self(), 0, &connection);
if (result != KERN_SUCCESS) {
LOG_ARG(@"failure, with return value 0x%x.\n", result);
IOObjectRelease(device);
if (failure_result < SMS_FAIL_OPENING) {
failure_result = SMS_FAIL_OPENING;
}
continue;
} else if (connection == 0) {
LOG_ARG(@"'success', but didn't get a connection.\n", result);
IOObjectRelease(device);
if (failure_result < SMS_FAIL_CONNECTION) {
failure_result = SMS_FAIL_CONNECTION;
}
continue;
} else {
IOObjectRelease(device);
LOG(@"success.\n");
}
LOG(@" Testing device.\n");
defaultCalibration();
iRecord = (char*) malloc(recordSize);
oRecord = (char*) malloc(recordSize);
running = YES;
result = getData(&accel, true, logObject, logSelector);
running = NO;
if (result) {
LOG_ARG(@" Failure testing device, with result 0x%x.\n", result);
free(iRecord);
iRecord = 0;
free(oRecord);
oRecord = 0;
if (failure_result < SMS_FAIL_ACCESS) {
failure_result = SMS_FAIL_ACCESS;
}
continue;
} else {
LOG(@" Success testing device!\n");
running = YES;
return SMS_SUCCESS;
}
}
return failure_result;
}
// This starts up the library in debug mode, ignoring the actual hardware.
// Returned data is in the form of 1Hz sine waves, with the X, Y and Z
// axes 120 degrees out of phase; "calibrated" data has range +/- (1.0/5);
// "uncalibrated" data has range +/- (256/5). X and Y axes centered on 0.0,
// Z axes centered on 1 (calibrated) or 256 (uncalibrated).
// Don't use smsGetBufferLength or smsGetBufferData. Always returns SMS_SUCCESS.
int smsDebugStartup(id logObject, SEL logSelector) {
LOG(@"Starting up in debug mode\n");
debugging = YES;
return SMS_SUCCESS;
}
// Returns the current calibration values.
void smsGetCalibration(sms_calibration *calibrationRecord) {
int x;
for (x = 0; x < 3; x++) {
calibrationRecord->zeros[x] = (debugging ? 0 : zeros[x]);
calibrationRecord->onegs[x] = (debugging ? 256 : onegs[x]);
}
}
// Sets the calibration, but does NOT store it as a preference. If the argument
// is nil then the current calibration is set from the built-in value table.
void smsSetCalibration(sms_calibration *calibrationRecord) {
int x;
if (!debugging) {
if (calibrationRecord) {
for (x = 0; x < 3; x++) {
zeros[x] = calibrationRecord->zeros[x];
onegs[x] = calibrationRecord->onegs[x];
}
} else {
defaultCalibration();
}
}
}
// Stores the current calibration values as a stored preference.
void smsStoreCalibration(void) {
if (!debugging)
storeCalibration();
}
// Loads the stored preference values into the current calibration.
// Returns YES if successful.
BOOL smsLoadCalibration(void) {
if (debugging) {
return YES;
} else if (loadCalibration()) {
return YES;
} else {
defaultCalibration();
return NO;
}
}
// Deletes any stored calibration, and then takes the current calibration values
// from the built-in value table.
void smsDeleteCalibration(void) {
if (!debugging) {
deleteCalibration();
defaultCalibration();
}
}
// Fills in the accel record with calibrated acceleration data. Takes
// 1-2ms to return a value. Returns 0 if success, error number if failure.
int smsGetData(sms_acceleration *accel) {
NSTimeInterval time;
if (debugging) {
usleep(1500); // Usually takes 1-2 milliseconds
time = [NSDate timeIntervalSinceReferenceDate];
accel->x = fakeData(time)/5;
accel->y = fakeData(time - 1)/5;
accel->z = fakeData(time - 2)/5 + 1.0;
return true;
} else {
return getData(accel, true, nil, nil);
}
}
// Fills in the accel record with uncalibrated acceleration data.
// Returns 0 if success, error number if failure.
int smsGetUncalibratedData(sms_acceleration *accel) {
NSTimeInterval time;
if (debugging) {
usleep(1500); // Usually takes 1-2 milliseconds
time = [NSDate timeIntervalSinceReferenceDate];
accel->x = fakeData(time) * 256 / 5;
accel->y = fakeData(time - 1) * 256 / 5;
accel->z = fakeData(time - 2) * 256 / 5 + 256;
return true;
} else {
return getData(accel, false, nil, nil);
}
}
// Returns the length of a raw block of data for the current type of sensor.
int smsGetBufferLength(void) {
if (debugging) {
return 0;
} else if (running) {
return sensors[sensorNum].recordSize;
} else {
return 0;
}
}
// Takes a pointer to accelGetRawLength() bytes; sets those bytes
// to return value from sensor. Make darn sure the buffer length is right!
void smsGetBufferData(char *buffer) {
IOItemCount iSize = recordSize;
IOByteCount oSize = recordSize;
kern_return_t result;
if (debugging || running == NO) {
return;
}
memset(iRecord, 1, iSize);
memset(buffer, 0, oSize);
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
const size_t InStructSize = recordSize;
size_t OutStructSize = recordSize;
result = IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void *)iRecord,
InStructSize,
(void *)buffer,
&OutStructSize
);
#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
result = IOConnectMethodStructureIStructureO(connection,
function, // magic kernel function number
iSize,
&oSize,
iRecord,
buffer
);
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
if (result != KERN_SUCCESS) {
running = NO;
}
}
// This returns an NSString describing the current calibration in
// human-readable form. Also include a description of the machine.
NSString *smsGetCalibrationDescription(void) {
BOOL success;
NSMutableString *s = [[NSMutableString alloc] init];
if (debugging) {
[s release];
return @"Debugging!";
}
[s appendString:@"---- SeisMac Calibration Record ----\n \n"];
[s appendFormat:@"Machine model: %@\n",
getModelName()];
[s appendFormat:@"OS X build: %@\n",
getOSVersion()];
[s appendFormat:@"SeisMacLib version %s, record %d\n \n",
SMSLIB_VERSION, sensorNum];
[s appendFormat:@"Using service \"%s\", function index %d, size %d\n \n",
serviceName, function, recordSize];
if (prefIntRead(CALIBRATED_NAME, &success) && success) {
[s appendString:@"Calibration values (from calibration):\n"];
} else {
[s appendString:@"Calibration values (from defaults):\n"];
}
[s appendFormat:@" X-Axis-Zero = %.2f\n", zeros[0]];
[s appendFormat:@" X-Axis-One-g = %.2f\n", onegs[0]];
[s appendFormat:@" Y-Axis-Zero = %.2f\n", zeros[1]];
[s appendFormat:@" Y-Axis-One-g = %.2f\n", onegs[1]];
[s appendFormat:@" Z-Axis-Zero = %.2f\n", zeros[2]];
[s appendFormat:@" Z-Axis-One-g = %.2f\n \n", onegs[2]];
[s appendString:@"---- End Record ----\n"];
return s;
}
// Shuts down the accelerometer.
void smsShutdown(void) {
if (!debugging) {
running = NO;
if (iRecord) free(iRecord);
if (oRecord) free(oRecord);
IOServiceClose(connection);
}
}
#pragma mark Internal functions
// Loads the current calibration from the stored preferences.
// Returns true iff successful.
BOOL loadCalibration(void) {
BOOL thisSuccess, allSuccess;
int x;
prefSynchronize();
if (prefIntRead(CALIBRATED_NAME, &thisSuccess) && thisSuccess) {
// Calibrated. Set all values from saved values.
allSuccess = YES;
for (x = 0; x < 3; x++) {
zeros[x] = prefFloatRead(ZERO_NAME(x), &thisSuccess);
allSuccess &= thisSuccess;
onegs[x] = prefFloatRead(ONEG_NAME(x), &thisSuccess);
allSuccess &= thisSuccess;
}
return allSuccess;
}
return NO;
}
// Stores the current calibration into the stored preferences.
static void storeCalibration(void) {
int x;
prefIntWrite(CALIBRATED_NAME, 1);
for (x = 0; x < 3; x++) {
prefFloatWrite(ZERO_NAME(x), zeros[x]);
prefFloatWrite(ONEG_NAME(x), onegs[x]);
}
prefSynchronize();
}
// Sets the calibration to its default values.
void defaultCalibration(void) {
int x;
for (x = 0; x < 3; x++) {
zeros[x] = sensors[sensorNum].axes[x].zerog;
onegs[x] = sensors[sensorNum].axes[x].oneg;
}
}
// Deletes the stored preferences.
static void deleteCalibration(void) {
int x;
prefDelete(CALIBRATED_NAME);
for (x = 0; x < 3; x++) {
prefDelete(ZERO_NAME(x));
prefDelete(ONEG_NAME(x));
}
prefSynchronize();
}
// Read a named floating point value from the stored preferences. Sets
// the success boolean based on, you guessed it, whether it succeeds.
static float prefFloatRead(NSString *prefName, BOOL *success) {
float result = 0.0f;
CFPropertyListRef ref = CFPreferencesCopyAppValue((CFStringRef)prefName,
APP_ID);
// If there isn't such a preference, fail
if (ref == NULL) {
*success = NO;
return result;
}
CFTypeID typeID = CFGetTypeID(ref);
// Is it a number?
if (typeID == CFNumberGetTypeID()) {
// Is it a floating point number?
if (CFNumberIsFloatType((CFNumberRef)ref)) {
// Yup: grab it.
*success = CFNumberGetValue((__CFNumber*)ref, kCFNumberFloat32Type, &result);
} else {
// Nope: grab as an integer, and convert to a float.
long num;
if (CFNumberGetValue((CFNumberRef)ref, kCFNumberLongType, &num)) {
result = num;
*success = YES;
} else {
*success = NO;
}
}
// Or is it a string (e.g. set by the command line "defaults" command)?
} else if (typeID == CFStringGetTypeID()) {
result = (float)CFStringGetDoubleValue((CFStringRef)ref);
*success = YES;
} else {
// Can't convert to a number: fail.
*success = NO;
}
CFRelease(ref);
return result;
}
// Writes a named floating point value to the stored preferences.
static void prefFloatWrite(NSString *prefName, float prefValue) {
CFNumberRef cfFloat = CFNumberCreate(kCFAllocatorDefault,
kCFNumberFloatType,
&prefValue);
CFPreferencesSetAppValue((CFStringRef)prefName,
cfFloat,
APP_ID);
CFRelease(cfFloat);
}
// Reads a named integer value from the stored preferences.
static int prefIntRead(NSString *prefName, BOOL *success) {
Boolean internalSuccess;
CFIndex result = CFPreferencesGetAppIntegerValue((CFStringRef)prefName,
APP_ID,
&internalSuccess);
*success = internalSuccess;
return result;
}
// Writes a named integer value to the stored preferences.
static void prefIntWrite(NSString *prefName, int prefValue) {
CFPreferencesSetAppValue((CFStringRef)prefName,
(CFNumberRef)[NSNumber numberWithInt:prefValue],
APP_ID);
}
// Deletes the named preference values.
static void prefDelete(NSString *prefName) {
CFPreferencesSetAppValue((CFStringRef)prefName,
NULL,
APP_ID);
}
// Synchronizes the local preferences with the stored preferences.
static void prefSynchronize(void) {
CFPreferencesAppSynchronize(APP_ID);
}
// Internal version of accelGetData, with logging
int getData(sms_acceleration *accel, int calibrated, id logObject, SEL logSelector) {
IOItemCount iSize = recordSize;
IOByteCount oSize = recordSize;
kern_return_t result;
if (running == NO) {
return -1;
}
memset(iRecord, 1, iSize);
memset(oRecord, 0, oSize);
LOG_2ARG(@" Querying device: ",
sensors[sensorNum].function, sensors[sensorNum].recordSize);
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
const size_t InStructSize = recordSize;
size_t OutStructSize = recordSize;
result = IOConnectCallStructMethod(connection,
function, // magic kernel function number
(const void *)iRecord,
InStructSize,
(void *)oRecord,
&OutStructSize
);
#else // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
result = IOConnectMethodStructureIStructureO(connection,
function, // magic kernel function number
iSize,
&oSize,
iRecord,
oRecord
);
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED 1050
if (result != KERN_SUCCESS) {
LOG(@"failed.\n");
running = NO;
return result;
} else {
LOG(@"succeeded.\n");
accel->x = getAxis(0, calibrated);
accel->y = getAxis(1, calibrated);
accel->z = getAxis(2, calibrated);
return 0;
}
}
// Given the returned record, extracts the value of the given axis. If
// calibrated, then zero G is 0.0, and one G is 1.0.
float getAxis(int which, int calibrated) {
// Get various values (to make code cleaner)
int indx = sensors[sensorNum].axes[which].index;
int size = sensors[sensorNum].axes[which].size;
float zerog = zeros[which];
float oneg = onegs[which];
// Storage for value to be returned
int value = 0;
// Although the values in the returned record should have the proper
// endianness, we still have to get it into the proper end of value.
#if (BYTE_ORDER == BIG_ENDIAN)
// On PowerPC processors
memcpy(((char *)&value) + (sizeof(int) - size), &oRecord[indx], size);
#endif
#if (BYTE_ORDER == LITTLE_ENDIAN)
// On Intel processors
memcpy(&value, &oRecord[indx], size);
#endif
value = signExtend(value, size);
if (calibrated) {
// Scale and shift for zero.
return ((float)(value - zerog)) / oneg;
} else {
return value;
}
}
// Extends the sign, given the length of the value.
int signExtend(int value, int size) {
// Extend sign
switch (size) {
case 1:
if (value & 0x00000080)
value |= 0xffffff00;
break;
case 2:
if (value & 0x00008000)
value |= 0xffff0000;
break;
case 3:
if (value & 0x00800000)
value |= 0xff000000;
break;
}
return value;
}
// Returns the model name of the computer (e.g. "MacBookPro1,1")
NSString *getModelName(void) {
char model[32];
size_t len = sizeof(model);
int name[2] = {CTL_HW, HW_MODEL};
NSString *result;
if (sysctl(name, 2, &model, &len, NULL, 0) == 0) {
result = [NSString stringWithFormat:@"%s", model];
} else {
result = @"";
}
return result;
}
// Returns the current OS X version and build (e.g. "10.4.7 (build 8J2135a)")
NSString *getOSVersion(void) {
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"];
NSString *versionString = [dict objectForKey:@"ProductVersion"];
NSString *buildString = [dict objectForKey:@"ProductBuildVersion"];
NSString *wholeString = [NSString stringWithFormat:@"%@ (build %@)",
versionString, buildString];
return wholeString;
}
// Returns time within the current second in microseconds.
// long getMicroseconds() {
// struct timeval t;
// gettimeofday(&t, 0);
// return t.tv_usec;
//}
// Returns fake data given the time. Range is +/-1.
float fakeData(NSTimeInterval time) {
long secs = lround(floor(time));
int secsMod3 = secs % 3;
double angle = time * 10 * M_PI * 2;
double mag = exp(-(time - (secs - secsMod3)) * 2);
return sin(angle) * mag;
}

View File

@ -44,11 +44,14 @@
#include "nsIDOMEventTarget.h"
#include "nsIServiceManager.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMDeviceOrientationEvent.h"
#include "nsIDOMDeviceMotionEvent.h"
#include "nsIServiceManager.h"
#include "nsIPrefService.h"
#include "nsDOMDeviceMotionEvent.h"
using mozilla::TimeStamp;
using mozilla::TimeDuration;
// also see sDefaultSensorHint in mobile/android/base/GeckoAppShell.java
#define DEFAULT_SENSOR_POLL 100
static const nsTArray<nsIDOMWindow*>::index_type NoIndex =
nsTArray<nsIDOMWindow*>::NoIndex;
@ -117,21 +120,16 @@ NS_IMPL_ISUPPORTS2(nsDeviceMotion, nsIDeviceMotion, nsIDeviceMotionUpdate)
nsDeviceMotion::nsDeviceMotion()
: mStarted(false),
mUpdateInterval(50), /* default to 50 ms */
mEnabled(true)
{
nsCOMPtr<nsIPrefBranch> prefSrv = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefSrv) {
PRInt32 value;
nsresult rv = prefSrv->GetIntPref("device.motion.update.interval", &value);
if (NS_SUCCEEDED(rv))
mUpdateInterval = value;
bool bvalue;
rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
nsresult rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
if (NS_SUCCEEDED(rv) && bvalue == false)
mEnabled = false;
}
mLastDOMMotionEventTime = TimeStamp::Now();
}
nsDeviceMotion::~nsDeviceMotion()
@ -255,8 +253,10 @@ nsDeviceMotion::DeviceMotionChanged(PRUint32 type, double x, double y, double z)
if (domdoc) {
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
if (type == nsIDeviceMotionData::TYPE_ACCELERATION)
FireDOMMotionEvent(domdoc, target, x, y, z);
if (type == nsIDeviceMotionData::TYPE_ACCELERATION ||
type == nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION ||
type == nsIDeviceMotionData::TYPE_GYROSCOPE )
FireDOMMotionEvent(domdoc, target, type, x, y, z);
else if (type == nsIDeviceMotionData::TYPE_ORIENTATION)
FireDOMOrientationEvent(domdoc, target, x, y, z);
}
@ -264,6 +264,64 @@ nsDeviceMotion::DeviceMotionChanged(PRUint32 type, double x, double y, double z)
return NS_OK;
}
NS_IMETHODIMP
nsDeviceMotion::NeedsCalibration()
{
if (!mEnabled)
return NS_ERROR_NOT_INITIALIZED;
nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
for (PRUint32 i = listeners.Count(); i > 0 ; ) {
--i;
listeners[i]->NeedsCalibration();
}
nsCOMArray<nsIDOMWindow> windowListeners;
for (PRUint32 i = 0; i < mWindowListeners.Length(); i++) {
windowListeners.AppendObject(mWindowListeners[i]);
}
for (PRUint32 i = windowListeners.Count(); i > 0 ; ) {
--i;
// check to see if this window is in the background. if
// it is, don't send any device motion to it.
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(windowListeners[i]);
if (!pwindow ||
!pwindow->GetOuterWindow() ||
pwindow->GetOuterWindow()->IsBackground())
continue;
nsCOMPtr<nsIDOMDocument> domdoc;
windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
FireNeedsCalibration(domdoc, target);
}
}
return NS_OK;
}
void
nsDeviceMotion::FireNeedsCalibration(nsIDOMDocument *domdoc,
nsIDOMEventTarget *target)
{
nsCOMPtr<nsIDOMEvent> event;
domdoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
if (!event)
return;
event->InitEvent(NS_LITERAL_STRING("compassneedscalibration"), true, false);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
if (privateEvent)
privateEvent->SetTrusted(true);
bool defaultActionEnabled = true;
target->DispatchEvent(event, &defaultActionEnabled);
}
void
nsDeviceMotion::FireDOMOrientationEvent(nsIDOMDocument *domdoc,
nsIDOMEventTarget *target,
@ -300,34 +358,57 @@ nsDeviceMotion::FireDOMOrientationEvent(nsIDOMDocument *domdoc,
void
nsDeviceMotion::FireDOMMotionEvent(nsIDOMDocument *domdoc,
nsIDOMEventTarget *target,
PRUint32 type,
double x,
double y,
double z) {
// Attempt to coalesce events
bool fireEvent = TimeStamp::Now() > mLastDOMMotionEventTime + TimeDuration::FromMilliseconds(DEFAULT_SENSOR_POLL);
switch (type) {
case nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION:
mLastAcceleration = new nsDOMDeviceAcceleration(x, y, z);
break;
case nsIDeviceMotionData::TYPE_ACCELERATION:
mLastAccelerationIncluduingGravity = new nsDOMDeviceAcceleration(x, y, z);
break;
case nsIDeviceMotionData::TYPE_GYROSCOPE:
mLastRotationRate = new nsDOMDeviceRotationRate(x, y, z);
break;
}
if (!fireEvent && (!mLastAcceleration || !mLastAccelerationIncluduingGravity || !mLastRotationRate)) {
return;
}
nsCOMPtr<nsIDOMEvent> event;
bool defaultActionEnabled = true;
domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
nsCOMPtr<nsIDOMDeviceMotionEvent> me = do_QueryInterface(event);
if (!me) {
return;
}
// Currently acceleration as determined includes gravity.
nsRefPtr<nsDOMDeviceAcceleration> acceleration = new nsDOMDeviceAcceleration(x, y, z);
}
me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
true,
false,
nsnull,
acceleration,
nsnull,
0);
mLastAcceleration,
mLastAccelerationIncluduingGravity,
mLastRotationRate,
DEFAULT_SENSOR_POLL);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
if (privateEvent)
privateEvent->SetTrusted(true);
bool defaultActionEnabled = true;
target->DispatchEvent(event, &defaultActionEnabled);
mLastRotationRate = nsnull;
mLastAccelerationIncluduingGravity = nsnull;
mLastAcceleration = nsnull;
mLastDOMMotionEventTime = TimeStamp::Now();
}

View File

@ -43,6 +43,10 @@
#include "nsTArray.h"
#include "nsCOMPtr.h"
#include "nsITimer.h"
#include "nsIDOMDeviceOrientationEvent.h"
#include "nsIDOMDeviceMotionEvent.h"
#include "nsDOMDeviceMotionEvent.h"
#include "mozilla/TimeStamp.h"
#define NS_DEVICE_MOTION_CID \
{ 0xecba5203, 0x77da, 0x465a, \
@ -76,6 +80,9 @@ private:
protected:
void FireNeedsCalibration(nsIDOMDocument *domdoc,
nsIDOMEventTarget *target);
void FireDOMOrientationEvent(class nsIDOMDocument *domDoc,
class nsIDOMEventTarget *target,
double alpha,
@ -84,15 +91,20 @@ private:
void FireDOMMotionEvent(class nsIDOMDocument *domDoc,
class nsIDOMEventTarget *target,
PRUint32 type,
double x,
double y,
double z);
PRUint32 mUpdateInterval;
bool mEnabled;
virtual void Startup() = 0;
virtual void Shutdown() = 0;
bool mEnabled;
mozilla::TimeStamp mLastDOMMotionEventTime;
nsRefPtr<nsDOMDeviceAcceleration> mLastAcceleration;
nsRefPtr<nsDOMDeviceAcceleration> mLastAccelerationIncluduingGravity;
nsRefPtr<nsDOMDeviceRotationRate> mLastRotationRate;
};
#endif

View File

@ -82,4 +82,7 @@ LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \
endif
endif
# We fire the nsDOMDeviceAcceleration
LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
include $(topsrcdir)/config/rules.mk

View File

@ -42,6 +42,8 @@
#include "nsDeviceMotionSystem.h"
#include "nsIServiceManager.h"
#define DEFAULT_SENSOR_POLL 100
using namespace mozilla;
typedef struct {
@ -223,7 +225,7 @@ void nsDeviceMotionSystem::Startup()
if (mUpdateTimer)
mUpdateTimer->InitWithFuncCallback(UpdateHandler,
this,
mUpdateInterval,
DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK);
}

View File

@ -49,6 +49,9 @@ LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
# We fire the nsDOMDeviceAcceleration
LOCAL_INCLUDES += -I$(topsrcdir)/content/events/src
include $(topsrcdir)/config/config.mk
CPPSRCS = \

View File

@ -39,6 +39,8 @@
#include "nsIServiceManager.h"
#include "windows.h"
#define DEFAULT_SENSOR_POLL 100
////////////////////////////
// ThinkPad
////////////////////////////
@ -156,7 +158,7 @@ void nsDeviceMotionSystem::Startup()
if (mUpdateTimer)
mUpdateTimer->InitWithFuncCallback(UpdateHandler,
this,
mUpdateInterval,
DEFAULT_SENSOR_POLL,
nsITimer::TYPE_REPEATING_SLACK);
}

View File

@ -164,8 +164,8 @@ Telephony::Create(nsPIDOMWindow* aOwner, nsIRadioInterfaceLayer* aRIL)
nsRefPtr<Telephony> telephony = new Telephony();
telephony->mOwner = aOwner;
telephony->mScriptContext.swap(scriptContext);
telephony->BindToOwner(aOwner);
telephony->mRIL = aRIL;
telephony->mRILTelephonyCallback = new RILTelephonyCallback(telephony);
@ -328,12 +328,16 @@ Telephony::GetActive(jsval* aActive)
return NS_OK;
}
nsresult rv =
nsContentUtils::WrapNative(mScriptContext->GetNativeContext(),
mScriptContext->GetNativeGlobal(),
mActiveCall->ToISupports(), aActive);
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
if (sc) {
rv =
nsContentUtils::WrapNative(sc->GetNativeContext(),
sc->GetNativeGlobal(),
mActiveCall->ToISupports(), aActive);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
@ -342,17 +346,24 @@ Telephony::GetCalls(jsval* aCalls)
{
JSObject* calls = mCallsArray;
if (!calls) {
nsresult rv =
nsTArrayToJSArray(mScriptContext->GetNativeContext(),
mScriptContext->GetNativeGlobal(), mCalls, &calls);
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
if (sc) {
rv =
nsTArrayToJSArray(sc->GetNativeContext(),
sc->GetNativeGlobal(), mCalls, &calls);
NS_ENSURE_SUCCESS(rv, rv);
if (!mRooted) {
NS_HOLD_JS_OBJECTS(this, Telephony);
mRooted = true;
if (!mRooted) {
NS_HOLD_JS_OBJECTS(this, Telephony);
mRooted = true;
}
mCallsArray = calls;
} else {
NS_ENSURE_SUCCESS(rv, rv);
}
mCallsArray = calls;
}
aCalls->setObject(*calls);

View File

@ -118,18 +118,6 @@ public:
return mRIL;
}
nsPIDOMWindow*
Owner() const
{
return mOwner;
}
nsIScriptContext*
ScriptContext() const
{
return mScriptContext;
}
private:
Telephony();
~Telephony();

View File

@ -57,8 +57,8 @@ TelephonyCall::Create(Telephony* aTelephony, const nsAString& aNumber,
nsRefPtr<TelephonyCall> call = new TelephonyCall();
call->mOwner = aTelephony->Owner();
call->mScriptContext = aTelephony->ScriptContext();
call->BindToOwner(aTelephony->GetOwner());
call->mTelephony = aTelephony;
call->mNumber = aNumber;
call->mCallIndex = aCallIndex;

View File

@ -252,10 +252,9 @@ public class GeckoEvent {
}
}
public GeckoEvent(Location l, Address a) {
public GeckoEvent(Location l) {
mType = LOCATION_EVENT;
mLocation = l;
mAddress = a;
}
public GeckoEvent(int imeAction, int offset, int count) {

View File

@ -580,47 +580,10 @@ class GeckoSurfaceView
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
}
private class GeocoderTask extends AsyncTask<Location, Void, Void> {
protected Void doInBackground(Location... location) {
try {
List<Address> addresses = mGeocoder.getFromLocation(location[0].getLatitude(),
location[0].getLongitude(), 1);
// grab the first address. in the future,
// may want to expose multiple, or filter
// for best.
mLastGeoAddress = addresses.get(0);
GeckoAppShell.sendEventToGecko(new GeckoEvent(location[0], mLastGeoAddress));
} catch (Exception e) {
Log.w(LOG_FILE_NAME, "GeocoderTask "+e);
}
return null;
}
}
// geolocation
public void onLocationChanged(Location location)
{
if (mGeocoder == null)
mGeocoder = new Geocoder(getContext(), Locale.getDefault());
if (mLastGeoAddress == null) {
new GeocoderTask().execute(location);
}
else {
float[] results = new float[1];
Location.distanceBetween(location.getLatitude(),
location.getLongitude(),
mLastGeoAddress.getLatitude(),
mLastGeoAddress.getLongitude(),
results);
// pfm value. don't want to slam the
// geocoder with very similar values, so
// only call after about 100m
if (results[0] > 100)
new GeocoderTask().execute(location);
}
GeckoAppShell.sendEventToGecko(new GeckoEvent(location, mLastGeoAddress));
GeckoAppShell.sendEventToGecko(new GeckoEvent(location));
}
public void onProviderDisabled(String provider)
@ -825,9 +788,6 @@ class GeckoSurfaceView
ByteBuffer mSoftwareBuffer;
Bitmap mSoftwareBufferCopy;
Geocoder mGeocoder;
Address mLastGeoAddress;
final SynchronousQueue<Object> mSyncDraws = new SynchronousQueue<Object>();
}

View File

@ -42,6 +42,8 @@
#include "gfxFT2FontList.h"
#include "gfxImageSurface.h"
#include "nsXULAppAPI.h"
#include "nsIScreen.h"
#include "nsIScreenManager.h"
#include "cairo.h"
@ -57,6 +59,15 @@ static FT_Library gPlatformFTLibrary = NULL;
gfxAndroidPlatform::gfxAndroidPlatform()
{
FT_Init_FreeType(&gPlatformFTLibrary);
nsCOMPtr<nsIScreenManager> screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
nsCOMPtr<nsIScreen> screen;
screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
PRInt32 depth = 24;
screen->GetColorDepth(&depth);
mOffscreenFormat = depth == 16 ? gfxASurface::ImageFormatRGB16_565 :
gfxASurface::ImageFormatARGB32;
}
gfxAndroidPlatform::~gfxAndroidPlatform()

View File

@ -68,7 +68,7 @@ public:
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend) { aBackend = mozilla::gfx::BACKEND_SKIA; return true; }
virtual gfxImageFormat GetOffscreenFormat() { return gfxASurface::ImageFormatRGB16_565; }
virtual gfxImageFormat GetOffscreenFormat() { return mOffscreenFormat; }
mozilla::RefPtr<mozilla::gfx::ScaledFont>
GetScaledFontForFont(gfxFont *aFont);
@ -102,6 +102,9 @@ public:
virtual bool FontHintingEnabled() MOZ_OVERRIDE;
FT_Library GetFTLibrary();
private:
gfxImageFormat mOffscreenFormat;
};
#endif /* GFX_PLATFORM_ANDROID_H */

View File

@ -54,6 +54,8 @@ enum SensorType {
SENSOR_ORIENTATION,
SENSOR_ACCELERATION,
SENSOR_PROXIMITY,
SENSOR_LINEAR_ACCELERATION,
SENSOR_GYROSCOPE,
NUM_SENSOR_TYPE
};

View File

@ -5,6 +5,7 @@
#include "base/platform_thread.h"
#import <Foundation/Foundation.h>
#include <dlfcn.h>
#include "base/logging.h"
#include "base/scoped_nsautorelease_pool.h"
@ -51,3 +52,26 @@ void InitThreading() {
}
} // namespace base
// static
void PlatformThread::SetName(const char* name) {
// pthread_setname_np is only available in 10.6 or later, so test
// for it at runtime.
int (*dynamic_pthread_setname_np)(const char*);
*reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
dlsym(RTLD_DEFAULT, "pthread_setname_np");
if (!dynamic_pthread_setname_np)
return;
// Mac OS X does not expose the length limit of the name, so
// hardcode it.
const int kMaxNameLength = 63;
std::string shortened_name = std::string(name).substr(0, kMaxNameLength);
// pthread_setname() fails (harmlessly) in the sandbox, ignore when it does.
// See http://crbug.com/47058
// The name parameter is copied thus it's safe to release it after calling.
// Checked against the bionic implementation in bionic/libc/bionic/pthread.c
dynamic_pthread_setname_np(shortened_name.c_str());
}

View File

@ -61,6 +61,9 @@ void PlatformThread::Sleep(int duration_ms) {
sleep_time = remaining;
}
#ifndef OS_MACOSX
// Mac is implemented in platform_thread_mac.mm.
// static
void PlatformThread::SetName(const char* name) {
// The POSIX standard does not provide for naming threads, and neither Linux
@ -70,6 +73,7 @@ void PlatformThread::SetName(const char* name) {
// TODO(darin): decide whether stuffing the name in TLS or other in-memory
// structure would be useful for debugging or not.
}
#endif // !OS_MACOSX
namespace {

View File

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
13.0a1
14.0a1

View File

@ -54,6 +54,210 @@
namespace js {
namespace gcstats {
/* Except for the first and last, slices of less than 12ms are not reported. */
static const int64_t SLICE_MIN_REPORT_TIME = 12 * PRMJ_USEC_PER_MSEC;
class StatisticsSerializer
{
typedef Vector<char, 128, SystemAllocPolicy> CharBuffer;
CharBuffer buf_;
bool asJSON_;
bool needComma_;
bool oom_;
const static int MaxFieldValueLength = 128;
public:
enum Mode {
AsJSON = true,
AsText = false
};
StatisticsSerializer(Mode asJSON)
: buf_(), asJSON_(asJSON), needComma_(false), oom_(false)
{}
bool isJSON() { return asJSON_; }
bool isOOM() { return oom_; }
void endLine() {
if (!asJSON_) {
p("\n");
needComma_ = false;
}
}
void extra(const char *str) {
if (!asJSON_) {
needComma_ = false;
p(str);
}
}
void appendString(const char *name, const char *value) {
put(name, value, "", true);
}
void appendNumber(const char *name, const char *vfmt, const char *units, ...) {
va_list va;
va_start(va, units);
append(name, vfmt, va, units);
va_end(va);
}
void appendIfNonzeroMS(const char *name, double v) {
if (asJSON_ || v)
appendNumber(name, "%.1f", "ms", v);
}
void beginObject(const char *name) {
if (needComma_)
pJSON(", ");
if (asJSON_ && name) {
putQuoted(name);
pJSON(": ");
}
pJSON("{");
needComma_ = false;
}
void endObject() {
needComma_ = false;
pJSON("}");
needComma_ = true;
}
void beginArray(const char *name) {
if (needComma_)
pJSON(", ");
if (asJSON_)
putQuoted(name);
pJSON(": [");
needComma_ = false;
}
void endArray() {
needComma_ = false;
pJSON("]");
needComma_ = true;
}
jschar *finishJSString() {
char *buf = finishCString();
if (!buf)
return NULL;
size_t nchars = strlen(buf);
jschar *out = (jschar *)js_malloc(sizeof(jschar) * (nchars + 1));
if (!out) {
oom_ = true;
js_free(buf);
return NULL;
}
size_t outlen = nchars;
bool ok = InflateStringToBuffer(NULL, buf, nchars, out, &outlen);
js_free(buf);
if (!ok) {
oom_ = true;
js_free(out);
return NULL;
}
out[nchars] = 0;
return out;
}
char *finishCString() {
if (oom_)
return NULL;
buf_.append('\0');
char *buf = buf_.extractRawBuffer();
if (!buf)
oom_ = true;
return buf;
}
private:
void append(const char *name, const char *vfmt,
va_list va, const char *units)
{
char val[MaxFieldValueLength];
JS_vsnprintf(val, MaxFieldValueLength, vfmt, va);
put(name, val, units, false);
}
void p(const char *cstr) {
if (oom_)
return;
if (!buf_.append(cstr, strlen(cstr)))
oom_ = true;
}
void p(const char c) {
if (oom_)
return;
if (!buf_.append(c))
oom_ = true;
}
void pJSON(const char *str) {
if (asJSON_)
p(str);
}
void put(const char *name, const char *val, const char *units, bool valueIsQuoted) {
if (needComma_)
p(", ");
needComma_ = true;
putKey(name);
p(": ");
if (valueIsQuoted)
putQuoted(val);
else
p(val);
if (!asJSON_)
p(units);
}
void putQuoted(const char *str) {
pJSON("\"");
p(str);
pJSON("\"");
}
void putKey(const char *str) {
if (!asJSON_) {
p(str);
return;
}
p("\"");
const char *c = str;
while (*c) {
if (*c == ' ' || *c == '\t')
p('_');
else if (isupper(*c))
p(tolower(*c));
else if (*c == '+')
p("added_");
else if (*c == '-')
p("removed_");
else if (*c != '(' && *c != ')')
p(*c);
c++;
}
p("\"");
}
};
static const char *
ExplainReason(gcreason::Reason reason)
{
@ -70,57 +274,36 @@ ExplainReason(gcreason::Reason reason)
}
}
void
Statistics::fmt(const char *f, ...)
static double
t(int64_t t)
{
va_list va;
size_t off = strlen(buffer);
va_start(va, f);
JS_vsnprintf(buffer + off, BUFFER_SIZE - off, f, va);
va_end(va);
return double(t) / PRMJ_USEC_PER_MSEC;
}
void
Statistics::fmtIfNonzero(const char *name, double t)
static void
formatPhases(StatisticsSerializer &ss, const char *name, int64_t *times)
{
if (t) {
if (needComma)
fmt(", ");
fmt("%s: %.1f", name, t);
needComma = true;
}
ss.beginObject(name);
ss.appendIfNonzeroMS("Mark", t(times[PHASE_MARK]));
ss.appendIfNonzeroMS("Mark Roots", t(times[PHASE_MARK_ROOTS]));
ss.appendIfNonzeroMS("Mark Delayed", t(times[PHASE_MARK_DELAYED]));
ss.appendIfNonzeroMS("Mark Other", t(times[PHASE_MARK_OTHER]));
ss.appendIfNonzeroMS("Sweep", t(times[PHASE_SWEEP]));
ss.appendIfNonzeroMS("Sweep Object", t(times[PHASE_SWEEP_OBJECT]));
ss.appendIfNonzeroMS("Sweep String", t(times[PHASE_SWEEP_STRING]));
ss.appendIfNonzeroMS("Sweep Script", t(times[PHASE_SWEEP_SCRIPT]));
ss.appendIfNonzeroMS("Sweep Shape", t(times[PHASE_SWEEP_SHAPE]));
ss.appendIfNonzeroMS("Discard Code", t(times[PHASE_DISCARD_CODE]));
ss.appendIfNonzeroMS("Discard Analysis", t(times[PHASE_DISCARD_ANALYSIS]));
ss.appendIfNonzeroMS("XPConnect", t(times[PHASE_XPCONNECT]));
ss.appendIfNonzeroMS("Deallocate", t(times[PHASE_DESTROY]));
ss.endObject();
}
void
Statistics::formatPhases(int64_t *times)
bool
Statistics::formatData(StatisticsSerializer &ss)
{
needComma = false;
fmtIfNonzero("mark", t(times[PHASE_MARK]));
fmtIfNonzero("mark-roots", t(times[PHASE_MARK_ROOTS]));
fmtIfNonzero("mark-delayed", t(times[PHASE_MARK_DELAYED]));
fmtIfNonzero("mark-other", t(times[PHASE_MARK_OTHER]));
fmtIfNonzero("sweep", t(times[PHASE_SWEEP]));
fmtIfNonzero("sweep-obj", t(times[PHASE_SWEEP_OBJECT]));
fmtIfNonzero("sweep-string", t(times[PHASE_SWEEP_STRING]));
fmtIfNonzero("sweep-script", t(times[PHASE_SWEEP_SCRIPT]));
fmtIfNonzero("sweep-shape", t(times[PHASE_SWEEP_SHAPE]));
fmtIfNonzero("discard-code", t(times[PHASE_DISCARD_CODE]));
fmtIfNonzero("discard-analysis", t(times[PHASE_DISCARD_ANALYSIS]));
fmtIfNonzero("xpconnect", t(times[PHASE_XPCONNECT]));
fmtIfNonzero("deallocate", t(times[PHASE_DESTROY]));
}
/* Except for the first and last, slices of less than 12ms are not reported. */
static const int64_t SLICE_MIN_REPORT_TIME = 12 * PRMJ_USEC_PER_MSEC;
const char *
Statistics::formatData()
{
buffer[0] = 0x00;
int64_t total = 0, longest = 0;
for (SliceData *slice = slices.begin(); slice != slices.end(); slice++) {
total += slice->duration();
if (slice->duration() > longest)
@ -130,47 +313,70 @@ Statistics::formatData()
double mmu20 = computeMMU(20 * PRMJ_USEC_PER_MSEC);
double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
fmt("TotalTime: %.1fms, Type: %s", t(total), compartment ? "compartment" : "global");
fmt(", MMU(20ms): %d%%, MMU(50ms): %d%%", int(mmu20 * 100), int(mmu50 * 100));
if (slices.length() > 1)
fmt(", MaxPause: %.1f", t(longest));
ss.beginObject(NULL);
ss.appendNumber("Total Time", "%.1f", "ms", t(total));
ss.appendString("Type", compartment ? "compartment" : "global");
ss.appendNumber("MMU (20ms)", "%d", "%", int(mmu20 * 100));
ss.appendNumber("MMU (50ms)", "%d", "%", int(mmu50 * 100));
if (slices.length() > 1 || ss.isJSON())
ss.appendNumber("Max Pause", "%.1f", "ms", t(longest));
else
fmt(", Reason: %s", ExplainReason(slices[0].reason));
ss.appendString("Reason", ExplainReason(slices[0].reason));
if (nonincrementalReason || ss.isJSON()) {
ss.appendString("Nonincremental Reason",
nonincrementalReason ? nonincrementalReason : "none");
}
ss.appendNumber("+Chunks", "%d", "", counts[STAT_NEW_CHUNK]);
ss.appendNumber("-Chunks", "%d", "", counts[STAT_DESTROY_CHUNK]);
ss.endLine();
if (nonincrementalReason)
fmt(", NonIncrementalReason: %s", nonincrementalReason);
fmt(", +chunks: %d, -chunks: %d\n", counts[STAT_NEW_CHUNK], counts[STAT_DESTROY_CHUNK]);
if (slices.length() > 1) {
if (slices.length() > 1 || ss.isJSON()) {
ss.beginArray("Slices");
for (size_t i = 0; i < slices.length(); i++) {
int64_t width = slices[i].duration();
if (i != 0 && i != slices.length() - 1 && width < SLICE_MIN_REPORT_TIME &&
!slices[i].resetReason)
!slices[i].resetReason && !ss.isJSON())
{
continue;
}
fmt(" Slice %d @ %.1fms (Pause: %.1f, Reason: %s",
i,
t(slices[i].end - slices[0].start),
t(width),
ExplainReason(slices[i].reason));
ss.beginObject(NULL);
ss.extra(" ");
ss.appendNumber("Slice", "%d", "", i);
ss.appendNumber("Time", "%.1f", "ms", t(slices[i].end - slices[0].start));
ss.extra(" (");
ss.appendNumber("Pause", "%.1f", "", t(width));
ss.appendString("Reason", ExplainReason(slices[i].reason));
if (slices[i].resetReason)
fmt(", Reset: %s", slices[i].resetReason);
fmt("): ");
formatPhases(slices[i].phaseTimes);
fmt("\n");
ss.appendString("Reset", slices[i].resetReason);
ss.extra("): ");
formatPhases(ss, "times", slices[i].phaseTimes);
ss.endLine();
ss.endObject();
}
fmt(" Totals: ");
ss.endArray();
}
ss.extra(" Totals: ");
formatPhases(ss, "totals", phaseTimes);
ss.endObject();
formatPhases(phaseTimes);
fmt("\n");
return !ss.isOOM();
}
return buffer;
jschar *
Statistics::formatMessage()
{
StatisticsSerializer ss(StatisticsSerializer::AsText);
formatData(ss);
return ss.finishJSString();
}
jschar *
Statistics::formatJSON()
{
StatisticsSerializer ss(StatisticsSerializer::AsJSON);
formatData(ss);
return ss.finishJSString();
}
Statistics::Statistics(JSRuntime *rt)
@ -179,8 +385,7 @@ Statistics::Statistics(JSRuntime *rt)
fp(NULL),
fullFormat(false),
compartment(NULL),
nonincrementalReason(NULL),
needComma(false)
nonincrementalReason(NULL)
{
PodArrayZero(phaseTotals);
PodArrayZero(counts);
@ -209,9 +414,13 @@ Statistics::~Statistics()
{
if (fp) {
if (fullFormat) {
buffer[0] = 0x00;
formatPhases(phaseTotals);
fprintf(fp, "TOTALS\n%s\n\n-------\n", buffer);
StatisticsSerializer ss(StatisticsSerializer::AsText);
formatPhases(ss, "", phaseTotals);
char *msg = ss.finishCString();
if (msg) {
fprintf(fp, "TOTALS\n%s\n\n-------\n", msg);
js_free(msg);
}
}
if (fp != stdout && fp != stderr)
@ -219,12 +428,6 @@ Statistics::~Statistics()
}
}
double
Statistics::t(int64_t t)
{
return double(t) / PRMJ_USEC_PER_MSEC;
}
int64_t
Statistics::gcDuration()
{
@ -235,9 +438,13 @@ void
Statistics::printStats()
{
if (fullFormat) {
fprintf(fp, "GC(T+%.3fs) %s\n",
t(slices[0].start - startupTime) / 1000.0,
formatData());
StatisticsSerializer ss(StatisticsSerializer::AsText);
formatData(ss);
char *msg = ss.finishCString();
if (msg) {
fprintf(fp, "GC(T+%.3fs) %s\n", t(slices[0].start - startupTime) / 1000.0, msg);
js_free(msg);
}
} else {
fprintf(fp, "%f %f %f\n",
t(gcDuration()),
@ -301,10 +508,8 @@ Statistics::beginSlice(JSCompartment *comp, gcreason::Reason reason)
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback)
(*cb)(JS_TELEMETRY_GC_REASON, reason);
if (GCSliceCallback cb = runtime->gcSliceCallback) {
GCDescription desc(NULL, !!compartment);
(*cb)(runtime, first ? GC_CYCLE_BEGIN : GC_SLICE_BEGIN, desc);
}
if (GCSliceCallback cb = runtime->gcSliceCallback)
(*cb)(runtime, first ? GC_CYCLE_BEGIN : GC_SLICE_BEGIN, GCDescription(!!compartment));
}
void
@ -323,9 +528,9 @@ Statistics::endSlice()
if (GCSliceCallback cb = runtime->gcSliceCallback) {
if (last)
(*cb)(runtime, GC_CYCLE_END, GCDescription(formatData(), !!compartment));
(*cb)(runtime, GC_CYCLE_END, GCDescription(!!compartment));
else
(*cb)(runtime, GC_SLICE_END, GCDescription(NULL, !!compartment));
(*cb)(runtime, GC_SLICE_END, GCDescription(!!compartment));
}
}

View File

@ -76,7 +76,7 @@ enum Stat {
STAT_LIMIT
};
static const size_t BUFFER_SIZE = 8192;
class StatisticsSerializer;
struct Statistics {
Statistics(JSRuntime *rt);
@ -96,6 +96,9 @@ struct Statistics {
counts[s]++;
}
jschar *formatMessage();
jschar *formatJSON();
private:
JSRuntime *runtime;
@ -136,19 +139,12 @@ struct Statistics {
/* Number of events of this type for this GC. */
unsigned int counts[STAT_LIMIT];
char buffer[BUFFER_SIZE];
bool needComma;
void beginGC();
void endGC();
int64_t gcDuration();
double t(int64_t t);
void printStats();
void fmt(const char *f, ...);
void fmtIfNonzero(const char *name, double t);
void formatPhases(int64_t *times);
const char *formatData();
bool formatData(StatisticsSerializer &ss);
double computeMMU(int64_t resolution);
};

View File

@ -4284,7 +4284,7 @@ prop_iter_trace(JSTracer *trc, JSObject *obj)
static Class prop_iter_class = {
"PropertyIterator",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(1),
JS_PropertyStub, /* addProperty */
JS_PropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
@ -6445,23 +6445,10 @@ JS_ClearPendingException(JSContext *cx)
JS_PUBLIC_API(JSBool)
JS_ReportPendingException(JSContext *cx)
{
JSBool ok;
bool save;
AssertNoGC(cx);
CHECK_REQUEST(cx);
/*
* Set cx->generatingError to suppress the standard error-to-exception
* conversion done by all {js,JS}_Report* functions except for OOM. The
* cx->generatingError flag was added to suppress recursive divergence
* under js_ErrorToException, but it serves for our purposes here too.
*/
save = cx->generatingError;
cx->generatingError = JS_TRUE;
ok = js_ReportUncaughtException(cx);
cx->generatingError = save;
return ok;
return js_ReportUncaughtException(cx);
}
struct JSExceptionState {

View File

@ -120,7 +120,6 @@
#include "jsnum.h"
#include "jsobj.h"
#include "jsscope.h"
#include "jsstr.h"
#include "jswrapper.h"
#include "methodjit/MethodJIT.h"
#include "methodjit/StubCalls.h"

View File

@ -827,11 +827,11 @@ struct JSContext : js::ContextFriendFields
bool hasVersionOverride;
/* Exception state -- the exception member is a GC root by definition. */
JSBool throwing; /* is there a pending exception? */
js::Value exception; /* most-recently-thrown exception */
JSBool throwing; /* is there a pending exception? */
js::Value exception; /* most-recently-thrown exception */
/* Per-context run options. */
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
unsigned runOptions; /* see jsapi.h for JSOPTION_* */
public:
int32_t reportGranularity; /* see jsprobes.h */
@ -841,11 +841,8 @@ struct JSContext : js::ContextFriendFields
js::AutoResolving *resolvingList;
/*
* True if generating an error, to prevent runaway recursion.
* NB: generatingError packs with throwing below.
*/
bool generatingError;
/* True if generating an error, to prevent runaway recursion. */
bool generatingError;
/* GC heap compartment. */
JSCompartment *compartment;

View File

@ -1074,7 +1074,6 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
const JSErrorFormatString *errorString;
JSExnType exn;
jsval tv[4];
JSBool ok;
JSObject *errProto, *errObject;
JSString *messageStr, *filenameStr;
@ -1083,7 +1082,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
*/
JS_ASSERT(reportp);
if (JSREPORT_IS_WARNING(reportp->flags))
return JS_FALSE;
return false;
/* Find the exception index associated with this error. */
errorNumber = (JSErrNum) reportp->errorNumber;
@ -1106,19 +1105,12 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
* with the given error number.
*/
if (exn == JSEXN_NONE)
return JS_FALSE;
return false;
/*
* Prevent runaway recursion, via cx->generatingError. If an out-of-memory
* error occurs, no exception object will be created, but we don't assume
* that OOM is the only kind of error that subroutines of this function
* called below might raise.
*/
/* Prevent infinite recursion. */
if (cx->generatingError)
return JS_FALSE;
MUST_FLOW_THROUGH("out");
cx->generatingError = JS_TRUE;
return false;
AutoScopedAssign<bool> asa(&cx->generatingError, true);
/* Protect the newly-created strings below from nesting GCs. */
PodArrayZero(tv);
@ -1129,45 +1121,32 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
* exception constructor name in the scope chain of the current context's
* top stack frame, or in the global object if no frame is active.
*/
ok = js_GetClassPrototype(cx, NULL, GetExceptionProtoKey(exn), &errProto);
if (!ok)
goto out;
if (!js_GetClassPrototype(cx, NULL, GetExceptionProtoKey(exn), &errProto))
return false;
tv[0] = OBJECT_TO_JSVAL(errProto);
errObject = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL);
if (!errObject) {
ok = JS_FALSE;
goto out;
}
if (!(errObject = NewObjectWithGivenProto(cx, &ErrorClass, errProto, NULL)))
return false;
tv[1] = OBJECT_TO_JSVAL(errObject);
messageStr = JS_NewStringCopyZ(cx, message);
if (!messageStr) {
ok = JS_FALSE;
goto out;
}
if (!(messageStr = JS_NewStringCopyZ(cx, message)))
return false;
tv[2] = STRING_TO_JSVAL(messageStr);
filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
if (!filenameStr) {
ok = JS_FALSE;
goto out;
}
if (!(filenameStr = JS_NewStringCopyZ(cx, reportp->filename)))
return false;
tv[3] = STRING_TO_JSVAL(filenameStr);
ok = InitExnPrivate(cx, errObject, messageStr, filenameStr,
reportp->lineno, reportp, exn);
if (!ok)
goto out;
if (!InitExnPrivate(cx, errObject, messageStr, filenameStr,
reportp->lineno, reportp, exn)) {
return false;
}
JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
/* Flag the error report passed in to indicate an exception was raised. */
reportp->flags |= JSREPORT_EXCEPTION;
out:
cx->generatingError = JS_FALSE;
return ok;
return true;
}
JSBool

View File

@ -717,6 +717,18 @@ SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
return old;
}
jschar *
GCDescription::formatMessage(JSRuntime *rt) const
{
return rt->gcStats.formatMessage();
}
jschar *
GCDescription::formatJSON(JSRuntime *rt) const
{
return rt->gcStats.formatJSON();
}
JS_FRIEND_API(bool)
WantGCSlice(JSRuntime *rt)
{

View File

@ -699,12 +699,14 @@ enum GCProgress {
GC_CYCLE_END
};
struct GCDescription {
const char *logMessage;
struct JS_FRIEND_API(GCDescription) {
bool isCompartment;
GCDescription(const char *msg, bool isCompartment)
: logMessage(msg), isCompartment(isCompartment) {}
GCDescription(bool isCompartment)
: isCompartment(isCompartment) {}
jschar *formatMessage(JSRuntime *rt) const;
jschar *formatJSON(JSRuntime *rt) const;
};
typedef void

View File

@ -6931,7 +6931,7 @@ mjit::Compiler::jsop_regexp()
*/
analyze::SSAUseChain *uses =
analysis->useChain(analyze::SSAValue::PushedValue(PC - script->code, 0));
if (uses && uses->popped && !uses->next) {
if (uses && uses->popped && !uses->next && !reobj->global() && !reobj->sticky()) {
jsbytecode *use = script->code + uses->offset;
uint32_t which = uses->u.which;
if (JSOp(*use) == JSOP_CALLPROP) {

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1 +0,0 @@

View File

@ -1,7 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1 +0,0 @@

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1 +0,0 @@

View File

@ -1,40 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

View File

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

Some files were not shown because too many files have changed in this diff Show More