diff --git a/.hgtags b/.hgtags index b357128e0106..9211295d8858 100644 --- a/.hgtags +++ b/.hgtags @@ -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 diff --git a/accessible/src/base/AccIterator.cpp b/accessible/src/base/AccIterator.cpp index 85e3e4d4400d..58c4de6af7b1 100644 --- a/accessible/src/base/AccIterator.cpp +++ b/accessible/src/base/AccIterator.cpp @@ -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 refElm; - mXBLDocument->GetAnonymousElementByAttribute(mBindingParent, - NS_LITERAL_STRING("anonid"), - aID, - getter_AddRefs(refElm)); - nsCOMPtr 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 refDOMElm; + nsCOMPtr xblDocument = + do_QueryInterface(mContent->OwnerDoc()); + + // Check inside the binding the element is contained in. + nsIContent* bindingParent = mContent->GetBindingParent(); + if (bindingParent) { + nsCOMPtr bindingParentElm = do_QueryInterface(bindingParent); + xblDocument->GetAnonymousElementByAttribute(bindingParentElm, + NS_LITERAL_STRING("anonid"), + aID, + getter_AddRefs(refDOMElm)); + nsCOMPtr refElm = do_QueryInterface(refDOMElm); + if (refElm) + return refElm; + } + + // Check inside the binding of the element. + if (mContent->OwnerDoc()->BindingManager()->GetBinding(mContent)) { + nsCOMPtr elm = do_QueryInterface(mContent); + xblDocument->GetAnonymousElementByAttribute(elm, + NS_LITERAL_STRING("anonid"), + aID, + getter_AddRefs(refDOMElm)); + nsCOMPtr refElm = do_QueryInterface(refDOMElm); + return refElm; + } + + return nsnull; } nsAccessible* diff --git a/accessible/src/base/AccIterator.h b/accessible/src/base/AccIterator.h index d91c4ed86960..0be6880a4dd2 100644 --- a/accessible/src/base/AccIterator.h +++ b/accessible/src/base/AccIterator.h @@ -291,11 +291,8 @@ private: IDRefsIterator operator = (const IDRefsIterator&); nsString mIDs; + nsIContent* mContent; nsAString::index_type mCurrIdx; - - nsIDocument* mDocument; - nsCOMPtr mXBLDocument; - nsCOMPtr mBindingParent; }; /** diff --git a/accessible/src/msaa/CAccessibleComponent.cpp b/accessible/src/msaa/CAccessibleComponent.cpp index 0036bba5cf48..349effe5b462 100644 --- a/accessible/src/msaa/CAccessibleComponent.cpp +++ b/accessible/src/msaa/CAccessibleComponent.cpp @@ -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 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 acc(do_QueryObject(this)); if (acc->IsDefunct()) return E_FAIL; - nsCOMPtr styleDecl = - nsWinUtils::GetComputedStyleDeclaration(acc->GetContent()); - NS_ENSURE_STATE(styleDecl); + nsIFrame* frame = acc->GetFrame(); + if (frame) + *aBackground = frame->GetStyleBackground()->mBackgroundColor; - nsCOMPtr cssGenericValue; - styleDecl->GetPropertyCSSValue(aPropName, getter_AddRefs(cssGenericValue)); - - nsCOMPtr cssValue = - do_QueryInterface(cssGenericValue); - if (!cssValue) - return E_FAIL; - - nsCOMPtr rgbColor; - nsresult rv = cssValue->GetRGBColorValue(getter_AddRefs(rgbColor)); - if (NS_FAILED(rv) || !rgbColor) - return GetHRESULT(rv); - - nsCOMPtr rgbaColor(do_QueryInterface(rgbColor)); - if (!rgbaColor) - return GetHRESULT(rv); - - // get alpha - nsCOMPtr 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 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 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 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; } diff --git a/accessible/src/msaa/CAccessibleComponent.h b/accessible/src/msaa/CAccessibleComponent.h index 25e874ac023a..4157771c1b42 100644 --- a/accessible/src/msaa/CAccessibleComponent.h +++ b/accessible/src/msaa/CAccessibleComponent.h @@ -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 diff --git a/accessible/tests/mochitest/relations.js b/accessible/tests/mochitest/relations.js index 6fd4a0c7b410..f41fe0e218ff 100644 --- a/accessible/tests/mochitest/relations.js +++ b/accessible/tests/mochitest/relations.js @@ -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. diff --git a/accessible/tests/mochitest/relations/Makefile.in b/accessible/tests/mochitest/relations/Makefile.in index 4a1eca4d497a..a447b4699a01 100644 --- a/accessible/tests/mochitest/relations/Makefile.in +++ b/accessible/tests/mochitest/relations/Makefile.in @@ -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) diff --git a/accessible/tests/mochitest/relations/test_bindings.xhtml b/accessible/tests/mochitest/relations/test_bindings.xhtml new file mode 100644 index 000000000000..65a7a08752cb --- /dev/null +++ b/accessible/tests/mochitest/relations/test_bindings.xhtml @@ -0,0 +1,103 @@ + + + + Accessible relations for bindings + + + + + + + + + + +
+
+
+
+ + + + + +
+ + + + + + + + + + + + + + Mozilla Bug 421242 + + +

+ +
+  
+
+ + +
+ + diff --git a/accessible/tests/mochitest/relations/test_ui_modalprompt.html b/accessible/tests/mochitest/relations/test_ui_modalprompt.html new file mode 100644 index 000000000000..8ac2e6045e4c --- /dev/null +++ b/accessible/tests/mochitest/relations/test_ui_modalprompt.html @@ -0,0 +1,95 @@ + + + + Modal prompts + + + + + + + + + + + + + + + + + + + Mozilla Bug 661293 + +
+

+ +
+  
+ + + diff --git a/browser/base/content/test/browser_pageInfo.js b/browser/base/content/test/browser_pageInfo.js index 8dca2c10f110..c0159380cdcb 100644 --- a/browser/base/content/test/browser_pageInfo.js +++ b/browser/base/content/test/browser_pageInfo.js @@ -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(); diff --git a/browser/config/version.txt b/browser/config/version.txt index d4157f8df484..644225a35f36 100644 --- a/browser/config/version.txt +++ b/browser/config/version.txt @@ -1 +1 @@ -13.0a1 +14.0a1 diff --git a/browser/themes/winstripe/browser-aero.css b/browser/themes/winstripe/browser-aero.css index c1c9df5077e6..1bca806e2d84 100644 --- a/browser/themes/winstripe/browser-aero.css +++ b/browser/themes/winstripe/browser-aero.css @@ -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; diff --git a/config/milestone.txt b/config/milestone.txt index f780391e9db5..17f7a63fad30 100644 --- a/config/milestone.txt +++ b/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -13.0a1 +14.0a1 diff --git a/content/base/test/test_XHR_timeout.js b/content/base/test/test_XHR_timeout.js index 408d33874d3a..bbe95650b7c2 100644 --- a/content/base/test/test_XHR_timeout.js +++ b/content/base/test/test_XHR_timeout.js @@ -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 diff --git a/content/events/test/test_eventctors.html b/content/events/test/test_eventctors.html index 4efecf7c6037..516e9e17e75c 100644 --- a/content/events/test/test_eventctors.html +++ b/content/events/test/test_eventctors.html @@ -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; } diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 4311a5196442..64664fbad750 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -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() { diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index d672d92484c7..845f556b5815 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -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 diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index 5885454b460b..311edab11809 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -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) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 51049168fd08..b537f582fb43 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -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 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 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 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 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 diff --git a/dom/base/nsWindowMemoryReporter.cpp b/dom/base/nsWindowMemoryReporter.cpp index b94e7afe6834..9be4e1bc356a 100644 --- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -53,7 +53,7 @@ nsWindowMemoryReporter::Init() NS_RegisterMemoryMultiReporter(new nsWindowMemoryReporter()); } -static bool +static void AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr) { nsCOMPtr 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//top= (inner=)/inner-window(id=, uri=) + // explicit/window-objects/top(, id=)//window()/... + // + // The path we give for "other" windows is as follows: + // + // explicit/window-objects/top(none)/window()/... // // Where: - // - is active, cached, or other, as described above. + // - is "active" or "cached", as described above. // - is the window id (nsPIDOMWindow::WindowID()) of // the top outer window (i.e. tab, or top level chrome window). - // - is the window id of the top window's inner - // window. - // - is the window id of the inner window in question. - // - is the URI per above description. + // - 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. + // - 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//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; diff --git a/dom/contacts/fallback/ContactDB.jsm b/dom/contacts/fallback/ContactDB.jsm index c1a42582eaca..ad68beb9a444 100644 --- a/dom/contacts/fallback/ContactDB.jsm +++ b/dom/contacts/fallback/ContactDB.jsm @@ -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) diff --git a/dom/contacts/tests/test_contacts_basics.html b/dom/contacts/tests/test_contacts_basics.html index 0b59521de052..546aff74a471 100644 --- a/dom/contacts/tests/test_contacts_basics.html +++ b/dom/contacts/tests/test_contacts_basics.html @@ -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 () { diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index feb00dd2e4b8..56865fa8cf7a 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -463,7 +463,7 @@ IDBCursor::GetDirection(nsAString& aDirection) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - switch(mDirection) { + switch (mDirection) { case NEXT: aDirection.AssignLiteral("next"); break; diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index 4db736cb995c..9729b26233ac 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -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; diff --git a/dom/interfaces/base/nsIDOMNavigator.idl b/dom/interfaces/base/nsIDOMNavigator.idl index 90bddee82d9b..2df1d2294d2a 100644 --- a/dom/interfaces/base/nsIDOMNavigator.idl +++ b/dom/interfaces/base/nsIDOMNavigator.idl @@ -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 diff --git a/dom/interfaces/geolocation/Makefile.in b/dom/interfaces/geolocation/Makefile.in index 67655d343924..e775bdc5af9a 100644 --- a/dom/interfaces/geolocation/Makefile.in +++ b/dom/interfaces/geolocation/Makefile.in @@ -49,7 +49,6 @@ GRE_MODULE = 1 XPIDLSRCS = \ nsIDOMGeoGeolocation.idl \ nsIDOMGeoPosition.idl \ - nsIDOMGeoPositionAddress.idl \ nsIDOMGeoPositionCoords.idl \ nsIDOMGeoPositionCallback.idl \ nsIDOMGeoPositionError.idl \ diff --git a/dom/interfaces/geolocation/nsIDOMGeoPosition.idl b/dom/interfaces/geolocation/nsIDOMGeoPosition.idl index 6895356b8a83..ee6c19ff1c28 100644 --- a/dom/interfaces/geolocation/nsIDOMGeoPosition.idl +++ b/dom/interfaces/geolocation/nsIDOMGeoPosition.idl @@ -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; - }; diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index c81f30fd0545..459514bf8411 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -753,6 +753,16 @@ ContentChild::RecvDeviceMotionChanged(const long int& type, return true; } +bool +ContentChild::RecvNeedsCalibration() +{ + nsCOMPtr dmu = + do_GetService(NS_DEVICE_MOTION_CONTRACTID); + if (dmu) + dmu->NeedsCalibration(); + return true; +} + bool ContentChild::RecvScreenSizeChanged(const gfxIntSize& size) { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 206bf8342002..fafbe50bacd5 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -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); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 8507ac9a48c8..a237c87dbfff 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1291,6 +1291,12 @@ ContentParent::OnMotionChange(nsIDeviceMotionData *aDeviceData) { return NS_OK; } +NS_IMETHODIMP +ContentParent::NeedsCalibration() { + unused << SendNeedsCalibration(); + return NS_OK; +} + } // namespace dom } // namespace mozilla diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 32efef5e119a..2e2823aa5600 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -134,6 +134,7 @@ child: AddPermission(Permission permission); DeviceMotionChanged(long type, double x, double y, double z); + NeedsCalibration(); ScreenSizeChanged(gfxIntSize size); diff --git a/dom/src/geolocation/nsGeoPosition.cpp b/dom/src/geolocation/nsGeoPosition.cpp index b750b475435f..8981ef7a8144 100644 --- a/dom/src/geolocation/nsGeoPosition.cpp +++ b/dom/src/geolocation/nsGeoPosition.cpp @@ -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; -} - diff --git a/dom/src/geolocation/nsGeoPosition.h b/dom/src/geolocation/nsGeoPosition.h index c763b5becd85..a7a29770251f 100644 --- a/dom/src/geolocation/nsGeoPosition.h +++ b/dom/src/geolocation/nsGeoPosition.h @@ -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 mCoords; - nsRefPtr mAddress; }; #endif /* nsGeoPosition_h */ diff --git a/dom/src/geolocation/nsGeoPositionIPCSerialiser.h b/dom/src/geolocation/nsGeoPositionIPCSerialiser.h index f4597f8a52fd..89d0c9215148 100644 --- a/dom/src/geolocation/nsGeoPositionIPCSerialiser.h +++ b/dom/src/geolocation/nsGeoPositionIPCSerialiser.h @@ -41,98 +41,11 @@ #include "nsGeoPosition.h" #include "nsIDOMGeoPosition.h" -typedef nsIDOMGeoPositionAddress *GeoPositionAddress; typedef nsGeoPositionCoords *GeoPositionCoords; typedef nsIDOMGeoPosition *GeoPosition; namespace IPC { -template <> -struct ParamTraits -{ - 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, ®ion ) && - 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 { @@ -235,11 +148,6 @@ struct ParamTraits aParam->GetCoords(getter_AddRefs(coords)); GeoPositionCoords simpleCoords = static_cast(coords.get()); WriteParam(aMsg, simpleCoords); - - nsCOMPtr 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 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; }; diff --git a/dom/system/Makefile.in b/dom/system/Makefile.in index ce9346ba491e..b5b2062fa996 100644 --- a/dom/system/Makefile.in +++ b/dom/system/Makefile.in @@ -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. diff --git a/dom/system/android/Makefile.in b/dom/system/android/Makefile.in index 48cf9473c350..6f79c35fd085 100644 --- a/dom/system/android/Makefile.in +++ b/dom/system/android/Makefile.in @@ -59,6 +59,7 @@ CPPSRCS = \ $(NULL) LOCAL_INCLUDES += -I$(topsrcdir)/dom/src/geolocation \ + -I$(topsrcdir)/content/events/src $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/dom/system/cocoa/Makefile.in b/dom/system/cocoa/Makefile.in index bbc3d49fe454..7853d19a71d5 100644 --- a/dom/system/cocoa/Makefile.in +++ b/dom/system/cocoa/Makefile.in @@ -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) diff --git a/dom/system/cocoa/nsDeviceMotionSystem.mm b/dom/system/cocoa/nsDeviceMotionSystem.mm index 6fc0385c2ee6..bdeefdf679d5 100644 --- a/dom/system/cocoa/nsDeviceMotionSystem.mm +++ b/dom/system/cocoa/nsDeviceMotionSystem.mm @@ -42,8 +42,9 @@ #include #include -#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(); } diff --git a/dom/system/cocoa/smslib.h b/dom/system/cocoa/smslib.h new file mode 100644 index 000000000000..2f0b2664e459 --- /dev/null +++ b/dom/system/cocoa/smslib.h @@ -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 + * + * or contact + * Daniel Griscom + * Suitable Systems + * 1 Centre Street, Suite 204 + * Wakefield, MA 01880 + * (781) 665-0053 + * + */ + +#import + +#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); + diff --git a/dom/system/cocoa/smslib.mm b/dom/system/cocoa/smslib.mm new file mode 100644 index 000000000000..8761a81f48fa --- /dev/null +++ b/dom/system/cocoa/smslib.mm @@ -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 + * + * or contact + * Daniel Griscom + * Suitable Systems + * 1 Centre Street, Suite 204 + * Wakefield, MA 01880 + * (781) 665-0053 + * + */ + +#import +#import +#import +#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; +} + diff --git a/dom/system/nsDeviceMotion.cpp b/dom/system/nsDeviceMotion.cpp index 9c2230c63893..c1048ac9fcc2 100644 --- a/dom/system/nsDeviceMotion.cpp +++ b/dom/system/nsDeviceMotion.cpp @@ -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::index_type NoIndex = nsTArray::NoIndex; @@ -117,21 +120,16 @@ NS_IMPL_ISUPPORTS2(nsDeviceMotion, nsIDeviceMotion, nsIDeviceMotionUpdate) nsDeviceMotion::nsDeviceMotion() : mStarted(false), - mUpdateInterval(50), /* default to 50 ms */ mEnabled(true) { nsCOMPtr 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 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 listeners = mListeners; + for (PRUint32 i = listeners.Count(); i > 0 ; ) { + --i; + listeners[i]->NeedsCalibration(); + } + + nsCOMArray 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 pwindow = do_QueryInterface(windowListeners[i]); + if (!pwindow || + !pwindow->GetOuterWindow() || + pwindow->GetOuterWindow()->IsBackground()) + continue; + + nsCOMPtr domdoc; + windowListeners[i]->GetDocument(getter_AddRefs(domdoc)); + + if (domdoc) { + nsCOMPtr target = do_QueryInterface(windowListeners[i]); + FireNeedsCalibration(domdoc, target); + } + } + + return NS_OK; +} + +void +nsDeviceMotion::FireNeedsCalibration(nsIDOMDocument *domdoc, + nsIDOMEventTarget *target) +{ + nsCOMPtr event; + domdoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event)); + if (!event) + return; + + event->InitEvent(NS_LITERAL_STRING("compassneedscalibration"), true, false); + nsCOMPtr 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 event; - bool defaultActionEnabled = true; domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event)); nsCOMPtr me = do_QueryInterface(event); if (!me) { return; -} - - // Currently acceleration as determined includes gravity. - nsRefPtr 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 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(); + } diff --git a/dom/system/nsDeviceMotion.h b/dom/system/nsDeviceMotion.h index e2bada95fe6e..1618a6c73b57 100644 --- a/dom/system/nsDeviceMotion.h +++ b/dom/system/nsDeviceMotion.h @@ -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 mLastAcceleration; + nsRefPtr mLastAccelerationIncluduingGravity; + nsRefPtr mLastRotationRate; + }; #endif diff --git a/dom/system/unix/Makefile.in b/dom/system/unix/Makefile.in index fa443281fea6..7414673faeee 100644 --- a/dom/system/unix/Makefile.in +++ b/dom/system/unix/Makefile.in @@ -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 diff --git a/dom/system/unix/nsDeviceMotionSystem.cpp b/dom/system/unix/nsDeviceMotionSystem.cpp index 21e863e78498..7baaeb4aa197 100644 --- a/dom/system/unix/nsDeviceMotionSystem.cpp +++ b/dom/system/unix/nsDeviceMotionSystem.cpp @@ -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); } diff --git a/dom/system/windows/Makefile.in b/dom/system/windows/Makefile.in index 551a54921bfc..cd8319e75428 100644 --- a/dom/system/windows/Makefile.in +++ b/dom/system/windows/Makefile.in @@ -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 = \ diff --git a/dom/system/windows/nsDeviceMotionSystem.cpp b/dom/system/windows/nsDeviceMotionSystem.cpp index 767b9eca1a48..5ad353ae5fd4 100644 --- a/dom/system/windows/nsDeviceMotionSystem.cpp +++ b/dom/system/windows/nsDeviceMotionSystem.cpp @@ -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); } diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp index 6bec4e5237cd..fd7d162fc4c8 100644 --- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -164,8 +164,8 @@ Telephony::Create(nsPIDOMWindow* aOwner, nsIRadioInterfaceLayer* aRIL) nsRefPtr 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); diff --git a/dom/telephony/Telephony.h b/dom/telephony/Telephony.h index c374331f51ba..c602737b73da 100644 --- a/dom/telephony/Telephony.h +++ b/dom/telephony/Telephony.h @@ -118,18 +118,6 @@ public: return mRIL; } - nsPIDOMWindow* - Owner() const - { - return mOwner; - } - - nsIScriptContext* - ScriptContext() const - { - return mScriptContext; - } - private: Telephony(); ~Telephony(); diff --git a/dom/telephony/TelephonyCall.cpp b/dom/telephony/TelephonyCall.cpp index 81c7c0b2b717..421167a0d388 100644 --- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -57,8 +57,8 @@ TelephonyCall::Create(Telephony* aTelephony, const nsAString& aNumber, nsRefPtr call = new TelephonyCall(); - call->mOwner = aTelephony->Owner(); - call->mScriptContext = aTelephony->ScriptContext(); + call->BindToOwner(aTelephony->GetOwner()); + call->mTelephony = aTelephony; call->mNumber = aNumber; call->mCallIndex = aCallIndex; diff --git a/embedding/android/GeckoEvent.java b/embedding/android/GeckoEvent.java index c3f4e892b517..3d178baf87fa 100644 --- a/embedding/android/GeckoEvent.java +++ b/embedding/android/GeckoEvent.java @@ -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) { diff --git a/embedding/android/GeckoSurfaceView.java b/embedding/android/GeckoSurfaceView.java index 385c8d1e29ed..77649a447cf7 100644 --- a/embedding/android/GeckoSurfaceView.java +++ b/embedding/android/GeckoSurfaceView.java @@ -580,47 +580,10 @@ class GeckoSurfaceView GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); } - private class GeocoderTask extends AsyncTask { - protected Void doInBackground(Location... location) { - try { - List
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 mSyncDraws = new SynchronousQueue(); } diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index 0a1d788a5d41..1540b5eddbcc 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -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 screenMgr = do_GetService("@mozilla.org/gfx/screenmanager;1"); + nsCOMPtr screen; + screenMgr->GetPrimaryScreen(getter_AddRefs(screen)); + PRInt32 depth = 24; + screen->GetColorDepth(&depth); + + mOffscreenFormat = depth == 16 ? gfxASurface::ImageFormatRGB16_565 : + gfxASurface::ImageFormatARGB32; } gfxAndroidPlatform::~gfxAndroidPlatform() diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index 851525895f64..0b85749f10f1 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -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 GetScaledFontForFont(gfxFont *aFont); @@ -102,6 +102,9 @@ public: virtual bool FontHintingEnabled() MOZ_OVERRIDE; FT_Library GetFTLibrary(); + +private: + gfxImageFormat mOffscreenFormat; }; #endif /* GFX_PLATFORM_ANDROID_H */ diff --git a/hal/HalSensor.h b/hal/HalSensor.h index de4d8edac458..521c061787a7 100644 --- a/hal/HalSensor.h +++ b/hal/HalSensor.h @@ -54,6 +54,8 @@ enum SensorType { SENSOR_ORIENTATION, SENSOR_ACCELERATION, SENSOR_PROXIMITY, + SENSOR_LINEAR_ACCELERATION, + SENSOR_GYROSCOPE, NUM_SENSOR_TYPE }; diff --git a/ipc/chromium/src/base/platform_thread_mac.mm b/ipc/chromium/src/base/platform_thread_mac.mm index b055b8ace175..ef558a796847 100644 --- a/ipc/chromium/src/base/platform_thread_mac.mm +++ b/ipc/chromium/src/base/platform_thread_mac.mm @@ -5,6 +5,7 @@ #include "base/platform_thread.h" #import +#include #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(&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()); +} + diff --git a/ipc/chromium/src/base/platform_thread_posix.cc b/ipc/chromium/src/base/platform_thread_posix.cc index e3f49c7cd657..aa4f66157dc5 100644 --- a/ipc/chromium/src/base/platform_thread_posix.cc +++ b/ipc/chromium/src/base/platform_thread_posix.cc @@ -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 { diff --git a/js/src/config/milestone.txt b/js/src/config/milestone.txt index f780391e9db5..17f7a63fad30 100644 --- a/js/src/config/milestone.txt +++ b/js/src/config/milestone.txt @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -13.0a1 +14.0a1 diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index 607102d9eaec..1d7fd64ad525 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -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 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)); } } diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 31b8d5d699e8..6767ccade2ac 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -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); }; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 8b9f3a048e7e..1585f034ccba 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -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 { diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index c1cd20e4fc21..ed441d55e437 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -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" diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 32ac7340c993..c39036c7bf29 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -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; diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 3c83f78e55d2..6e97dae5825f 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -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 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 diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index f4bd7aa16116..7a25917f3bea 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -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) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index b4d2f0418264..afdb0d5e56c3 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -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 diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index aff5cc39773d..0305d27f27c7 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -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) { diff --git a/js/src/tests/ecma_2/browser.js b/js/src/tests/ecma_2/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/ecma_2/browser.js +++ b/js/src/tests/ecma_2/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/ecma_3/Date/browser.js b/js/src/tests/ecma_3/Date/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/ecma_3/Date/browser.js +++ b/js/src/tests/ecma_3/Date/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/ecma_3/browser.js b/js/src/tests/ecma_3/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/ecma_3/browser.js +++ b/js/src/tests/ecma_3/browser.js @@ -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 ***** */ diff --git a/js/src/tests/ecma_3/shell.js b/js/src/tests/ecma_3/shell.js index 789059f6b15a..e69de29bb2d1 100644 --- a/js/src/tests/ecma_3/shell.js +++ b/js/src/tests/ecma_3/shell.js @@ -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 ***** */ - diff --git a/js/src/tests/ecma_3_1/browser.js b/js/src/tests/ecma_3_1/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/ecma_3_1/browser.js +++ b/js/src/tests/ecma_3_1/browser.js @@ -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 ***** */ diff --git a/js/src/tests/ecma_3_1/shell.js b/js/src/tests/ecma_3_1/shell.js index 789059f6b15a..e69de29bb2d1 100644 --- a/js/src/tests/ecma_3_1/shell.js +++ b/js/src/tests/ecma_3_1/shell.js @@ -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 ***** */ - diff --git a/js/src/tests/ecma_5/Array/browser.js b/js/src/tests/ecma_5/Array/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Array/browser.js +++ b/js/src/tests/ecma_5/Array/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/Expressions/shell.js b/js/src/tests/ecma_5/Expressions/shell.js index 9c3e4eaf81fa..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Expressions/shell.js +++ b/js/src/tests/ecma_5/Expressions/shell.js @@ -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/ - */ - diff --git a/js/src/tests/ecma_5/Function/browser.js b/js/src/tests/ecma_5/Function/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Function/browser.js +++ b/js/src/tests/ecma_5/Function/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/Global/browser.js b/js/src/tests/ecma_5/Global/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Global/browser.js +++ b/js/src/tests/ecma_5/Global/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/JSON/browser.js b/js/src/tests/ecma_5/JSON/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/JSON/browser.js +++ b/js/src/tests/ecma_5/JSON/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/Object/browser.js b/js/src/tests/ecma_5/Object/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Object/browser.js +++ b/js/src/tests/ecma_5/Object/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/RegExp/browser.js b/js/src/tests/ecma_5/RegExp/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/RegExp/browser.js +++ b/js/src/tests/ecma_5/RegExp/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/String/browser.js b/js/src/tests/ecma_5/String/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/String/browser.js +++ b/js/src/tests/ecma_5/String/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/Types/browser.js b/js/src/tests/ecma_5/Types/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/Types/browser.js +++ b/js/src/tests/ecma_5/Types/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/browser.js b/js/src/tests/ecma_5/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/browser.js +++ b/js/src/tests/ecma_5/browser.js @@ -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 ***** */ diff --git a/js/src/tests/ecma_5/eval/browser.js b/js/src/tests/ecma_5/eval/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/eval/browser.js +++ b/js/src/tests/ecma_5/eval/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/extensions/browser.js b/js/src/tests/ecma_5/extensions/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/extensions/browser.js +++ b/js/src/tests/ecma_5/extensions/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/ecma_5/misc/browser.js b/js/src/tests/ecma_5/misc/browser.js index 8b137891791f..e69de29bb2d1 100644 --- a/js/src/tests/ecma_5/misc/browser.js +++ b/js/src/tests/ecma_5/misc/browser.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/js1_1/browser.js b/js/src/tests/js1_1/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/js1_1/browser.js +++ b/js/src/tests/js1_1/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/js1_1/shell.js b/js/src/tests/js1_1/shell.js index 086eec9fd35e..e69de29bb2d1 100644 --- a/js/src/tests/js1_1/shell.js +++ b/js/src/tests/js1_1/shell.js @@ -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 ***** */ - - diff --git a/js/src/tests/js1_2/browser.js b/js/src/tests/js1_2/browser.js index 6774b3998877..e69de29bb2d1 100644 --- a/js/src/tests/js1_2/browser.js +++ b/js/src/tests/js1_2/browser.js @@ -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 ***** */ diff --git a/js/src/tests/js1_2/shell.js b/js/src/tests/js1_2/shell.js index 008c7f189e18..e69de29bb2d1 100644 --- a/js/src/tests/js1_2/shell.js +++ b/js/src/tests/js1_2/shell.js @@ -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 ***** */ - - diff --git a/js/src/tests/js1_2/version120/browser.js b/js/src/tests/js1_2/version120/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/js1_2/version120/browser.js +++ b/js/src/tests/js1_2/version120/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/js1_3/browser.js b/js/src/tests/js1_3/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/js1_3/browser.js +++ b/js/src/tests/js1_3/browser.js @@ -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 ***** */ diff --git a/js/src/tests/js1_3/shell.js b/js/src/tests/js1_3/shell.js index 008c7f189e18..e69de29bb2d1 100644 --- a/js/src/tests/js1_3/shell.js +++ b/js/src/tests/js1_3/shell.js @@ -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 ***** */ - - diff --git a/js/src/tests/js1_4/browser.js b/js/src/tests/js1_4/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/js1_4/browser.js +++ b/js/src/tests/js1_4/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/js1_4/shell.js b/js/src/tests/js1_4/shell.js index 086eec9fd35e..e69de29bb2d1 100644 --- a/js/src/tests/js1_4/shell.js +++ b/js/src/tests/js1_4/shell.js @@ -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 ***** */ - - diff --git a/js/src/tests/js1_5/browser.js b/js/src/tests/js1_5/browser.js index 4cde9b062900..e69de29bb2d1 100644 --- a/js/src/tests/js1_5/browser.js +++ b/js/src/tests/js1_5/browser.js @@ -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 ***** */ - diff --git a/js/src/tests/js1_5/decompilation/shell.js b/js/src/tests/js1_5/decompilation/shell.js index 8d1c8b69c3fc..e69de29bb2d1 100644 --- a/js/src/tests/js1_5/decompilation/shell.js +++ b/js/src/tests/js1_5/decompilation/shell.js @@ -1 +0,0 @@ - diff --git a/js/src/tests/js1_5/shell.js b/js/src/tests/js1_5/shell.js index 56a369e27f77..e69de29bb2d1 100644 --- a/js/src/tests/js1_5/shell.js +++ b/js/src/tests/js1_5/shell.js @@ -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 ***** */ - - diff --git a/js/src/tests/js1_6/browser.js b/js/src/tests/js1_6/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/js1_6/browser.js +++ b/js/src/tests/js1_6/browser.js @@ -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 ***** */ diff --git a/js/src/tests/js1_6/shell.js b/js/src/tests/js1_6/shell.js index 789059f6b15a..e69de29bb2d1 100644 --- a/js/src/tests/js1_6/shell.js +++ b/js/src/tests/js1_6/shell.js @@ -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 ***** */ - diff --git a/js/src/tests/js1_7/browser.js b/js/src/tests/js1_7/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/js1_7/browser.js +++ b/js/src/tests/js1_7/browser.js @@ -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 ***** */ diff --git a/js/src/tests/js1_8/browser.js b/js/src/tests/js1_8/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/js1_8/browser.js +++ b/js/src/tests/js1_8/browser.js @@ -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 ***** */ diff --git a/js/src/tests/js1_8_1/browser.js b/js/src/tests/js1_8_1/browser.js index 2339522cb644..e69de29bb2d1 100644 --- a/js/src/tests/js1_8_1/browser.js +++ b/js/src/tests/js1_8_1/browser.js @@ -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 ***** */ diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index a3adef846250..680da9941ee8 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -2163,7 +2163,7 @@ DebuggerScript_trace(JSTracer *trc, JSObject *obj) /* This comes from a private pointer, so no barrier needed. */ if (JSScript *script = GetScriptReferent(obj)) { MarkScriptUnbarriered(trc, &script, "Debugger.Script referent"); - SetScriptReferent(obj, script); + obj->setPrivateUnbarriered(script); } } } diff --git a/js/xpconnect/src/Makefile.in b/js/xpconnect/src/Makefile.in index d59225b717d5..7dc781291a32 100644 --- a/js/xpconnect/src/Makefile.in +++ b/js/xpconnect/src/Makefile.in @@ -172,7 +172,7 @@ dombindings_gen.h: $(srcdir)/dombindings.conf \ -I$(topsrcdir)/xpcom/idl-parser \ $(srcdir)/dombindingsgen.py \ --idlpath=$(DEPTH)/dist/idl \ - --cachedir=$(DEPTH)/xpcom/idl-parser/cache \ + --cachedir=$(DEPTH)/xpcom/idl-parser \ --header-output dombindings_gen.h \ $(srcdir)/dombindings.conf @@ -189,7 +189,7 @@ dombindings_gen.cpp: $(srcdir)/dombindings.conf \ -I$(topsrcdir)/xpcom/idl-parser \ $(srcdir)/dombindingsgen.py \ --idlpath=$(DEPTH)/dist/idl \ - --cachedir=$(DEPTH)/xpcom/idl-parser/cache \ + --cachedir=$(DEPTH)/xpcom/idl-parser \ --stub-output dombindings_gen.cpp \ --makedepend-output $(MDDEPDIR)/dombindingsgen.pp \ $(srcdir)/dombindings.conf @@ -208,7 +208,7 @@ DictionaryHelpers.h: $(srcdir)/dictionary_helper_gen.conf \ -I$(topsrcdir)/xpcom/idl-parser \ $(srcdir)/dictionary_helper_gen.py \ -I $(DEPTH)/dist/idl \ - --cachedir=$(DEPTH)/xpcom/idl-parser/cache \ + --cachedir=$(DEPTH)/xpcom/idl-parser \ --header-output DictionaryHelpers.h \ $(srcdir)/dictionary_helper_gen.conf @@ -223,7 +223,7 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \ -I$(topsrcdir)/xpcom/idl-parser \ $(srcdir)/dictionary_helper_gen.py \ -I $(DEPTH)/dist/idl \ - --cachedir=$(DEPTH)/xpcom/idl-parser/cache \ + --cachedir=$(DEPTH)/xpcom/idl-parser \ --header-output DictionaryHelpers.h \ --stub-output DictionaryHelpers.cpp \ --makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \ @@ -248,9 +248,6 @@ GARBAGE += \ $(MDDEPDIR)/dombindingsgen.pp \ $(MDDEPDIR)/dictionary_helper_gen.pp \ $(wildcard $(topsrcdir)/other-licenses/ply/ply/*.pyc) \ - $(wildcard $(topsrcdir)/xpcom/idl-parser/*.pyc) \ $(NULL) -GARBAGE_DIRS += $(DEPTH)/xpcom/idl-parser/cache - DEFINES += -D_IMPL_NS_LAYOUT diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index f78307e513d5..b016592e4d43 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -140,8 +140,6 @@ abstract public class GeckoApp public static FormAssistPopup mFormAssistPopup; public Favicons mFavicons; - private Geocoder mGeocoder; - private Address mLastGeoAddress; private static LayerController mLayerController; private static PlaceholderLayerClient mPlaceholderLayerClient; private static GeckoLayerClient mLayerClient; @@ -2611,6 +2609,8 @@ abstract public class GeckoApp // accelerometer public void onAccuracyChanged(Sensor sensor, int accuracy) { + Log.w(LOGTAG, "onAccuracyChanged "+accuracy); + GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorAccuracyEvent(accuracy)); } public void onSensorChanged(SensorEvent event) @@ -2619,51 +2619,12 @@ abstract public class GeckoApp GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorEvent(event)); } - private class GeocoderRunnable implements Runnable { - Location mLocation; - GeocoderRunnable (Location location) { - mLocation = location; - } - public void run() { - try { - List
addresses = mGeocoder.getFromLocation(mLocation.getLatitude(), - mLocation.getLongitude(), 1); - // grab the first address. in the future, - // may want to expose multiple, or filter - // for best. - mLastGeoAddress = addresses.get(0); - GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(mLocation, mLastGeoAddress)); - } catch (Exception e) { - Log.w(LOGTAG, "GeocoderTask "+e); - } - } - } - // geolocation public void onLocationChanged(Location location) { Log.w(LOGTAG, "onLocationChanged "+location); - if (mGeocoder == null) - mGeocoder = new Geocoder(mLayerController.getView().getContext(), Locale.getDefault()); - if (mLastGeoAddress == null) { - GeckoAppShell.getHandler().post(new GeocoderRunnable(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) - GeckoAppShell.getHandler().post(new GeocoderRunnable(location)); - } - - GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location, mLastGeoAddress)); + GeckoAppShell.sendEventToGecko(GeckoEvent.createLocationEvent(location)); } public void onProviderDisabled(String provider) diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index b5ae75ec6c83..dac089338039 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -126,6 +126,15 @@ public class GeckoAppShell * sVibrationMaybePlaying is true. */ private static long sVibrationEndTime = 0; + /* Default value of how fast we should hint the Android sensors. */ + private static int sDefaultSensorHint = 100; + + private static Sensor gAccelerometerSensor = null; + private static Sensor gLinearAccelerometerSensor = null; + private static Sensor gGyroscopeSensor = null; + private static Sensor gOrientationSensor = null; + private static Sensor gProximitySensor = null; + /* The Android-side API: API methods that Android calls */ // Initialization methods @@ -534,31 +543,6 @@ public class GeckoAppShell tmp.countDown(); } - static Sensor gAccelerometerSensor = null; - static Sensor gOrientationSensor = null; - - public static void enableDeviceMotion(boolean enable) { - LayerView v = GeckoApp.mAppContext.getLayerController().getView(); - SensorManager sm = (SensorManager) v.getContext().getSystemService(Context.SENSOR_SERVICE); - - if (gAccelerometerSensor == null || gOrientationSensor == null) { - gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - gOrientationSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION); - } - - if (enable) { - if (gAccelerometerSensor != null) - sm.registerListener(GeckoApp.mAppContext, gAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME); - if (gOrientationSensor != null) - sm.registerListener(GeckoApp.mAppContext, gOrientationSensor, SensorManager.SENSOR_DELAY_GAME); - } else { - if (gAccelerometerSensor != null) - sm.unregisterListener(GeckoApp.mAppContext, gAccelerometerSensor); - if (gOrientationSensor != null) - sm.unregisterListener(GeckoApp.mAppContext, gOrientationSensor); - } - } - public static void enableLocation(final boolean enable) { getMainHandler().post(new Runnable() { public void run() { @@ -584,26 +568,46 @@ public class GeckoAppShell }); } - /* - * Keep these values consistent with |SensorType| in Hal.h - */ - private static final int SENSOR_ORIENTATION = 1; - private static final int SENSOR_ACCELERATION = 2; - private static final int SENSOR_PROXIMITY = 3; - - private static Sensor gProximitySensor = null; - public static void enableSensor(int aSensortype) { SensorManager sm = (SensorManager) GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE); switch(aSensortype) { - case SENSOR_PROXIMITY: + case GeckoHalDefines.SENSOR_ORIENTATION: + if(gOrientationSensor == null) + gOrientationSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION); + if (gOrientationSensor != null) + sm.registerListener(GeckoApp.mAppContext, gOrientationSensor, sDefaultSensorHint); + break; + + case GeckoHalDefines.SENSOR_ACCELERATION: + if(gAccelerometerSensor == null) + gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (gAccelerometerSensor != null) + sm.registerListener(GeckoApp.mAppContext, gAccelerometerSensor, sDefaultSensorHint); + break; + + case GeckoHalDefines.SENSOR_PROXIMITY: if(gProximitySensor == null) gProximitySensor = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY); - sm.registerListener(GeckoApp.mAppContext, gProximitySensor, - SensorManager.SENSOR_DELAY_GAME); + if (gProximitySensor != null) + sm.registerListener(GeckoApp.mAppContext, gProximitySensor, sDefaultSensorHint); break; + + case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION: + if(gLinearAccelerometerSensor == null) + gLinearAccelerometerSensor = sm.getDefaultSensor(10); + if (gLinearAccelerometerSensor != null) + sm.registerListener(GeckoApp.mAppContext, gLinearAccelerometerSensor, sDefaultSensorHint); + break; + + case GeckoHalDefines.SENSOR_GYROSCOPE: + if(gGyroscopeSensor == null) + gGyroscopeSensor = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE); + if (gGyroscopeSensor != null) + sm.registerListener(GeckoApp.mAppContext, gGyroscopeSensor, sDefaultSensorHint); + break; + } } @@ -611,9 +615,30 @@ public class GeckoAppShell SensorManager sm = (SensorManager) GeckoApp.mAppContext.getSystemService(Context.SENSOR_SERVICE); - switch(aSensortype) { - case SENSOR_PROXIMITY: - sm.unregisterListener(GeckoApp.mAppContext, gProximitySensor); + switch (aSensortype) { + case GeckoHalDefines.SENSOR_ORIENTATION: + if (gOrientationSensor != null) + sm.unregisterListener(GeckoApp.mAppContext, gOrientationSensor); + break; + + case GeckoHalDefines.SENSOR_ACCELERATION: + if (gAccelerometerSensor != null) + sm.unregisterListener(GeckoApp.mAppContext, gAccelerometerSensor); + break; + + case GeckoHalDefines.SENSOR_PROXIMITY: + if (gProximitySensor != null) + sm.unregisterListener(GeckoApp.mAppContext, gProximitySensor); + break; + + case GeckoHalDefines.SENSOR_LINEAR_ACCELERATION: + if (gLinearAccelerometerSensor != null) + sm.unregisterListener(GeckoApp.mAppContext, gLinearAccelerometerSensor); + break; + + case GeckoHalDefines.SENSOR_GYROSCOPE: + if (gGyroscopeSensor != null) + sm.unregisterListener(GeckoApp.mAppContext, gGyroscopeSensor); break; } } diff --git a/mobile/android/base/GeckoEvent.java b/mobile/android/base/GeckoEvent.java index 765c3081f42e..532ef04ace49 100644 --- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -53,6 +53,7 @@ import android.util.DisplayMetrics; import android.graphics.PointF; import android.text.format.Time; import android.os.SystemClock; +import java.lang.Math; import java.lang.System; import android.util.Log; @@ -69,8 +70,8 @@ public class GeckoEvent { private static final int NATIVE_POKE = 0; private static final int KEY_EVENT = 1; private static final int MOTION_EVENT = 2; - private static final int ORIENTATION_EVENT = 3; - private static final int ACCELERATION_EVENT = 4; + private static final int SENSOR_EVENT = 3; + private static final int UNUSED1_EVENT = 4; private static final int LOCATION_EVENT = 5; private static final int IME_EVENT = 6; private static final int DRAW = 7; @@ -90,6 +91,7 @@ public class GeckoEvent { private static final int PROXIMITY_EVENT = 23; private static final int ACTIVITY_RESUMING = 24; private static final int SCREENSHOT = 25; + private static final int SENSOR_ACCURACY = 26; public static final int IME_COMPOSITION_END = 0; public static final int IME_COMPOSITION_BEGIN = 1; @@ -121,7 +123,6 @@ public class GeckoEvent { public Point[] mPointRadii; public Rect mRect; public double mX, mY, mZ; - public double mAlpha, mBeta, mGamma; public double mDistance; public int mMetaState, mFlags; @@ -280,25 +281,46 @@ public class GeckoEvent { } public static GeckoEvent createSensorEvent(SensorEvent s) { - GeckoEvent event = null; int sensor_type = s.sensor.getType(); - + GeckoEvent event = null; + switch(sensor_type) { + case Sensor.TYPE_ACCELEROMETER: - event = new GeckoEvent(ACCELERATION_EVENT); + event = new GeckoEvent(SENSOR_EVENT); + event.mFlags = GeckoHalDefines.SENSOR_ACCELERATION; event.mX = s.values[0]; event.mY = s.values[1]; event.mZ = s.values[2]; break; - + + case 10 /* Requires API Level 9, so just use the raw value - Sensor.TYPE_LINEAR_ACCELEROMETER*/ : + event = new GeckoEvent(SENSOR_EVENT); + event.mFlags = GeckoHalDefines.SENSOR_LINEAR_ACCELERATION; + event.mX = s.values[0]; + event.mY = s.values[1]; + event.mZ = s.values[2]; + break; + case Sensor.TYPE_ORIENTATION: - event = new GeckoEvent(ORIENTATION_EVENT); - event.mAlpha = -s.values[0]; - event.mBeta = -s.values[1]; - event.mGamma = -s.values[2]; + event = new GeckoEvent(SENSOR_EVENT); + event.mFlags = GeckoHalDefines.SENSOR_ORIENTATION; + event.mX = s.values[0]; + event.mY = s.values[1]; + event.mZ = s.values[2]; + break; + + case Sensor.TYPE_GYROSCOPE: + event = new GeckoEvent(SENSOR_EVENT); + event.mFlags = GeckoHalDefines.SENSOR_GYROSCOPE; + event.mX = Math.toDegrees(s.values[0]); + event.mY = Math.toDegrees(s.values[1]); + event.mZ = Math.toDegrees(s.values[2]); break; case Sensor.TYPE_PROXIMITY: + // bug 734854 - maybe we can get rid of this event. is + // values[1] and values[2] valid? event = new GeckoEvent(PROXIMITY_EVENT); event.mDistance = s.values[0]; break; @@ -306,10 +328,9 @@ public class GeckoEvent { return event; } - public static GeckoEvent createLocationEvent(Location l, Address a) { + public static GeckoEvent createLocationEvent(Location l) { GeckoEvent event = new GeckoEvent(LOCATION_EVENT); event.mLocation = l; - event.mAddress = a; return event; } @@ -416,4 +437,10 @@ public class GeckoEvent { event.mMetaState = tabId; return event; } + + public static GeckoEvent createSensorAccuracyEvent(int accuracy) { + GeckoEvent event = new GeckoEvent(SENSOR_ACCURACY); + event.mFlags = accuracy; + return event; + } } diff --git a/dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl b/mobile/android/base/GeckoHalDefines.java similarity index 73% rename from dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl rename to mobile/android/base/GeckoHalDefines.java index 63ba4df455b2..ea6e02e06513 100644 --- a/dom/interfaces/geolocation/nsIDOMGeoPositionAddress.idl +++ b/mobile/android/base/GeckoHalDefines.java @@ -1,4 +1,5 @@ -/* ***** BEGIN LICENSE BLOCK ***** +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * ***** 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 @@ -11,14 +12,13 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Geolocation. + * The Original Code is Mozilla Android code. * - * The Initial Developer of the Original Code is Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2008 + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2012 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Doug Turner (Original Author) * * 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 @@ -34,18 +34,16 @@ * * ***** END LICENSE BLOCK ***** */ +package org.mozilla.gecko; -#include "domstubs.idl" - -[scriptable, uuid(93abae10-7024-49eb-8e05-1931343b0ebb)] -interface nsIDOMGeoPositionAddress : nsISupports +public class GeckoHalDefines { - readonly attribute DOMString streetNumber; - readonly attribute DOMString street; - readonly attribute DOMString premises; - readonly attribute DOMString city; - readonly attribute DOMString county; - readonly attribute DOMString region; - readonly attribute DOMString country; - readonly attribute DOMString postalCode; + /* + * Keep these values consistent with |SensorType| in Hal.h + */ + public static final int SENSOR_ORIENTATION = 0; + public static final int SENSOR_ACCELERATION = 1; + public static final int SENSOR_PROXIMITY = 2; + public static final int SENSOR_LINEAR_ACCELERATION = 3; + public static final int SENSOR_GYROSCOPE = 4; }; diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 7861038e6376..e5dc3f434e51 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -87,6 +87,7 @@ FENNEC_JAVA_FILES = \ GeckoEvent.java \ GeckoEventListener.java \ GeckoEventResponder.java \ + GeckoHalDefines.java \ GeckoInputConnection.java \ GeckoMessageReceiver.java \ GeckoPreferences.java \ @@ -235,6 +236,7 @@ RES_LAYOUT = \ $(SYNC_RES_LAYOUT) \ res/layout/autocomplete_list_item.xml \ res/layout/awesomebar.xml \ + res/layout/awesomebar_actionbar.xml \ res/layout/awesomebar_folder_row.xml \ res/layout/awesomebar_folder_header_row.xml \ res/layout/awesomebar_header_row.xml \ diff --git a/mobile/android/base/TabsTray.java b/mobile/android/base/TabsTray.java index a2ff0ef91c8b..170bbe28ca5a 100644 --- a/mobile/android/base/TabsTray.java +++ b/mobile/android/base/TabsTray.java @@ -1,39 +1,7 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** 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 Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Sriram Ramasubramanian - * - * 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 ***** */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; @@ -60,6 +28,8 @@ import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; +import org.mozilla.gecko.sync.setup.SyncAccounts; + public class TabsTray extends Activity implements Tabs.OnTabsChangedListener { private static int sPreferredHeight; @@ -122,19 +92,23 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener { tabs.refreshThumbnails(); onTabChanged(null, null); - // If sync is set up, query the database for remote clients - // Cleanup after Bug: 734211 is fixed - if (AccountManager.get(getApplicationContext()).getAccountsByType("org.mozilla.firefox_sync").length > 0) { - TabsAccessor.areClientsAvailable(getApplicationContext(), new TabsAccessor.OnClientsAvailableListener() { - @Override - public void areAvailable(boolean available) { - if (available) - mRemoteTabs.setVisibility(View.VISIBLE); - else - mRemoteTabs.setVisibility(View.GONE); - } - }); - } + // If Sync is set up, query the database for remote clients. + final Context context = getApplicationContext(); + new SyncAccounts.AccountsExistTask() { + @Override + protected void onPostExecute(Boolean result) { + if (!result.booleanValue()) { + return; + } + TabsAccessor.areClientsAvailable(context, new TabsAccessor.OnClientsAvailableListener() { + @Override + public void areAvailable(boolean available) { + final int visibility = available ? View.VISIBLE : View.GONE; + mRemoteTabs.setVisibility(visibility); + } + }); + } + }.execute(context); } @Override diff --git a/mobile/android/base/resources/layout/awesomebar_actionbar.xml b/mobile/android/base/resources/layout/awesomebar_actionbar.xml new file mode 100644 index 000000000000..1b6c67d12d68 --- /dev/null +++ b/mobile/android/base/resources/layout/awesomebar_actionbar.xml @@ -0,0 +1,3 @@ + + diff --git a/mobile/android/base/resources/values-v11/styles.xml b/mobile/android/base/resources/values-v11/styles.xml index 6e5b7a0b5e4a..c29b7245c0de 100644 --- a/mobile/android/base/resources/values-v11/styles.xml +++ b/mobile/android/base/resources/values-v11/styles.xml @@ -39,6 +39,8 @@ diff --git a/mobile/android/base/sync/repositories/RepositorySession.java b/mobile/android/base/sync/repositories/RepositorySession.java index 205735b26892..743fe11019d3 100644 --- a/mobile/android/base/sync/repositories/RepositorySession.java +++ b/mobile/android/base/sync/repositories/RepositorySession.java @@ -1,40 +1,6 @@ -/* ***** 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 Android Sync Client. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jason Voll - * Richard Newman - * - * 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 ***** */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.sync.repositories; @@ -53,16 +19,22 @@ import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelega import org.mozilla.gecko.sync.repositories.domain.Record; /** - * A RepositorySession is created and used thusly: + * A RepositorySession is created and used thusly: * - * * Construct, with a reference to its parent Repository, by calling - * Repository.createSession(). - * * Populate with saved information by calling unbundle(). - * * Begin a sync by calling begin(). - * * Perform operations such as fetchSince() and store(). - * * Finish by calling finish(), retrieving and storing the current bundle. + *
    + *
  • Construct, with a reference to its parent {@link Repository}, by calling + * {@link Repository#createSession(RepositorySessionCreationDelegate, android.content.Context)}.
  • + *
  • Populate with saved information by calling {@link #unbundle(RepositorySessionBundle)}.
  • + *
  • Begin a sync by calling {@link #begin(RepositorySessionBeginDelegate)}. begin() + * is an appropriate place to initialize expensive resources.
  • + *
  • Perform operations such as {@link #fetchSince(long, RepositorySessionFetchRecordsDelegate)} and + * {@link #store(Record)}.
  • + *
  • Finish by calling {@link #finish(RepositorySessionFinishDelegate)}, retrieving and storing + * the current bundle.
  • + *
* - * @author rnewman + * If finish() is not called, {@link #abort()} must be called. These calls must + * always be paired with begin(). * */ public abstract class RepositorySession { @@ -192,6 +164,13 @@ public abstract class RepositorySession { this.transitionFrom(SessionStatus.UNSTARTED, SessionStatus.ACTIVE); } + /** + * Start the session. This is an appropriate place to initialize + * data access components such as database handles. + * + * @param delegate + * @throws InvalidSessionTransitionException + */ public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException { sharedBegin(); delegate.deferredBeginDelegate(delegateQueue).onBeginSucceeded(this); @@ -228,6 +207,10 @@ public abstract class RepositorySession { delegate.deferredFinishDelegate(delegateQueue).onFinishSucceeded(this, this.getBundle(null)); } + /** + * Abnormally terminate the repository session, freeing or closing + * any resources that were opened during the lifetime of the session. + */ public void abort() { // TODO: do something here. this.setStatus(SessionStatus.ABORTED); @@ -243,6 +226,13 @@ public abstract class RepositorySession { } } + /** + * End the repository session, freeing or closing any resources + * that were opened during the lifetime of the session. + * + * @param delegate notified of success or failure. + * @throws InactiveSessionException + */ public void finish(final RepositorySessionFinishDelegate delegate) throws InactiveSessionException { try { this.transitionFrom(SessionStatus.ACTIVE, SessionStatus.DONE); diff --git a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java index 3fa15fbe5812..81af2e45395f 100644 --- a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java +++ b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java @@ -459,21 +459,21 @@ public class AndroidBrowserBookmarksRepositorySession extends AndroidBrowserRepo } @Override - protected boolean checkRecordType(Record record) { + protected boolean shouldIgnore(Record record) { if (!(record instanceof BookmarkRecord)) { - return false; + return true; } if (record.deleted) { - return true; + return false; } BookmarkRecord bmk = (BookmarkRecord) record; if (bmk.isBookmark() || bmk.isFolder()) { - return true; + return false; } Logger.info(LOG_TAG, "Ignoring record with guid: " + bmk.guid + " and type: " + bmk.type); - return false; + return true; } @Override diff --git a/mobile/android/base/sync/repositories/android/AndroidBrowserRepositorySession.java b/mobile/android/base/sync/repositories/android/AndroidBrowserRepositorySession.java index 8505f423b75a..2207b8b6909b 100644 --- a/mobile/android/base/sync/repositories/android/AndroidBrowserRepositorySession.java +++ b/mobile/android/base/sync/repositories/android/AndroidBrowserRepositorySession.java @@ -1,40 +1,6 @@ -/* ***** 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 Android Sync Client. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jason Voll - * Richard Newman - * - * 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 ***** */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.sync.repositories.android; @@ -118,9 +84,13 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos */ protected abstract Record retrieveDuringFetch(Cursor cur) throws NoGuidForIdException, NullCursorException, ParentNotFoundException; - // Must be overriden by AndroidBookmarkRepositorySession. - protected boolean checkRecordType(Record record) { - return true; + /** + * Override this to allow records to be skipped during insertion. + * + * For example, a session subclass might skip records of an unsupported type. + */ + protected boolean shouldIgnore(Record record) { + return false; } /** @@ -393,8 +363,8 @@ public abstract class AndroidBrowserRepositorySession extends StoreTrackingRepos // including livemarks and queries, are simply ignored. // See Bug 708149. This might be resolved by Fennec changing its database // schema, or by Sync storing non-applied records in its own private database. - if (!checkRecordType(record)) { - Logger.debug(LOG_TAG, "Ignoring record " + record.guid + " due to unknown record type."); + if (shouldIgnore(record)) { + Logger.debug(LOG_TAG, "Ignoring record " + record.guid); // Don't throw: we don't want to abort the entire sync when we get a livemark! // delegate.onRecordStoreFailed(new InvalidBookmarkTypeException(null)); diff --git a/mobile/android/base/sync/setup/SyncAccounts.java b/mobile/android/base/sync/setup/SyncAccounts.java new file mode 100644 index 000000000000..fd7b1c1f5d67 --- /dev/null +++ b/mobile/android/base/sync/setup/SyncAccounts.java @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.sync.setup; + +import org.mozilla.gecko.db.BrowserContract; +import org.mozilla.gecko.sync.Logger; +import org.mozilla.gecko.sync.Utils; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; + +/** + * This class contains utilities that are of use to Fennec + * and Sync setup activities. + * + * Do not break these APIs without correcting upstream code! + */ +public class SyncAccounts { + + private final static String DEFAULT_SERVER = "https://auth.services.mozilla.com/"; + private static final String LOG_TAG = "SyncAccounts"; + + /** + * Returns true if a Sync account is set up. + * + * Do not call this method from the main thread. + */ + public static boolean syncAccountsExist(Context c) { + return AccountManager.get(c).getAccountsByType("org.mozilla.firefox_sync").length > 0; + } + + /** + * This class provides background-thread abstracted access to whether a + * Firefox Sync account has been set up on this device. + * + * Subclass this task and override `onPostExecute` to act on the result. + */ + public static class AccountsExistTask extends AsyncTask { + @Override + protected Boolean doInBackground(Context... params) { + Context c = params[0]; + return syncAccountsExist(c); + } + } + + public static Intent createAccount(Context context, + AccountManager accountManager, + String username, + String syncKey, + String password, + String serverURL) { + + final Account account = new Account(username, Constants.ACCOUNTTYPE_SYNC); + final Bundle userbundle = new Bundle(); + + // Add sync key and server URL. + userbundle.putString(Constants.OPTION_SYNCKEY, syncKey); + if (serverURL != null) { + Logger.info(LOG_TAG, "Setting explicit server URL: " + serverURL); + userbundle.putString(Constants.OPTION_SERVER, serverURL); + } else { + userbundle.putString(Constants.OPTION_SERVER, DEFAULT_SERVER); + } + Logger.debug(LOG_TAG, "Adding account for " + Constants.ACCOUNTTYPE_SYNC); + boolean result = false; + try { + result = accountManager.addAccountExplicitly(account, password, userbundle); + } catch (SecurityException e) { + final String message = e.getMessage(); + if (message != null && (message.indexOf("is different than the authenticator's uid") > 0)) { + Log.wtf("FirefoxSync", + "Unable to create account. " + + "If you have more than one version of " + + "Firefox/Beta/Aurora/Nightly/Fennec installed, that's why.", + e); + } else { + Log.e("FirefoxSync", "Unable to create account.", e); + } + } + + Logger.debug(LOG_TAG, "Account: " + account + " added successfully? " + result); + if (!result) { + Logger.error(LOG_TAG, "Failed to add account!"); + } + + // Set components to sync (default: all). + ContentResolver.setMasterSyncAutomatically(true); + + String authority = BrowserContract.AUTHORITY; + Logger.debug(LOG_TAG, "Setting authority " + authority + " to sync automatically."); + ContentResolver.setSyncAutomatically(account, authority, true); + ContentResolver.setIsSyncable(account, authority, 1); + + // TODO: add other ContentProviders as needed (e.g. passwords) + // TODO: for each, also add to res/xml to make visible in account settings + Logger.debug(LOG_TAG, "Finished setting syncables."); + + // TODO: correctly implement Sync Options. + Logger.info(LOG_TAG, "Clearing preferences for this account."); + try { + Utils.getSharedPreferences(context, username, serverURL).edit().clear().commit(); + } catch (Exception e) { + Logger.error(LOG_TAG, "Could not clear prefs path!", e); + } + + final Intent intent = new Intent(); + intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, username); + intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNTTYPE_SYNC); + intent.putExtra(AccountManager.KEY_AUTHTOKEN, Constants.ACCOUNTTYPE_SYNC); + return intent; + } +} diff --git a/mobile/android/base/sync/setup/activities/AccountActivity.java b/mobile/android/base/sync/setup/activities/AccountActivity.java index 9809683095e4..88543a992cfb 100644 --- a/mobile/android/base/sync/setup/activities/AccountActivity.java +++ b/mobile/android/base/sync/setup/activities/AccountActivity.java @@ -7,14 +7,11 @@ package org.mozilla.gecko.sync.setup.activities; import java.util.Locale; import org.mozilla.gecko.R; -import org.mozilla.gecko.db.BrowserContract; -import org.mozilla.gecko.sync.Utils; import org.mozilla.gecko.sync.setup.Constants; +import org.mozilla.gecko.sync.setup.SyncAccounts; -import android.accounts.Account; import android.accounts.AccountAuthenticatorActivity; import android.accounts.AccountManager; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -31,8 +28,6 @@ import android.widget.EditText; public class AccountActivity extends AccountAuthenticatorActivity { private final static String LOG_TAG = "AccountActivity"; - private final static String DEFAULT_SERVER = "https://auth.services.mozilla.com/"; - private AccountManager mAccountManager; private Context mContext; private String username; @@ -156,9 +151,11 @@ public class AccountActivity extends AccountAuthenticatorActivity { } private boolean validateInputs() { - if (usernameInput.length() == 0 || passwordInput.length() == 0 - || synckeyInput.length() == 0 - || (serverCheckbox.isChecked() && serverInput.length() == 0)) { + if (usernameInput.length() == 0 || + passwordInput.length() == 0 || + synckeyInput.length() == 0 || + (serverCheckbox.isChecked() && + serverInput.length() == 0)) { return false; } return true; @@ -171,7 +168,7 @@ public class AccountActivity extends AccountAuthenticatorActivity { // Create and add account to AccountManager // TODO: only allow one account to be added? Log.d(LOG_TAG, "Using account manager " + mAccountManager); - final Intent intent = createAccount(mContext, mAccountManager, + final Intent intent = SyncAccounts.createAccount(mContext, mAccountManager, username, key, password, server); setAccountAuthenticatorResult(intent.getExtras()); @@ -193,74 +190,6 @@ public class AccountActivity extends AccountAuthenticatorActivity { }); } - // TODO: lift this out. - public static Intent createAccount(Context context, - AccountManager accountManager, - String username, - String syncKey, - String password, - String serverURL) { - - final Account account = new Account(username, Constants.ACCOUNTTYPE_SYNC); - final Bundle userbundle = new Bundle(); - - // Add sync key and server URL. - userbundle.putString(Constants.OPTION_SYNCKEY, syncKey); - if (serverURL != null) { - Log.i(LOG_TAG, "Setting explicit server URL: " + serverURL); - userbundle.putString(Constants.OPTION_SERVER, serverURL); - } else { - userbundle.putString(Constants.OPTION_SERVER, DEFAULT_SERVER); - } - Log.d(LOG_TAG, "Adding account for " + Constants.ACCOUNTTYPE_SYNC); - boolean result = false; - try { - result = accountManager.addAccountExplicitly(account, password, userbundle); - } catch (SecurityException e) { - final String message = e.getMessage(); - if (message != null && (message.indexOf("is different than the authenticator's uid") > 0)) { - Log.wtf("FirefoxSync", - "Unable to create account. " + - "If you have more than one version of " + - "Firefox/Beta/Aurora/Nightly/Fennec installed, that's why.", - e); - } else { - Log.e("FirefoxSync", "Unable to create account.", e); - } - } - - Log.d(LOG_TAG, "Account: " + account + " added successfully? " + result); - if (!result) { - Log.e(LOG_TAG, "Failed to add account!"); - } - - // Set components to sync (default: all). - ContentResolver.setMasterSyncAutomatically(true); - - String authority = BrowserContract.AUTHORITY; - Log.d(LOG_TAG, "Setting authority " + authority + " to sync automatically."); - ContentResolver.setSyncAutomatically(account, authority, true); - ContentResolver.setIsSyncable(account, authority, 1); - - // TODO: add other ContentProviders as needed (e.g. passwords) - // TODO: for each, also add to res/xml to make visible in account settings - Log.d(LOG_TAG, "Finished setting syncables."); - - // TODO: correctly implement Sync Options. - Log.i(LOG_TAG, "Clearing preferences for this account."); - try { - Utils.getSharedPreferences(context, username, serverURL).edit().clear().commit(); - } catch (Exception e) { - Log.e(LOG_TAG, "Could not clear prefs path!", e); - } - - final Intent intent = new Intent(); - intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, username); - intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNTTYPE_SYNC); - intent.putExtra(AccountManager.KEY_AUTHTOKEN, Constants.ACCOUNTTYPE_SYNC); - return intent; - } - @SuppressWarnings("unused") private void authFailure() { enableCredEntry(true); diff --git a/mobile/android/base/sync/setup/activities/SetupSyncActivity.java b/mobile/android/base/sync/setup/activities/SetupSyncActivity.java index bac2175c7d16..3745455ad107 100644 --- a/mobile/android/base/sync/setup/activities/SetupSyncActivity.java +++ b/mobile/android/base/sync/setup/activities/SetupSyncActivity.java @@ -13,6 +13,7 @@ import org.mozilla.gecko.sync.ThreadPool; import org.mozilla.gecko.sync.jpake.JPakeClient; import org.mozilla.gecko.sync.jpake.JPakeNoActivePairingException; import org.mozilla.gecko.sync.setup.Constants; +import org.mozilla.gecko.sync.setup.SyncAccounts; import android.accounts.Account; import android.accounts.AccountAuthenticatorActivity; @@ -362,7 +363,7 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity { String serverURL = (String) jCreds.get(Constants.JSON_KEY_SERVER); Logger.debug(LOG_TAG, "Using account manager " + mAccountManager); - final Intent intent = AccountActivity.createAccount(mContext, mAccountManager, + final Intent intent = SyncAccounts.createAccount(mContext, mAccountManager, accountName, syncKey, password, serverURL); setAccountAuthenticatorResult(intent.getExtras()); diff --git a/mobile/android/chrome/Makefile.in b/mobile/android/chrome/Makefile.in index 599b5b42668d..4d31adb28a32 100644 --- a/mobile/android/chrome/Makefile.in +++ b/mobile/android/chrome/Makefile.in @@ -47,7 +47,4 @@ DEFINES += -DAB_CD=$(MOZ_UI_LOCALE) \ -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \ $(NULL) - -TEST_DIRS += tests - include $(topsrcdir)/config/rules.mk diff --git a/mobile/android/chrome/content/bindings.xml b/mobile/android/chrome/content/bindings.xml index 70e68f8bb670..103a2b9cba64 100644 --- a/mobile/android/chrome/content/bindings.xml +++ b/mobile/android/chrome/content/bindings.xml @@ -109,33 +109,6 @@ - - - - - - - - - - - - - - - - - - - @@ -261,70 +234,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mobile/android/chrome/content/bindings/settings.xml b/mobile/android/chrome/content/bindings/settings.xml new file mode 100644 index 000000000000..afc54c9d6aa3 --- /dev/null +++ b/mobile/android/chrome/content/bindings/settings.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/android/chrome/content/browser.css b/mobile/android/chrome/content/browser.css index a01513f94125..a8657db596db 100644 --- a/mobile/android/chrome/content/browser.css +++ b/mobile/android/chrome/content/browser.css @@ -1,45 +1,3 @@ -settings { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings"); -} - -setting[type="bool"] { - -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-bool"); -} - -setting[type="bool"][localized="true"] { - -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-localized-bool"); -} - -setting[type="boolint"] { - -moz-binding: url("chrome://browser/content/bindings.xml#setting-fulltoggle-boolint"); -} - -setting[type="integer"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-integer"); -} - -setting[type="control"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-control"); -} - -setting[type="string"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-string"); -} - -setting[type="color"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-color"); -} - -setting[type="file"], -setting[type="directory"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-path"); -} - -setting[type="radio"], -setting[type="menulist"] { - -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-multi"); -} - radio { -moz-binding: url("chrome://global/content/bindings/radio.xml#radio"); } @@ -52,10 +10,6 @@ menulist { -moz-binding: url("chrome://browser/content/bindings.xml#menulist"); } -.chrome-select-option { - -moz-binding: url("chrome://browser/content/bindings.xml#chrome-select-option"); -} - /* richlist defaults ------------------------------------------------------- */ richlistbox[batch] { -moz-binding: url("chrome://browser/content/bindings.xml#richlistbox-batch"); diff --git a/mobile/android/chrome/jar.mn b/mobile/android/chrome/jar.mn index 7fe708b425ab..3b89c73f57b2 100644 --- a/mobile/android/chrome/jar.mn +++ b/mobile/android/chrome/jar.mn @@ -16,6 +16,7 @@ chrome.jar: * content/browser.js (content/browser.js) * content/bindings.xml (content/bindings.xml) content/bindings/checkbox.xml (content/bindings/checkbox.xml) + content/bindings/settings.xml (content/bindings/settings.xml) content/bindings/dialog.xml (content/bindings/dialog.xml) content/browser.css (content/browser.css) content/cursor.css (content/cursor.css) diff --git a/mobile/android/chrome/tests/Makefile.in b/mobile/android/chrome/tests/Makefile.in deleted file mode 100644 index 5780f544d803..000000000000 --- a/mobile/android/chrome/tests/Makefile.in +++ /dev/null @@ -1,142 +0,0 @@ -# ***** 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. -# -# The Initial Developer of the Original Code is -# the Mozilla Foundation . -# Portions created by the Initial Developer are Copyright (C) 2008 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Mark Finkle -# -# 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 ***** - -DEPTH = ../../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ -relativesrcdir = mobile/chrome/tests -TESTXPI = $(CURDIR)/$(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)/addons -ADDONSRC = $(srcdir)/addons - -include $(DEPTH)/config/autoconf.mk -include $(topsrcdir)/config/rules.mk - -_BROWSER_FILES = \ - head.js \ - remote_autocomplete.js \ - remote_contentpopup.js \ - remote_head.js \ - remote_focus.js \ - remote_forms.js \ - remote_formsZoom.js \ - remote_vkb.js \ - browser_addons.js \ - browser_addons_locales.js \ - browser_appmenu.js \ - browser_autocompletesearch.js \ - $(info browser_awesomescreen.js is disabled because the localepicker is disabled (bug 693524)) \ - browser_blank_01.html \ - browser_blank_02.html \ - browser_blank_03.html \ - browser_bookmarks.js \ - browser_contacts.js \ - browser_dragger.js \ - browser_escape.js \ - browser_find.js \ - browser_focus.html \ - browser_focus.js \ - browser_forms.html \ - $(warning browser_forms.js disabled due to failures) \ - browser_formsZoom.html \ - $(warning browser_formsZoom.js disabled due to failures) \ - $(info browser_history.js is disabled because it is random orange on XUL fennec (bug 700537)) \ - $(info browser_localepicker.js is disabled because the localepicker is disabled (bug 694047)) \ - browser_localepicker_escape.js \ - browser_mainui.js \ - browser_preferences_text.js \ - browser_preferences_fulltoggle.js \ - browser_rect.js \ - $(info browser_rememberPassword.js is disabled because it is random orange on XUL fennec (bug 698387)) \ - browser_scroll.js \ - browser_scroll.html \ - browser_scrollbar.js \ - browser_select.html \ - browser_select.js \ - browser_sessionstore.js \ - $(info browser_tabs.js is disabled because it is random orange on XUL fennec (bug 700537)) \ - $(info browser_tapping.js is disabled because it is random orange on XUL fennec (bug 698387)) \ - $(info browser_tap_content.html is disabled because it is random orange on XUL fennec (bug 698387)) \ - browser_tapping_edit.js \ - browser_tap_contentedit.html \ - browser_test.js \ - browser_vkb.js \ - $(warning browser_viewport.js disabled due to failures) \ - browser_viewport.sjs \ - browser_scrollbar.sjs \ - browser_title.sjs \ - $(info browser_thumbnails.js is disabled because it is random orange on XUL fennec (bug 700537)) \ - browser_install.xml \ - browser_upgrade.rdf\ - browser_localerepository.js \ - browser_localerepository_pref.js \ - browser_localerepository_buildid.js \ - locales_list.sjs \ - mock_autocomplete.json\ - $(NULL) - -ifneq ($(OS_TARGET),Android) -_BROWSER_FILES += \ - browser_autocomplete.html \ - browser_autocomplete.js \ - browser_bookmarks_star.js \ - browser_bookmarks_tags.js \ - browser_click_content.html \ - browser_click_content.js \ - browser_contentpopup.html \ - browser_contentpopup.js \ - browser_navigation.js \ - $(NULL) -ifndef MOZ_PLATFORM_MAEMO -_BROWSER_FILES += browser_sidebars.js -endif -endif - -libs:: $(_BROWSER_FILES) - $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir) - -libs:: - rm -rf $(TESTXPI) - $(NSINSTALL) -D $(TESTXPI) - if [ -d $(ADDONSRC) ]; then \ - $(EXIT_ON_ERROR) \ - for dir in $(ADDONSRC)/*; do \ - base=`basename $$dir` ; \ - (cd $$dir && zip $(TESTXPI)/$$base.xpi *) \ - done \ - fi - diff --git a/mobile/android/chrome/tests/addons/browser_install1_1/bootstrap.js b/mobile/android/chrome/tests/addons/browser_install1_1/bootstrap.js deleted file mode 100644 index 7b86e419a3b3..000000000000 --- a/mobile/android/chrome/tests/addons/browser_install1_1/bootstrap.js +++ /dev/null @@ -1,9 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -function install(data, reason) {} -function startup(data, reason) {} -function shutdown(data, reason) {} -function uninstall(data, reason) {} - diff --git a/mobile/android/chrome/tests/addons/browser_install1_1/install.rdf b/mobile/android/chrome/tests/addons/browser_install1_1/install.rdf deleted file mode 100644 index 0825d11aa0cb..000000000000 --- a/mobile/android/chrome/tests/addons/browser_install1_1/install.rdf +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - addon1@tests.mozilla.org - 1.0 - http://example.com/browser/mobile/chrome/tests/browser_upgrade.rdf - true - - - - toolkit@mozilla.org - 0 - * - - - - - Install Tests - - - diff --git a/mobile/android/chrome/tests/addons/browser_install1_2/install.rdf b/mobile/android/chrome/tests/addons/browser_install1_2/install.rdf deleted file mode 100644 index 945afb22b014..000000000000 --- a/mobile/android/chrome/tests/addons/browser_install1_2/install.rdf +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - addon2@tests.mozilla.org - 2.0 - - - - toolkit@mozilla.org - 0 - * - - - - - Install Tests 2 - - - diff --git a/mobile/android/chrome/tests/addons/browser_install1_3/install.rdf b/mobile/android/chrome/tests/addons/browser_install1_3/install.rdf deleted file mode 100644 index 2c10f4921628..000000000000 --- a/mobile/android/chrome/tests/addons/browser_install1_3/install.rdf +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - addon1@tests.mozilla.org - 3.0 - http://example.com/browser/mobile/chrome/tests/browser_upgrade.rdf - - - - toolkit@mozilla.org - 0 - * - - - - - Install Tests - - - diff --git a/mobile/android/chrome/tests/addons/browser_locale1/boostrap.js b/mobile/android/chrome/tests/addons/browser_locale1/boostrap.js deleted file mode 100644 index 7b86e419a3b3..000000000000 --- a/mobile/android/chrome/tests/addons/browser_locale1/boostrap.js +++ /dev/null @@ -1,9 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -function install(data, reason) {} -function startup(data, reason) {} -function shutdown(data, reason) {} -function uninstall(data, reason) {} - diff --git a/mobile/android/chrome/tests/addons/browser_locale1/chrome.manifest b/mobile/android/chrome/tests/addons/browser_locale1/chrome.manifest deleted file mode 100644 index a909200d5b02..000000000000 --- a/mobile/android/chrome/tests/addons/browser_locale1/chrome.manifest +++ /dev/null @@ -1,4 +0,0 @@ -locale mozapps te-st chrome # locale -locale browser te-st chrome # duplicate locale -locale browser te-st-a chrome # second locale -locale branding te-st-3 chrome # wrong component diff --git a/mobile/android/chrome/tests/addons/browser_locale1/install.rdf b/mobile/android/chrome/tests/addons/browser_locale1/install.rdf deleted file mode 100644 index ba92a4581869..000000000000 --- a/mobile/android/chrome/tests/addons/browser_locale1/install.rdf +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - locale1@tests.mozilla.org - 1.0 - 8 - true - - - - toolkit@mozilla.org - 0 - * - - - - - Test Locale - - - diff --git a/mobile/android/chrome/tests/browser_addons.js b/mobile/android/chrome/tests/browser_addons.js deleted file mode 100644 index 7b465e2e5cdf..000000000000 --- a/mobile/android/chrome/tests/browser_addons.js +++ /dev/null @@ -1,503 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -Components.utils.import("resource://gre/modules/AddonManager.jsm"); -Components.utils.import("resource://gre/modules/AddonUpdateChecker.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/NetUtil.jsm"); - -const RELATIVE_DIR = "browser/mobile/chrome/tests/"; -const TESTROOT = "http://example.com/" + RELATIVE_DIR; -const TESTROOT2 = "http://example.org/" + RELATIVE_DIR; -const PREF_LOGGING_ENABLED = "extensions.logging.enabled"; -const PREF_SEARCH_MAXRESULTS = "extensions.getAddons.maxResults"; -const CHROME_NAME = "mochikit"; -const PREF_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault" -const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL"; -const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; -const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url"; -const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL"; -const PREF_GETADDONS_UPDATE = "extensions.update.url"; -const PREF_ADDONS_LOGGING = "extensions.logging.enabled"; -const PREF_ADDONS_SECURITY = "extensions.checkUpdateSecurity"; -const SEARCH_URL = TESTROOT + "browser_details.xml"; -const ADDON_IMG = "chrome://browser/skin/images/alert-addons-30.png"; - -var addons = [{ - id: "addon1@tests.mozilla.org", - name : "Install Tests", - iconURL: "http://example.com/icon.png", - homepageURL: "http://example.com/", - version: "1.0", - description: "Test add-on", - sourceURL: TESTROOT + "addons/browser_install1_1.xpi", - bootstrapped: true, - willFail: false, - updateIndex: 2, -}, -{ - id: "addon2@tests.mozilla.org", - name : "Install Tests 2", - iconURL: "http://example.com/icon.png", - homepageURL: "http://example.com/", - version: "1.0", - description: "Test add-on 2", - sourceURL: TESTROOT + "addons/browser_install1_2.xpi", - bootstrapped: false, - willFail: false, -}, -{ - id: "addon1@tests.mozilla.org", - name : "Install Tests 3", - iconURL: "http://example.com/icon.png", - homepageURL: "http://example.com/", - version: "1.0", - description: "Test add-on 3", - sourceURL: TESTROOT + "addons/browser_install1_3.xpi", - bootstrapped: false, - willFail: false, -}]; - - -var gPendingTests = []; -var gTestsRun = 0; -var gTestStart = null; -var gDate = new Date(2010, 7, 1); -var gApp = Strings.brand.GetStringFromName("brandShortName"); -var gCategoryUtilities; -var gSearchCount = 0; -var gTestURL = TESTROOT + "browser_blank_01.html"; -var gCurrentTab = null; - -function test() { - waitForExplicitFinish(); - requestLongerTimeout(2); - Services.prefs.setCharPref(PREF_GETADDONS_GETRECOMMENDED, TESTROOT + "browser_install.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_BROWSERECOMMENDED, TESTROOT + "browser_install.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS, TESTROOT + "browser_install.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, TESTROOT + "browser_install.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_UPDATE, TESTROOT + "browser_upgrade.rdf"); - Services.prefs.setBoolPref(PREF_ADDONS_SECURITY, false); - Services.prefs.setBoolPref(PREF_ADDONS_LOGGING, true); - run_next_test(); -} - -function end_test() { - close_manager(); - Services.prefs.clearUserPref(PREF_GETADDONS_GETRECOMMENDED); - Services.prefs.clearUserPref(PREF_GETADDONS_BROWSERECOMMENDED); - Services.prefs.clearUserPref(PREF_GETADDONS_BROWSESEARCHRESULTS); - Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS); - Services.prefs.clearUserPref(PREF_GETADDONS_UPDATE); - Services.prefs.clearUserPref(PREF_ADDONS_SECURITY); - Services.prefs.clearUserPref(PREF_ADDONS_LOGGING); -} - -registerCleanupFunction(end_test); - -function add_test(test) { - gPendingTests.push(test); -} - -function run_next_test() { - if (gTestsRun > 0) - info("Test " + gTestsRun + " took " + (Date.now() - gTestStart) + "ms"); - - if (!gPendingTests.length) { - finish(); - return; - } - - gTestsRun++; - let test = gPendingTests.shift(); - if (test.name) - info("Running test " + gTestsRun + " (" + test.name + ")"); - else - info("Running test " + gTestsRun); - - gTestStart = Date.now(); - test(); -} - -function checkAttribute(aElt, aAttr, aVal) { - ok(aElt.hasAttribute(aAttr), "Element has " + aAttr + " attribute"); - if(aVal) - is(aElt.getAttribute(aAttr), aVal, "Element has " + aAttr + " attribute with value " + aVal); -} - -function installExtension(elt, aListener) { - elt.parentNode.ensureElementIsVisible(elt); - elt.install.addListener(aListener) - - let button = document.getAnonymousElementByAttribute(elt, "class", "addon-install hide-on-install hide-on-restart"); - ok(!!button, "Extension has install button"); - ExtensionsView.installFromRepo(elt); -} - -function isRestartShown(aShown, isUpdate, aCallback) { - let msg = document.getElementById("addons-messages"); - ok(!!msg, "Have message box"); - - let done = function(aNotification) { - is(!!aNotification, aShown, "Restart exists = " + aShown); - if (aShown && aNotification) { - let showsUpdate = aNotification.label.match(/update/i) != null; - // this test regularly fails due to race conditions here - is(showsUpdate, isUpdate, "Restart shows correct message"); - } - msg.removeAllNotifications(true); - aCallback(); - } - - let notification = msg.getNotificationWithValue("restart-app"); - if (!notification && aShown) { - window.addEventListener("AlertActive", function() { - window.removeEventListener("AlertActive", arguments.callee, true); - notification = msg.getNotificationWithValue("restart-app"); - done(notification); - }, true); - } else { - done(notification); - } -} - -function checkInstallAlert(aShown, aCallback) { - checkAlert(null, "xpinstall", null, aShown, function(aNotifyBox, aNotification) { - if (aShown) { - let button = aNotification.childNodes[0]; - ok(!!button, "Notification has button"); - if (button) - button.click(); - } - aNotifyBox.removeAllNotifications(true); - if (aCallback) - aCallback(); - }); -} - -function checkDownloadNotification(aCallback) { - let msg = /download/i; - checkNotification(/Add-ons/, msg, ADDON_IMG, aCallback); -} - -function checkInstallNotification(aRestart, aCallback) { - let msg = null; - if (aRestart) - msg = /restart/i; - checkNotification(/Add-ons/, msg, ADDON_IMG, aCallback); -} - -function checkNotification(aTitle, aMessage, aIcon, aCallback) { - let doTest = function() { - ok(document.getElementById("alerts-container").classList.contains("showing"), "Alert shown"); - let title = document.getElementById("alerts-title").value; - let msg = document.getElementById("alerts-text").textContent; - let img = document.getElementById("alerts-image").getAttribute("src"); - - if (aTitle) - ok(aTitle.test(title), "Correct title alert shown: " + title); - if (aMessage) - ok(aMessage.test(msg), "Correct message shown: " + msg); - if (aIcon) - is(img, aIcon, "Correct image shown: " + aIcon); - - // make sure this is hidden before another test asks about it - AlertsHelper.container.classList.remove("showing"); - AlertsHelper.container.height = 0; - AlertsHelper.container.hidden = true; - aCallback(); - }; - - let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2); - if (sysInfo.get("device")) - aCallback(); - else - waitFor(doTest, function() { return AlertsHelper.container.hidden == false; }); -} - -function checkAlert(aId, aName, aLabel, aShown, aCallback) { - let msg = null; - if (aId) - msg = document.getElementById(aId); - else - msg = window.getNotificationBox(gCurrentTab.browser); - ok(!!msg, "Have notification box"); - - let haveNotification = function(notify) { - is(!!notify, aShown, "Notification alert exists = " + aShown); - if (notify && aLabel) - ok(aLabel.test(notify.label), "Notification shows correct message"); - if (aCallback) - aCallback(msg, notify); - } - - let notification = msg.getNotificationWithValue(aName); - if (!notification && aShown) { - window.addEventListener("AlertActive", function() { - window.removeEventListener("AlertActive", arguments.callee, true); - notification = msg.getNotificationWithValue(aName); - haveNotification(notification); - }, true); - } else { - haveNotification(notification); - } -} - -function checkAddonListing(aAddon, elt, aType) { - ok(!!elt, "Element exists for addon"); - checkAttribute(elt, "id", "urn:mozilla:item:" + aAddon.id); - checkAttribute(elt, "addonID", aAddon.id); - checkAttribute(elt, "typeName", aType); - checkAttribute(elt, "name", aAddon.name); - checkAttribute(elt, "version", aAddon.version); - if (aType == "search") { - checkAttribute(elt, "iconURL", aAddon.iconURL); - checkAttribute(elt, "description", aAddon.description) - checkAttribute(elt, "homepageURL", aAddon.homepageURL); - checkAttribute(elt, "sourceURL", aAddon.sourceURL); - ok(elt.install, "Extension has install property"); - } -} - -function checkUpdate(aSettings) { - let os = Services.obs; - let ul = new updateListener(aSettings); - os.addObserver(ul, "addon-update-ended", false); - - ExtensionsView.updateAll(); -} - -function get_addon_element(aId) { - return document.getElementById("urn:mozilla:item:" + aId); -} - -function open_manager(aView, aCallback) { - BrowserUI.showPanel("addons-container"); - - ExtensionsView.init(); - ExtensionsView.delayedInit(); - - window.addEventListener("ViewChanged", function() { - window.removeEventListener("ViewChanged", arguments.callee, true); - aCallback(); - }, true); -} - -function close_manager(aCallback) { - let prefsButton = document.getElementById("tool-preferences"); - prefsButton.click(); - - ExtensionsView.clearSection(); - ExtensionsView.clearSection("local"); - ExtensionsView._list = null; - ExtensionsView._restartCount = 0; - BrowserUI.hidePanel(); - - if (aCallback) - aCallback(); -} - -function loadUrl(aURL, aCallback, aNewTab) { - if (aNewTab) - gCurrentTab = Browser.addTab(aURL, true); - else - Browser.loadURI(aURL); - - gCurrentTab.browser.messageManager.addMessageListener("pageshow", function(aMessage) { - if (gCurrentTab.browser.currentURI.spec == aURL) { - gCurrentTab.browser.messageManager.removeMessageListener(aMessage.name, arguments.callee); - if (aCallback) - setTimeout(aCallback, 0); - } - }); -} - -function checkInstallPopup(aName, aCallback) { - testPrompt("Installing Add-on", aName, [ {label: "Install", click: true}, - {label: "Cancel", click: false}], - aCallback); -} - -function testPrompt(aTitle, aMessage, aButtons, aCallback) { - function doTest() { - let prompt = document.getElementById("prompt-confirm-dialog"); - ok(!!prompt, "Prompt shown"); - - if (prompt) { - let title = document.getElementById("prompt-confirm-title"); - let message = document.getElementById("prompt-confirm-message"); - is(aTitle, title.textContent, "Correct title shown"); - is(aMessage, message.textContent, "Correct message shown"); - - let buttons = document.querySelectorAll("#prompt-confirm-buttons-box .prompt-button"); - let clickButton = null; - is(buttons.length, aButtons.length, "Prompt has correct number of buttons"); - if (buttons.length == aButtons.length) { - for (let i = 0; i < buttons.length; i++) { - is(buttons[i].label, aButtons[i].label, "Button has correct label"); - if (aButtons[i].click) - clickButton = buttons[i]; - } - } - if (clickButton) - clickButton.click(); - } - if (aCallback) - aCallback(); - } - - if (!document.getElementById("prompt-confirm-dialog")) { - window.addEventListener("DOMWillOpenModalDialog", function() { - window.removeEventListener("DOMWillOpenModalDialog", arguments.callee, true); - // without this timeout, this can cause the prompt service to fail - setTimeout(doTest, 500); - }, true); - } else { - doTest(); - } -} - -// Installs an addon via the urlbar. -function installFromURLBar(aAddon) { - return function() { - AddonManager.addInstallListener({ - onInstallEnded: function (install) { - AddonManager.removeInstallListener(this); - checkInstallNotification(!aAddon.bootstrapped, function() { - open_manager(true, function() { - isRestartShown(!aAddon.bootstrapped, false, function() { - let elt = get_addon_element(aAddon.id); - if (aAddon.bootstrapped) { - checkAddonListing(aAddon, elt, "local"); - let button = document.getAnonymousElementByAttribute(elt, "anonid", "uninstall-button"); - ok(!!button, "Extension has uninstall button"); - - let updateButton = document.getElementById("addons-update-all"); - is(updateButton.disabled, false, "Update button is enabled"); - - ExtensionsView.uninstall(elt); - - elt = get_addon_element(aAddon.id); - ok(!elt, "Addon element removed during uninstall"); - Browser.closeTab(gCurrentTab); - close_manager(run_next_test); - } else { - ok(!elt, "Extension not in list"); - AddonManager.getAllInstalls(function(aInstalls) { - for(let i = 0; i < aInstalls.length; i++) { - aInstalls[i].cancel(); - } - Browser.closeTab(gCurrentTab); - close_manager(run_next_test); - }); - } - }); - }); - }); - } - }); - loadUrl(gTestURL, function() { - loadUrl(aAddon.sourceURL, null, false); - checkInstallAlert(true, function() { - checkDownloadNotification(function() { - checkInstallPopup(aAddon.name, function() { }); - }); - }); - }, true); - }; -} - -// Installs an addon from the addons pref pane, and then -// updates it if requested. Checks to make sure -// restart notifications are shown at the right time -function installFromAddonsPage(aAddon, aDoUpdate) { - return function() { - open_manager(null, function() { - let elt = get_addon_element(aAddon.id); - checkAddonListing(aAddon, elt); - installExtension(elt, new installListener({ - addon: aAddon, - onComplete: function() { - if (aDoUpdate) { - checkUpdate({ - addon: addons[aAddon.updateIndex], - onComplete: function() { - close_manager(); - run_next_test(); - } - }); - } else { - close_manager(); - run_next_test(); - } - } - })); - }); - } -} - -add_test(installFromURLBar(addons[0])); -add_test(installFromURLBar(addons[1])); -add_test(installFromAddonsPage(addons[0], true)); -add_test(installFromAddonsPage(addons[1], false)); - -function installListener(aSettings) { - this.onComplete = aSettings.onComplete; - this.addon = aSettings.addon; -} - -installListener.prototype = { - onNewInstall : function(install) { }, - onDownloadStarted : function(install) { }, - onDownloadProgress : function(install) { }, - onDownloadEnded : function(install) { }, - onDownloadCancelled : function(install) { }, - onDownloadFailed : function(install) { - if(this.addon.willFail) - ok(false, "Install failed"); - }, - onInstallStarted : function(install) { }, - onInstallEnded : function(install, addon) { - let self = this; - isRestartShown(!this.addon.bootstrapped, false, function() { - if(self.onComplete) - self.onComplete(); - }); - }, - onInstallCancelled : function(install) { }, - onInstallFailed : function(install) { - if(this.willFail) - ok(false, "Install failed"); - }, - onExternalInstall : function(install, existing, needsRestart) { }, -}; - -function updateListener(aSettings) { - this.onComplete = aSettings.onComplete; - this.addon = aSettings.addon; -} - -updateListener.prototype = { - observe: function (aSubject, aTopic, aData) { - switch(aTopic) { - case "addon-update-ended" : - let json = aSubject.QueryInterface(Ci.nsISupportsString).data; - let update = JSON.parse(json); - if(update.id == this.addon.id) { - let os = Services.obs; - os.removeObserver(this, "addon-update-ended", false); - - let element = get_addon_element(update.id); - ok(!!element, "Have element for upgrade"); - - let self = this; - isRestartShown(!this.addon.bootstrapped, true, function() { - if(self.onComplete) - self.onComplete(); - }); - } - break; - } - }, -} diff --git a/mobile/android/chrome/tests/browser_addons_locales.js b/mobile/android/chrome/tests/browser_addons_locales.js deleted file mode 100644 index 1d9bc1add664..000000000000 --- a/mobile/android/chrome/tests/browser_addons_locales.js +++ /dev/null @@ -1,64 +0,0 @@ -var localeList = serverRoot + "locales_list.sjs"; -var PREF_LOCALE_LIST = "extensions.getLocales.get.url"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/LocaleRepository.jsm"); -Components.utils.import("resource://gre/modules/AddonManager.jsm"); - -function test() { - waitForExplicitFinish(); - runNextTest(); -} - -function end_test() { - Services.prefs.clearUserPref(PREF_LOCALE_LIST); -} - -registerCleanupFunction(end_test); - -gTests.push({ - addon: null, - desc: "Test the values returned from _getLocalesInAddon", - run: function() { - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList); - LocaleRepository.getLocales(this.listLoaded.bind(this)); - }, - - listLoaded: function(aLocales) { - is(aLocales.length, 1, "Correct number of locales were found"); - aLocales[0].addon.install.addListener(this); - aLocales[0].addon.install.install(); - }, - - onInstallEnded: function(aInstall, aAddon) { - aInstall.removeListener(this); - this.addon = aAddon; - info("Installed " + aAddon.id); - - try { - ExtensionsView._getLocalesInAddon(aAddon, null); - ok(false, "_getLocalesInAddon should have thrown with a null callback"); - } catch(ex) { - ok(ex, "_getLocalesInAddon requires a callback") - } - - try { - ExtensionsView._getLocalesInAddon(aAddon, "foo"); - ok(false, "_getLocalesInAddons should have thrown without a non-function callback"); - } catch(ex) { - ok(ex, "_getLocalesInAddon requires the callback be a function") - } - - ExtensionsView._getLocalesInAddon(aAddon, this.gotLocales.bind(this)); - }, - - gotLocales: function(aLocales) { - is(aLocales.length, 2, "Correct number of locales were found"); - ok(aLocales.indexOf("te-st") > -1, "te-st locale found"); - ok(aLocales.indexOf("te-st-a") > -1, "te-st-a locale found"); - - // locales can't be restartless yet, so we can't really test the uninstall code - this.addon.install.cancel(); - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_appmenu.js b/mobile/android/chrome/tests/browser_appmenu.js deleted file mode 100644 index 972b0ba0d817..000000000000 --- a/mobile/android/chrome/tests/browser_appmenu.js +++ /dev/null @@ -1,139 +0,0 @@ -let gTests = []; -let gCurrentTest = null; -let Panels = [AllPagesList, HistoryList, BookmarkList]; - -let removedForTestButtons = []; - -function test() { - waitForExplicitFinish(); - - // Make sure we start the test with less than a full menu - let menu = document.getElementById("appmenu"); - while (menu.children.length > 5) - removedForTestButtons.push(menu.removeChild(menu.lastChild)); - - setTimeout(runNextTest, 200); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } else { - // Add back any removed buttons - let menu = document.getElementById("appmenu"); - removedForTestButtons.forEach(function(aButton) { - menu.appendChild(aButton); - }); - - // Close the awesome panel just in case - AwesomeScreen.activePanel = null; - finish(); - } -} - -gTests.push({ -// This test will keep adding buttons and checking the result until there are a -// total of 9 buttons, then it will (one at a time) hide 3 items and check the -// result again. - - desc: "Test for showing the application menu", - newButtons: [], - hidden: 0, - - run: function() { - addEventListener("PopupChanged", gCurrentTest.popupOpened, false) - CommandUpdater.doCommand("cmd_menu"); - }, - - addButton: function() { - info("Adding a new button\n"); - let menu = document.getElementById("appmenu"); - let newButton = menu.children[0].cloneNode(true); - menu.appendChild(newButton); - gCurrentTest.newButtons.push(newButton); - }, - - popupOpened: function() { - removeEventListener("PopupChanged", gCurrentTest.popupOpened, false); - let menu = document.getElementById("appmenu"); - ok(!menu.hidden, "App menu is shown"); - - let more = document.getElementById("appmenu-more-button"); - if (menu.children.length > 6) { - ok(!!more, "More button is shown"); - addEventListener("PopupChanged", gCurrentTest.moreShown, false); - more.click(); - } else { - ok(!more, "More button is hidden"); - addEventListener("PopupChanged", gCurrentTest.popupClosed, false); - EventUtils.synthesizeKey("VK_ESCAPE", {}, window); - } - }, - - popupClosed: function() { - removeEventListener("PopupChanged", gCurrentTest.popupClosed, false); - let menu = document.getElementById("appmenu"); - ok(document.getElementById("appmenu").hidden, "Esc hides menus"); - if (menu.children.length < 9) { - gCurrentTest.addButton(); - gCurrentTest.run(); - } else { - menu.children[gCurrentTest.hidden].hidden = true; - gCurrentTest.hidden++; - addEventListener("PopupChanged", gCurrentTest.menuitemHidden, false) - CommandUpdater.doCommand("cmd_menu"); - } - }, - - moreShown: function(aEvent) { - // AppMenu hiding - if (!aEvent.detail) - return; - - let menu = document.getElementById("appmenu"); - ok(document.getElementById("appmenu").hidden, "Clicking more button hides menu"); - - removeEventListener("PopupChanged", gCurrentTest.moreShown, false); - let listbox = document.getElementById("appmenu-overflow-commands"); - is(listbox.childNodes.length, (menu.childNodes.length - 5), "Menu popup only shows overflow children"); - - addEventListener("PopupChanged", gCurrentTest.popupClosed, false); - EventUtils.synthesizeKey("VK_ESCAPE", {}, window); - }, - - menuitemHidden: function() { - removeEventListener("PopupChanged", gCurrentTest.menuitemHidden, false); - let menu = document.getElementById("appmenu"); - ok(!document.getElementById("appmenu").hidden, "App menu is shown"); - - let more = document.getElementById("appmenu-more-button"); - if (menu.children.length - gCurrentTest.hidden > 6) { - ok(more, "More button is shown"); - addEventListener("PopupChanged", gCurrentTest.popupClosed, false); - } else { - ok(!more, "More button is hidden"); - addEventListener("PopupChanged", gCurrentTest.popupClosedAgain, false); - } - EventUtils.synthesizeKey("VK_ESCAPE", {}, window); - }, - - popupClosedAgain: function() { - removeEventListener("PopupChanged", gCurrentTest.popupClosedAgain, false) - let menu = document.getElementById("appmenu"); - while (gCurrentTest.hidden > 0) { - gCurrentTest.hidden--; - menu.children[gCurrentTest.hidden].hidden = false; - } - - gCurrentTest.newButtons.forEach(function(aButton) { - menu.removeChild(aButton); - }); - - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_autocomplete.html b/mobile/android/chrome/tests/browser_autocomplete.html deleted file mode 100644 index 93d424fa627e..000000000000 --- a/mobile/android/chrome/tests/browser_autocomplete.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - -

- - - - - - - - - - - - -

- - - - - - -

- - - diff --git a/mobile/android/chrome/tests/browser_autocomplete.js b/mobile/android/chrome/tests/browser_autocomplete.js deleted file mode 100644 index 5649946722a9..000000000000 --- a/mobile/android/chrome/tests/browser_autocomplete.js +++ /dev/null @@ -1,184 +0,0 @@ -let testURL = chromeRoot + "browser_autocomplete.html"; -messageManager.loadFrameScript(chromeRoot + "remote_autocomplete.js", true); - -let newTab = null; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -function test() { - // This test is async - waitForExplicitFinish(); - - // Ensure the form helper is initialized - try { - FormHelperUI.enabled; - } - catch(e) { - FormHelperUI.init(); - } - - // Need to wait until the page is loaded - messageManager.addMessageListener("pageshow", function(aMessage) { - if (newTab && newTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - BrowserUI.closeAutoComplete(true); - setTimeout(runNextTest, 0); - } - }); - - newTab = Browser.addTab(testURL, true); -} - - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - // Add any cleanup code here - - // Close our tab when finished - Browser.closeTab(newTab); - } - finally { - // We must finialize the tests - finish(); - } - } -} - -function waitForAutocomplete(aCallback) { - window.addEventListener("contentpopupshown", function(aEvent) { - window.removeEventListener(aEvent.type, arguments.callee, false); - setTimeout(function() { - aCallback(FormHelperUI._currentElement.list); - }, 0); - }, false); -}; - -let data = [ - { label: "foo", value: "foo" }, - { label: "Somewhat bar", value: "bar" }, - { label: "foobar", value: "_" } -]; - -//------------------------------------------------------------------------------ -// Case: Click on a datalist element and show suggestions -gTests.push({ - desc: "Click on a datalist element and show suggestions", - - run: function() { - waitForAutocomplete(gCurrentTest.checkData); - AsyncTests.waitFor("TestRemoteAutocomplete:Click", - { id: "input-datalist-1" }, function(json) {}); - }, - - // Check that the data returned by the autocomplete handler on the content - // side is correct - checkData: function(aOptions) { - for (let i = 0; i < aOptions.length; i++) { - let option = aOptions[i]; - let valid = data[i]; - - is(option.label, valid.label, "Label should be equal (" + option.label + ", " + valid.label +")"); - is(option.value, valid.value, "Value should be equal (" + option.value + ", " + valid.value +")"); - } - - // Wait until suggestions box has been popupated - waitFor(gCurrentTest.checkUI, function() { - let suggestionsBox = document.getElementById("form-helper-suggestions"); - return suggestionsBox.childNodes.length; - }); - }, - - // Check that the UI reflect the specificity of the data - checkUI: function() { - let suggestionsBox = document.getElementById("form-helper-suggestions"); - let suggestions = suggestionsBox.childNodes; - - for (let i = 0; i < suggestions.length; i++) { - let suggestion = suggestions[i]; - let valid = data[i]; - let label = suggestion.getAttribute("value"); - let value = suggestion.getAttribute("data"); - - is(label, valid.label, "Label should be equal (" + label + ", " + valid.label +")"); - is(value, valid.value, "Value should be equal (" + value + ", " + valid.value +")"); - } - - gCurrentTest.checkUIClick(0); - }, - - // Ensure that clicking on a given datalist element set the right value in - // the input box - checkUIClick: function(aIndex) { - let suggestionsBox = document.getElementById("form-helper-suggestions"); - - let suggestion = suggestionsBox.childNodes[aIndex]; - if (!suggestion) { - gCurrentTest.finish(); - return; - } - - // Use the form helper autocompletion helper - FormHelperUI.doAutoComplete(suggestion); - - AsyncTests.waitFor("TestRemoteAutocomplete:Check", { id: "input-datalist-1" }, function(json) { - is(json.result, suggestion.getAttribute("data"), "The target input value should be set to " + data); - gCurrentTest.checkUIClick(aIndex + 1); - }); - }, - - finish: function() { - // Close the form assistant - FormHelperUI.hide(); - - - AsyncTests.waitFor("TestRemoteAutocomplete:Reset", { id: "input-datalist-1" }, function(json) { - runNextTest(); - }); - } -}); - -//------------------------------------------------------------------------------ -// Case: Check arrows visibility -gTests.push({ - desc: "Check arrows visibility", - - run: function() { - let popup = document.getElementById("form-helper-suggestions-container"); - popup.addEventListener("contentpopupshown", function(aEvent) { - aEvent.target.removeEventListener(aEvent.type, arguments.callee, false); - waitFor(gCurrentTest.checkNoArrows, function() { - return FormHelperUI._open; - }); - }, false); - - AsyncTests.waitFor("TestRemoteAutocomplete:Click", - { id: "input-datalist-3" }, function(json) {}); - }, - - checkNoArrows: function() { - let scrollbox = document.getElementById("form-helper-suggestions"); - todo_is(scrollbox._scrollButtonUp.collapsed, true, "Left button should be collapsed"); - todo_is(scrollbox._scrollButtonDown.collapsed, true, "Right button should be collapsed"); - gCurrentTest.finish(); - }, - - finish: function() { - // Close the form assistant - FormHelperUI.hide(); - - runNextTest(); - } -}); - diff --git a/mobile/android/chrome/tests/browser_autocompletesearch.js b/mobile/android/chrome/tests/browser_autocompletesearch.js deleted file mode 100644 index e7129eafe8ec..000000000000 --- a/mobile/android/chrome/tests/browser_autocompletesearch.js +++ /dev/null @@ -1,108 +0,0 @@ -Components.utils.import("resource://gre/modules/Services.jsm"); - -let match= [ - ["http://example.com/a", "A", "favicon", "http://example.com/a/favicon.png"], - ["http://example.com/b", "B", "favicon", "http://example.com/b/favicon.png"], - ["http://example.com/c", "C", "favicon", "http://example.com/c/favicon.png"], - ["http://example.com/d", "D", "bookmark", "http://example.com/d/favicon.png"], - ["http://example.com/e", "E", "boolmark", "http://example.com/e/favicon.png"] -]; - -var gAutocomplete = null; -var gProfileDir = null; - -function test() { - waitForExplicitFinish(); - - gProfileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - - // First we need to remove the existing cache file so we can control the state of the service - let oldCacheFile = gProfileDir.clone(); - oldCacheFile.append("autocomplete.json"); - if (oldCacheFile.exists()) - oldCacheFile.remove(true); - - // Since we removed the cache file, we know the service will need to write out a new - // file. We use that as a trigger to move forward. - Services.obs.addObserver(function (aSubject, aTopic, aData) { - Services.obs.removeObserver(arguments.callee, aTopic, false); - saveMockCache(); - }, "browser:cache-session-history-write-complete", false); - - // This might trigger an init or it may have already happened. That's why we need - // to do some work to control the state. - gAutocomplete = Cc["@mozilla.org/autocomplete/search;1?name=history"].getService(Ci.nsIAutoCompleteSearch); - - // Trigger the new cache to be written out, since the existing was removed - Services.obs.notifyObservers(null, "browser:cache-session-history-reload", ""); -} - -function saveMockCache() { - // Now we write our own mock data cache into the profile - let oldCacheFile = gProfileDir.clone(); - oldCacheFile.append("autocomplete.json"); - if (oldCacheFile.exists()) - oldCacheFile.remove(true); - - let mockCachePath = gTestPath; - info("mock path: " + mockCachePath); - let mockCacheURI = getResolvedURI(mockCachePath); - info("mock URI: " + mockCacheURI.spec); - if (mockCacheURI instanceof Ci.nsIJARURI) { - // Android tests are stored in a JAR file, so we need to extract the mock_autocomplete.json file - info("jar file: " + mockCacheURI.JARFile.spec); - let zReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader); - let fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].getService(Ci.nsIFileProtocolHandler); - let fileName = fileHandler.getFileFromURLSpec(mockCacheURI.JARFile.spec); - zReader.open(fileName); - - let extract = mockCacheURI.spec.split("!")[1]; - extract = extract.substring(1, extract.lastIndexOf("/") + 1); - extract += "mock_autocomplete.json"; - info("extract path: " + extract); - let target = gProfileDir.clone(); - target.append("autocomplete.json"); - info("target path: " + target.path); - zReader.extract(extract, target); - } else { - // Tests are run from a folder, so we can just copy the mock_autocomplete.json file - let mockCacheFile = getChromeDir(mockCacheURI); - info("mock file: " + mockCacheFile.path); - mockCacheFile.append("mock_autocomplete.json"); - mockCacheFile.copyToFollowingLinks(gProfileDir, "autocomplete.json"); - } - - // Listen for when the mock cache has been loaded - Services.obs.addObserver(function (aSubject, aTopic, aData) { - Services.obs.removeObserver(arguments.callee, aTopic, false); - runTest(); - }, "browser:cache-session-history-read-complete", false); - - // Trigger the new mock cache to be loaded - Services.obs.notifyObservers(null, "browser:cache-session-history-reload", ""); -} - -function runTest() { - let cacheFile = gProfileDir.clone(); - cacheFile.append("autocomplete.json"); - ok(cacheFile.exists(), "Mock autocomplete JSON cache file exists"); - - // Compare the mock data, which should be used now that we loaded it into the service - gAutocomplete.startSearch("", "", null, { - onSearchResult: function(search, result) { - is(result.matchCount, 5, "matchCount is correct"); - - for (let i=0; i<5; i++) { - is(result.getValueAt(i), match[i][0], "value matches"); - is(result.getCommentAt(i), match[i][1], "comment matches"); - is(result.getStyleAt(i), match[i][2], "style matches"); - is(result.getImageAt(i), match[i][3], "image matches"); - } - - if (cacheFile.exists()) - cacheFile.remove(true); - - finish(); - } - }); -} diff --git a/mobile/android/chrome/tests/browser_awesomescreen.js b/mobile/android/chrome/tests/browser_awesomescreen.js deleted file mode 100644 index 6283881b1dfc..000000000000 --- a/mobile/android/chrome/tests/browser_awesomescreen.js +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Bug 436069 - Fennec browser-chrome tests to verify correct navigation into the - * differents part of the awesome panel - */ - -let testURL_01 = chromeRoot + "browser_blank_01.html"; - -let gTests = []; -let gCurrentTest = null; -let Panels = [AllPagesList, HistoryList, BookmarkList]; - -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - setTimeout(runNextTest, 200); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - - // Ensure all tests start with hidden awesome screen - AwesomeScreen.activePanel = null; - - gCurrentTest.run(); - } - else { - // Close the awesome panel just in case - AwesomeScreen.activePanel = null; - finish(); - } -} - -function waitForNavigationPanel(aCallback, aWaitForHide) { - let evt = aWaitForHide ? "NavigationPanelHidden" : "NavigationPanelShown"; - info("waitFor " + evt + "(" + Components.stack.caller + ")"); - window.addEventListener(evt, function(aEvent) { - info("receive " + evt); - window.removeEventListener(aEvent.type, arguments.callee, false); - setTimeout(aCallback, 0); - }, false); -} - -//------------------------------------------------------------------------------ -// Case: Test awesome bar collapsed state -gTests.push({ - desc: "Test awesome bar collapsed state", - - run: function() { - waitForNavigationPanel(gCurrentTest.onPopupShown); - AllPagesList.doCommand(); - }, - - onPopupShown: function() { - is(AwesomeScreen.activePanel, AllPagesList, "AllPagesList should be visible"); - ok(!BrowserUI._edit.collapsed, "The urlbar edit element is visible"); - ok(BrowserUI._title.collapsed, "The urlbar title element is not visible"); - - waitForNavigationPanel(gCurrentTest.onPopupHidden, true); - - EventUtils.synthesizeKey("VK_ESCAPE", {type: "keypress"}, window); - }, - - onPopupHidden: function() { - is(AwesomeScreen.activePanel, null, "AllPagesList should be dismissed"); - ok(BrowserUI._edit.collapsed, "The urlbar edit element is not visible"); - ok(!BrowserUI._title.collapsed, "The urlbar title element is visible"); - - runNextTest(); - } -}); - - -//------------------------------------------------------------------------------ -// Case: Test typing a character should dismiss the awesome header -gTests.push({ - desc: "Test typing a character should dismiss the awesome header", - - run: function() { - waitForNavigationPanel(gCurrentTest.onPopupReady); - AllPagesList.doCommand(); - }, - - onPopupReady: function() { - is(AwesomeScreen.activePanel == AllPagesList, true, "AllPagesList should be visible"); - - let awesomeHeader = document.getElementById("awesome-header"); - is(awesomeHeader.hidden, false, "Awesome header should be visible"); - - BrowserUI._edit.addEventListener("onsearchbegin", function(aEvent) { - if (BrowserUI._edit.value == "") - return; - - BrowserUI._edit.removeEventListener(aEvent.type, arguments.callee, true); - let awesomeHeader = document.getElementById("awesome-header"); - is(awesomeHeader.hidden, true, "Awesome header should be hidden"); - gCurrentTest.onKeyPress(); - }, true); - EventUtils.synthesizeKey("A", {}, window); - }, - - onKeyPress: function(aKey, aHidden) { - waitForNavigationPanel(function() { - let awesomeHeader = document.getElementById("awesome-header"); - is(awesomeHeader.hidden, false, "Awesome header should be visible"); - runNextTest(); - }, true); - - EventUtils.synthesizeKey("VK_ESCAPE", {type: "keypress"}, window); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test typing a character should open the awesome bar -gTests.push({ - desc: "Test typing a character should open the All Pages List", - - run: function() { - waitForNavigationPanel(gCurrentTest.onPopupReady); - BookmarkList.doCommand(); - }, - - onPopupReady: function() { - BrowserUI._edit.addEventListener("onsearchbegin", function(aEvent) { - BrowserUI._edit.removeEventListener(aEvent.type, arguments.callee, false); - gCurrentTest.onSearchBegin(); - }, false); - EventUtils.synthesizeKey("I", {}, window); - }, - - onSearchBegin: function() { - let awesomeHeader = document.getElementById("awesome-header"); - is(awesomeHeader.hidden, true, "Awesome header should be hidden"); - is(AwesomeScreen.activePanel == AllPagesList, true, "AllPagesList should be opened on a keydown"); - is(BrowserUI._edit.readOnly, false, "urlbar should not be readonly after an input"); - - waitForNavigationPanel(gCurrentTest.onPopupHidden, true); - EventUtils.synthesizeKey("VK_ESCAPE", {type: "keypress"}, window); - }, - - onPopupHidden: function() { - is(AwesomeScreen.activePanel == null, true, "VK_ESCAPE should have dismissed the awesome panel"); - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test opening the awesome panel and checking the urlbar readonly state -gTests.push({ - desc: "Test opening the awesome panel and checking the urlbar readonly state", - - run: function() { - is(BrowserUI._edit.readOnly, true, "urlbar input textbox should be readonly"); - - waitForNavigationPanel(gCurrentTest.onPopupReady); - AllPagesList.doCommand(); - }, - - onPopupReady: function() { - is(Elements.urlbarState.getAttribute("mode"), "edit", "bcast_urlbarState mode attribute should be equal to 'edit'"); - - let edit = BrowserUI._edit; - is(edit.readOnly, BrowserUI._isKeyboardFullscreen(), "urlbar input textbox is readonly if keyboard is fullscreen, editable otherwise"); - - let urlString = BrowserUI.getDisplayURI(Browser.selectedBrowser); - if (Util.isURLEmpty(urlString)) - urlString = ""; - - let firstPanel = true; - Panels.forEach(function(aPanel) { - aPanel.doCommand(); - is(AwesomeScreen.activePanel, aPanel, "The panel " + aPanel.panel.id + " should be selected"); - if (firstPanel) { - // First panel will have selected text, if we are in portrait - is(edit.readOnly, BrowserUI._isKeyboardFullscreen(), "urlbar input textbox is readonly if keyboard is fullscreen, editable otherwise"); - } else { - is(edit.readOnly, true, "urlbar input textbox be readonly if not the first panel"); - } - edit.click(); - is(edit.readOnly, false, "urlbar input textbox should not be readonly after a click, in both landscape and portrait"); - is(edit.value, urlString, "urlbar value should be equal to the page uri"); - - firstPanel = false; - }); - - setTimeout(function() { - runNextTest(); - }, 0); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test opening the awesome panel and checking the urlbar selection -gTests.push({ - desc: "Test opening the awesome panel and checking the urlbar selection", - - run: function() { - BrowserUI.closeAutoComplete(true); - this.currentTab = BrowserUI.newTab(testURL_01); - - // Need to wait until the page is loaded - messageManager.addMessageListener("pageshow", - function(aMessage) { - if (gCurrentTest.currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - setTimeout(gCurrentTest.onPageReady, 0); - } - }); - }, - - onPageReady: function() { - waitForNavigationPanel(gCurrentTest.onPopupReady); - - AllPagesList.doCommand(); - }, - - onPopupReady: function() { - let edit = BrowserUI._edit; - - let firstPanel = true; - Panels.forEach(function(aPanel) { - aPanel.doCommand(); - if (firstPanel && !BrowserUI._isKeyboardFullscreen()) { - // First panel will have selected text, if we are in portrait - ok(edit.selectionStart == 0 && edit.selectionEnd == edit.textLength, "[case 1] urlbar text should be selected on a simple show"); - edit.click(); - // The click is not sync enough for this to work - todo(edit.selectionStart == edit.selectionEnd, "[case 1] urlbar text should not be selected on a click"); - } else { - ok(edit.selectionStart == edit.selectionEnd, "[case 2] urlbar text should not be selected on a simple show"); - edit.click(); - ok(edit.selectionStart == 0 && edit.selectionEnd == edit.textLength, "[case 2] urlbar text should be selected on a click"); - } - firstPanel = false; - }); - - // We are disabling it early, otherwise calling edit.click(); quickly made input.js though this is a double click (sigh) - let oldDoubleClickSelectsAll = Services.prefs.getBoolPref("browser.urlbar.doubleClickSelectsAll"); - Services.prefs.setBoolPref("browser.urlbar.doubleClickSelectsAll", false); - - let oldClickSelectsAll = edit.clickSelectsAll; - edit.clickSelectsAll = false; - firstPanel = true; - Panels.forEach(function(aPanel) { - aPanel.doCommand(); - if (firstPanel && !BrowserUI._isKeyboardFullscreen()) { - // First panel will have selected text, if we are in portrait - ok(edit.selectionStart == 0 && edit.selectionEnd == edit.textLength, "[case 1] urlbar text should be selected on a simple show"); - edit.click(); - // The click is not sync enough for this to work - todo(edit.selectionStart == edit.selectionEnd, "[case 1] urlbar text should not be selected on a click"); - } else { - ok(edit.selectionStart == edit.selectionEnd, "[case 2] urlbar text should not be selected on a simple show"); - edit.click(); - ok(edit.selectionStart == edit.selectionEnd, "[case 2] urlbar text should not be selected on a click"); - } - - firstPanel = false; - }); - - Panels.forEach(function(aPanel) { - aPanel.doCommand(); - ok(edit.selectionStart == edit.selectionEnd, "urlbar text should not be selected on a simple show"); - edit.click(); - edit.click(); - ok(edit.selectionStart == edit.selectionEnd, "urlbar text should not be selected on a double click"); - }); - - Services.prefs.setBoolPref("browser.urlbar.doubleClickSelectsAll", oldDoubleClickSelectsAll); - - Panels.forEach(function(aPanel) { - aPanel.doCommand(); - ok(edit.selectionStart == edit.selectionEnd, "urlbar text should not be selected on a simple show"); - edit.click(); - edit.click(); - ok(edit.selectionStart == 0 && edit.selectionEnd == edit.textLength, "urlbar text should be selected on a double click"); - }); - - edit.clickSelectsAll = oldClickSelectsAll; - - // Ensure the tab is well closed before doing the rest of the code, otherwise - // this cause some bugs with the composition events - let tabCount = Browser.tabs.length; - Browser.closeTab(gCurrentTest.currentTab, { forceClose: true }); - waitFor(runNextTest, function() Browser.tabs.length == tabCount - 1); - } -}); - -// Case: Test context clicks on awesome panel -gTests.push({ - desc: "Test context clicks on awesome panel", - - _panelIndex : 0, - _contextOpts : [ - ["link-openable", "link-shareable"], - ["link-openable", "link-shareable"], - ["edit-bookmark", "link-shareable", "link-openable"], - ], - - clearContextTypes: function clearContextTypes() { - if (ContextHelper.popupState) - ContextHelper.hide(); - }, - - checkContextTypes: function checkContextTypes(aTypes) { - let commandlist = document.getElementById("context-commands"); - - for (let i=0; i -1) { - // command should be visible - if(command.hidden == true) - return false; - } else { - if(command.hidden == false) - return false; - } - } - return true; - }, - - run: function() { - waitForNavigationPanel(gCurrentTest.onPopupReady); - AllPagesList.doCommand(); - }, - - onPopupReady: function() { - let self = this; - if(self._panelIndex < Panels.length) { - let panel = Panels[self._panelIndex]; - panel.doCommand(); - - self.clearContextTypes(); - - EventUtils.synthesizeMouse(panel.panel, panel.panel.width / 2, panel.panel.height / 2, { type: "mousedown" }); - setTimeout(function() { - EventUtils.synthesizeMouse(panel.panel, panel.panel.width / 2, panel.panel.height / 2, { type: "mouseup" }); - ok(self.checkContextTypes(self._contextOpts[self._panelIndex]), "Correct context menu shown for panel"); - self.clearContextTypes(); - - self._panelIndex++; - self.onPopupReady(); - }, 500); - } else { - runNextTest(); - } - } -}); - - -// Case: Test compositionevent -gTests.push({ - desc: "Test sending composition events", - _textValue: null, - get popup() { - delete this.popup; - return this.popup = document.getElementById("popup_autocomplete"); - }, - - get popupHeader() { - delete this.popupHeader; - return this.popupHeader = document.getElementById("awesome-header"); - }, - - get inputField() { - delete this.inputField; - return this.inputField = document.getElementById("urlbar-edit"); - }, - - run: function() { - // Saving value to compare the result before and after the composition event - gCurrentTest._textValue = gCurrentTest.inputField.value; - - window.addEventListener("popupshown", function() { - window.removeEventListener("popupshown", arguments.callee, false); - if (BrowserUI._isKeyboardFullscreen()) - gCurrentTest.inputField.readOnly = false; - setTimeout(gCurrentTest.onPopupReady, 0); - }, false); - AllPagesList.doCommand(); - }, - - _checkState: function() { - ok(gCurrentTest.popup._popupOpen, "AutoComplete popup should be opened"); - is(gCurrentTest.popupHeader.hidden, false, "AutoComplete popup header should be visible"); - is(gCurrentTest.inputField.value, gCurrentTest._textValue, "Value should not have changed"); - }, - - onPopupReady: function() { - gCurrentTest._checkState(); - - window.addEventListener("compositionstart", function() { - window.removeEventListener("compositionstart", arguments.callee, false); - setTimeout(gCurrentTest.onCompositionStart, 0) - }, false); - Browser.windowUtils.sendCompositionEvent("compositionstart", "", ""); - }, - - onCompositionStart: function() { - gCurrentTest._checkState(); - - window.addEventListener("compositionend", function() { - window.removeEventListener("compositionend", arguments.callee, false); - setTimeout(gCurrentTest.onCompositionEnd, 0) - }, false); - Browser.windowUtils.sendCompositionEvent("compositionend", "", ""); - }, - - onCompositionEnd: function() { - /* TODO: This is currently failing (bug 642771) - gCurrentTest._checkState(); - - let isHiddenHeader = function() { - return gCurrentTest.popupHeader.hidden; - } - - // Wait to be sure there the header won't dissapear - // XXX this sucks because it means we'll be stuck 500ms if the test succeed - // but I don't have a better idea about how to do it for now since we don't - // that to happen! - - waitForAndContinue(function() { - gCurrentTest._checkState(); - runNextTest(); - }, isHiddenHeader, Date.now() + 500); - */ - runNextTest(); - } -}); - -// Case: Test context popup dismiss on top of awesome panel -gTests.push({ - desc: "Case: Test context popup dismiss on top of awesome panel", - - run: function() { - waitForNavigationPanel(gCurrentTest.onPopupReady); - AllPagesList.doCommand(); - }, - - onPopupReady: function() { - EventUtils.synthesizeMouse(AllPagesList.panel, AllPagesList.panel.width / 2, - AllPagesList.panel.height / 2, { type: "mousedown" }); - - // Simulate a long tap - setTimeout(function(self) { - EventUtils.synthesizeMouse(AllPagesList.panel, AllPagesList.panel.width / 2, - AllPagesList.panel.height / 2, { type: "mouseup" }); - - let contextContainer = document.getElementById("context-container"); - - ok(!AllPagesList.panel.hidden, "The context popup is still visible after long tap"); - ok(!contextContainer.hidden, "The context popup is visible after long tap"); - - EventUtils.synthesizeMouse(AllPagesList.panel, 0, 0, {}); - - ok(contextContainer.hidden, "The context popup is not visible after tap"); - ok(!AllPagesList.panel.hidden, "The awesome panel is still visible after popup is dismissed"); - - AwesomeScreen.activePanel = null; - runNextTest(); - }, 500, this); - } -}); diff --git a/mobile/android/chrome/tests/browser_blank_01.html b/mobile/android/chrome/tests/browser_blank_01.html deleted file mode 100644 index 8fd14cc1bebd..000000000000 --- a/mobile/android/chrome/tests/browser_blank_01.html +++ /dev/null @@ -1,6 +0,0 @@ - -Browser Blank Page 01 - -

Browser Blank Page 01

- - diff --git a/mobile/android/chrome/tests/browser_blank_02.html b/mobile/android/chrome/tests/browser_blank_02.html deleted file mode 100644 index 61d6b1f61acc..000000000000 --- a/mobile/android/chrome/tests/browser_blank_02.html +++ /dev/null @@ -1,7 +0,0 @@ - -Browser Blank Page 02 - - -

Browser Blank Page 02

- - diff --git a/mobile/android/chrome/tests/browser_blank_03.html b/mobile/android/chrome/tests/browser_blank_03.html deleted file mode 100644 index 57b38163dd30..000000000000 --- a/mobile/android/chrome/tests/browser_blank_03.html +++ /dev/null @@ -1,6 +0,0 @@ - -Browser Blank Page 03 - -

Browser Blank Page 03

- - diff --git a/mobile/android/chrome/tests/browser_bookmarks.js b/mobile/android/chrome/tests/browser_bookmarks.js deleted file mode 100644 index f71b597ad197..000000000000 --- a/mobile/android/chrome/tests/browser_bookmarks.js +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Bug 486490 - Fennec browser-chrome tests to verify correct implementation of chrome - * code in mobile/chrome/content in terms of integration with Places - * component, specifically for bookmark management. - */ - -var testURL_01 = chromeRoot + "browser_blank_01.html"; -var testURL_02 = chromeRoot + "browser_blank_02.html"; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - PlacesUtils.bookmarks.removeFolderChildren(BookmarkList.panel.mobileRoot); - } - finally { - // We must finialize the tests - finish(); - } - } -} - -function waitForPageShow(aCallback) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (gCurrentTest._currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - setTimeout(aCallback, 0); - } - }); -} - -function waitForNavigationPanel(aCallback, aWaitForHide) { - let evt = aWaitForHide ? "NavigationPanelHidden" : "NavigationPanelShown"; - info("waitFor " + evt + "(" + Components.stack.caller + ")"); - window.addEventListener(evt, function(aEvent) { - info("receive " + evt); - window.removeEventListener(aEvent.type, arguments.callee, false); - setTimeout(aCallback, 0); - }, false); -} - -//------------------------------------------------------------------------------ -// Case: Test adding a bookmark with the Star button -gTests.push({ - desc: "Test adding a bookmark with the Star button", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_01, true); - - // Need to wait until the page is loaded - waitForPageShow(gCurrentTest.onPageReady); - }, - - onPageReady: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - window.addEventListener("BookmarkCreated", function(aEvent) { - window.removeEventListener(aEvent.type, arguments.callee, false); - let bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); - ok(bookmark != -1, testURL_01 + " should be added."); - - Browser.closeTab(gCurrentTest._currentTab); - - runNextTest(); - }, false); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test clicking on a bookmark loads the web page -gTests.push({ - desc: "Test clicking on a bookmark loads the web page", - _currentTab: null, - - run: function() { - BrowserUI.closeAutoComplete(true); - this._currentTab = Browser.addTab(testURL_02, true); - - // Need to wait until the page is loaded - waitForPageShow(gCurrentTest.onPageReady); - }, - - onPageReady: function() { - // Wait for the bookmarks to load, then do the test - waitForNavigationPanel(gCurrentTest.onBookmarksReady); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - let bookmarkitem = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_01); - bookmarkitem.control.scrollBoxObject.ensureElementIsVisible(bookmarkitem); - - isnot(bookmarkitem, null, "Found the bookmark"); - is(bookmarkitem.getAttribute("uri"), testURL_01, "Bookmark has the right URL via attribute"); - is(bookmarkitem.spec, testURL_01, "Bookmark has the right URL via property"); - - // Create a listener for the opening bookmark - waitForPageShow(function() { - if (Services.appinfo.OS == "Android") - todo_is(gCurrentTest._currentTab.browser.currentURI.spec, testURL_01, "Opened the right bookmark"); - else - is(gCurrentTest._currentTab.browser.currentURI.spec, testURL_01, "Opened the right bookmark"); - - Browser.closeTab(gCurrentTest._currentTab); - - runNextTest(); - }); - - EventUtils.synthesizeMouse(bookmarkitem, bookmarkitem.width / 2, bookmarkitem.height / 2, {}); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test editing URI of existing bookmark -gTests.push({ - desc: "Test editing URI of existing bookmark", - - run: function() { - // Wait for the bookmarks to load, then do the test - waitForNavigationPanel(gCurrentTest.onBookmarksReady); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - // Go into edit mode - let bookmark = BookmarkList.panel.items[0]; - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmarkitem = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_01); - EventUtils.synthesizeMouse(bookmarkitem, bookmarkitem.width / 2, bookmarkitem.height / 2, {}); - - let uritextbox = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "uri"); - uritextbox.value = testURL_02; - - let donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); - donebutton.click(); - - let bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); - is(bookmark, -1, testURL_01 + " should no longer in bookmark"); - bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); - isnot(bookmark, -1, testURL_02 + " is in bookmark"); - - AwesomeScreen.activePanel = null; - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test editing title of existing bookmark -gTests.push({ - desc: "Test editing title of existing bookmark", - - run: function() { - // Wait for the bookmarks to load, then do the test - waitForNavigationPanel(gCurrentTest.onBookmarksReady); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - // Go into edit mode - let bookmark = BookmarkList.panel.items[0]; - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); - is(PlacesUtils.bookmarks.getItemTitle(bookmark), "Browser Blank Page 01", "Title remains the same."); - - let bookmarkitem = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - EventUtils.synthesizeMouse(bookmarkitem, bookmarkitem.width / 2, bookmarkitem.height / 2, {}); - - let titletextbox = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "name"); - let newtitle = "Changed Title"; - titletextbox.value = newtitle; - - let donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); - donebutton.click(); - - isnot(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)), -1, testURL_02 + " is still in bookmark."); - is(PlacesUtils.bookmarks.getItemTitle(bookmark), newtitle, "Title is changed."); - - AwesomeScreen.activePanel = null; - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test removing existing bookmark -gTests.push({ - desc: "Test removing existing bookmark", - bookmarkitem: null, - - run: function() { - // Wait for the bookmarks to load, then do the test - waitForNavigationPanel(gCurrentTest.onBookmarksReady); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - // Go into edit mode - let bookmark = BookmarkList.panel.items[0]; - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - bookmark.remove(); - - let bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); - ok(bookmark == -1, testURL_02 + " should no longer in bookmark"); - bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); - ok(bookmark == -1, testURL_01 + " should no longer in bookmark"); - - AwesomeScreen.activePanel = null; - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test editing title of desktop folder -gTests.push({ - desc: "Test editing title of desktop folder", - bmId: null, - - run: function() { - // Add a bookmark to the desktop area so the desktop folder is displayed - gCurrentTest.bmId = PlacesUtils.bookmarks - .insertBookmark(PlacesUtils.unfiledBookmarksFolderId, - makeURI(testURL_02), - Ci.nsINavBookmarksService.DEFAULT_INDEX, - testURL_02); - - // Wait for the bookmarks to load, then do the test - waitForNavigationPanel(gCurrentTest.onBookmarksReady); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - // Go into edit mode - let bookmarksPanel = BookmarkList.panel; - let bookmark = bookmarksPanel.items[0]; - bookmark.startEditing(); - - // Is the "desktop" folder showing? - let first = bookmarksPanel._children.firstChild; - is(first.itemId, bookmarksPanel._desktopFolderId, "Desktop folder is showing"); - - // Is the "desktop" folder in edit mode? - is(first.isEditing, false, "Desktop folder is not in edit mode"); - - // Do not allow the "desktop" folder to be editable by tap - EventUtils.synthesizeMouse(first, first.width / 2, first.height / 2, {}); - - // A tap on the "desktop" folder _should_ open the folder, not put it into edit mode. - // So we need to get the first item again. - first = bookmarksPanel._children.firstChild; - - // It should not be the "desktop" folder - isnot(first.itemId, bookmarksPanel._desktopFolderId, "Desktop folder is not showing after mouse click"); - - // But it should be one of the other readonly bookmark roots - isnot(bookmarksPanel._readOnlyFolders.indexOf(parseInt(first.itemId)), -1, "Desktop subfolder is showing after mouse click"); - - PlacesUtils.bookmarks.removeItem(gCurrentTest.bmId); - - AwesomeScreen.activePanel = null; - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_bookmarks_star.js b/mobile/android/chrome/tests/browser_bookmarks_star.js deleted file mode 100644 index 3dfac0eb5aec..000000000000 --- a/mobile/android/chrome/tests/browser_bookmarks_star.js +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Bug 486490 - Fennec browser-chrome tests to verify correct implementation of chrome - * code in mobile/chrome/content in terms of integration with Places - * component, specifically for bookmark management. - */ - -let testURL_01 = chromeRoot + "browser_blank_01.html"; -let testURL_02 = chromeRoot + "browser_blank_02.html"; - -function test() { - BookmarkHelper.logging = true; - - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} - -registerCleanupFunction(function() { - BookmarkHelper.logging = false; - PlacesUtils.bookmarks.removeFolderChildren(BookmarkList.panel.mobileRoot); -}); - -//------------------------------------------------------------------------------ -// Case: Test appearance and behavior of the bookmark popup -gTests.push({ - desc: "Test appearance and behavior of the bookmark popup", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_02, true); - - messageManager.addMessageListener("pageshow", - function(aMessage) { - if (gCurrentTest._currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - - // Wait a bit until Places is initialized - waitFor(gCurrentTest.onPageLoad, function() { - let mobileRoot = PlacesUtils.annotations.getItemsWithAnnotation("mobile/bookmarksRoot", {})[0]; - return mobileRoot; - }); - } - }); - }, - - onPageLoad: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupReady, function() { return BookmarkPopup.box.hidden == false; }); - }, - - onPopupReady: function() { - // Let's make it disappear again by clicking the star again - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupGone, function() { return BookmarkPopup.box.hidden == true; }); - }, - - onPopupGone: function() { - // Make sure it's hidden again - is(BookmarkPopup.box.hidden, true, "Bookmark popup should be hidden by clicking star"); - - // Let's make it appear again and continue the test - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupReady2, function() { return BookmarkPopup.box.hidden == false; }); - }, - - onPopupReady2: function() { - // Let's make it disappear again by clicking somewhere - let contentarea = document.getElementById("browsers"); - EventUtils.synthesizeMouse(contentarea, contentarea.clientWidth / 2, contentarea.clientHeight / 2, {}); - - waitFor(gCurrentTest.onPopupGone2, function() { return BookmarkPopup.box.hidden == true; }); - }, - - onPopupGone2: function() { - // Make sure it's hidden again - is(BookmarkPopup.box.hidden, true, "Bookmark popup should be hidden by clicking in content"); - - BookmarkHelper.removeBookmarksForURI(getBrowser().currentURI); - BrowserUI.closeTab(this._currentTab); - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test adding tags via star icon -gTests.push({ - desc: "Test adding tags via star icon", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_02, true); - - messageManager.addMessageListener("pageshow", - function(aMessage) { - if (gCurrentTest._currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - gCurrentTest.onPageLoad(); - } - }); - }, - - onPageLoad: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupReady, function() { return BookmarkPopup.box.hidden == false }); - }, - - onPopupReady: function() { - let editbutton = document.getElementById("bookmark-popup-edit"); - editbutton.click(); - - waitFor(gCurrentTest.onEditorReady, function() { - let item = document.getElementById("bookmark-item"); - return item && item.isEditing == true; - }); - }, - - onEditorReady: function() { - let bookmarkitem = document.getElementById("bookmark-item"); - bookmarkitem.tags = "tagone, tag two, tag-three, tag4"; - - let donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); - donebutton.click(); - - waitFor(gCurrentTest.onEditorDone, function() { return document.getElementById("bookmark-container").hidden == true; }); - }, - - onEditorDone: function() { - let uri = makeURI(testURL_02); - let tagsarray = PlacesUtils.tagging.getTagsForURI(uri, {}); - is(tagsarray.length, 4, "All tags are added."); - - BookmarkHelper.removeBookmarksForURI(uri); - BrowserUI.closeTab(this._currentTab); - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test editing uri via star icon -gTests.push({ - desc: "Test editing uri via star icon", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_02, true); - - messageManager.addMessageListener("pageshow", - function(aMessage) { - if (gCurrentTest._currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - gCurrentTest.onPageLoad(); - } - }); - }, - - onPageLoad: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupReady, function() { - return BookmarkPopup.box.hidden == false && - PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)) != -1; - }); - }, - - onPopupReady: function() { - let editbutton = document.getElementById("bookmark-popup-edit"); - editbutton.click(); - - waitFor(gCurrentTest.onEditorReady, function() { - let item = document.getElementById("bookmark-item"); - return item && item.isEditing == true; - }); - }, - - onEditorReady: function() { - let bookmarkitem = document.getElementById("bookmark-item"); - bookmarkitem.spec = testURL_01; - - let donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); - donebutton.click(); - - waitFor(gCurrentTest.onEditorDone, function() { return document.getElementById("bookmark-container").hidden == true; }); - }, - - onEditorDone: function() { - isnot(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)), -1, testURL_01 + " is now bookmarked"); - is(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)), -1, testURL_02 + " is no longer bookmarked"); - - BookmarkHelper.removeBookmarksForURI(makeURI(testURL_02)); - BrowserUI.closeTab(this._currentTab); - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test removing existing bookmark via popup -gTests.push({ - desc: "Test removing existing bookmark via popup", - _currentTab: null, - run: function() { - this._currentTab = Browser.addTab(testURL_01, true); - - messageManager.addMessageListener("pageshow", - function(aMessage) { - if (gCurrentTest._currentTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - gCurrentTest.onPageLoad(); - } - }); - }, - - onPageLoad: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - waitFor(gCurrentTest.onPopupReady, function() { - return BookmarkPopup.box.hidden == false && - PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)) != -1; - }); - }, - - onPopupReady: function() { - let removebutton = document.getElementById("bookmark-popup-remove"); - removebutton.click(); - - let bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); - ok(bookmark == -1, testURL_01 + " should no longer in bookmark"); - - BrowserUI.closeTab(this._currentTab); - - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_bookmarks_tags.js b/mobile/android/chrome/tests/browser_bookmarks_tags.js deleted file mode 100644 index 43849e3ce25c..000000000000 --- a/mobile/android/chrome/tests/browser_bookmarks_tags.js +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Bug 486490 - Fennec browser-chrome tests to verify correct implementation of chrome - * code in mobile/chrome/content in terms of integration with Places - * component, specifically for bookmark management. - */ - -var testURL_01 = chromeRoot + "browser_blank_01.html"; -var testURL_02 = chromeRoot + "browser_blank_02.html"; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - PlacesUtils.bookmarks.removeFolderChildren(BookmarkList.panel.mobileRoot); - } - finally { - // We must finialize the tests - finish(); - } - } -} - -//------------------------------------------------------------------------------ -// Case: Test adding tags to bookmark -gTests.push({ - desc: "Test adding tags to a bookmark", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_02, true); - function handleEvent() { - gCurrentTest._currentTab.browser.removeEventListener("load", handleEvent, true); - gCurrentTest.onPageLoad(); - }; - this._currentTab.browser.addEventListener("load", handleEvent , true); - }, - - onPageLoad: function() { - let starbutton = document.getElementById("tool-star"); - starbutton.click(); - - window.addEventListener("BookmarkCreated", function(aEvent) { - window.removeEventListener(aEvent.type, arguments.callee, false); - let bookmarkItem = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); - ok(bookmarkItem != -1, testURL_02 + " should be added."); - - // Wait for the bookmarks to load, then do the test - window.addEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - BrowserUI.doCommand("cmd_bookmarks"); - }, false); - }, - - onBookmarksReady: function() { - window.removeEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - - // Go into edit mode - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - let tagstextbox = document.getAnonymousElementByAttribute(bookmark, "anonid", "tags"); - tagstextbox.value = "tagone, tag two, tag-three, tag4"; - - let donebutton = document.getAnonymousElementByAttribute(bookmark, "anonid", "done-button"); - donebutton.click(); - - let tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); - is(tagsarray.length, 4, "All tags are associated with specified bookmark"); - - AwesomeScreen.activePanel = null; - - Browser.closeTab(gCurrentTest._currentTab); - - runNextTest(); - } -}); - -//------------------------------------------------------------------------------ -// Case: Test editing tags to bookmark -gTests.push({ - desc: "Test editing tags to bookmark", - - run: function() { - // Wait for the bookmarks to load, then do the test - window.addEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - window.removeEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - - - // Go into edit mode - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - - let taggeduri = PlacesUtils.tagging.getURIsForTag("tag-three"); - is(taggeduri[0].spec, testURL_02, "Old tag still associated with bookmark"); - - let tagstextbox = document.getAnonymousElementByAttribute(bookmark, "anonid", "tags"); - tagstextbox.value = "tagone, tag two, edited-tag-three, tag4"; - - let donebutton = document.getAnonymousElementByAttribute(bookmark, "anonid", "done-button"); - donebutton.click(); - - let untaggeduri = PlacesUtils.tagging.getURIsForTag("tag-three"); - is(untaggeduri, "", "Old tag is not associated with any bookmark"); - taggeduri = PlacesUtils.tagging.getURIsForTag("edited-tag-three"); - is(taggeduri[0].spec, testURL_02, "New tag is added to bookmark"); - let tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); - is(tagsarray.length, 4, "Bookmark still has same number of tags"); - - AwesomeScreen.activePanel = null; - - runNextTest(); - } -}); - - -//------------------------------------------------------------------------------ -// Case: Test removing tags from bookmark -gTests.push({ - desc: "Test removing tags from a bookmark", - _currentTab: null, - - run: function() { - // Wait for the bookmarks to load, then do the test - window.addEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - BrowserUI.doCommand("cmd_bookmarks"); - }, - - onBookmarksReady: function() { - window.removeEventListener("NavigationPanelShown", gCurrentTest.onBookmarksReady, false); - - // Go into edit mode - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - bookmark.startEditing(); - - waitFor(gCurrentTest.onEditorReady, function() { return bookmark.isEditing == true; }); - }, - - onEditorReady: function() { - let bookmark = document.getAnonymousElementByAttribute(BookmarkList.panel, "uri", testURL_02); - - let tagstextbox = document.getAnonymousElementByAttribute(bookmark, "anonid", "tags"); - tagstextbox.value = "tagone, tag two, tag4"; - - let donebutton = document.getAnonymousElementByAttribute(bookmark, "anonid", "done-button"); - donebutton.click(); - - let untaggeduri = PlacesUtils.tagging.getURIsForTag("edited-tag-three"); - is(untaggeduri, "", "Old tag is not associated with any bookmark"); - let tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); - is(tagsarray.length, 3, "Tag is successfully deleted"); - - AwesomeScreen.activePanel = null; - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_click_content.html b/mobile/android/chrome/tests/browser_click_content.html deleted file mode 100644 index 071ce21c24ba..000000000000 --- a/mobile/android/chrome/tests/browser_click_content.html +++ /dev/null @@ -1,7 +0,0 @@ - -Browser Click Page 01 - - - - - diff --git a/mobile/android/chrome/tests/browser_click_content.js b/mobile/android/chrome/tests/browser_click_content.js deleted file mode 100644 index f06428f90e2d..000000000000 --- a/mobile/android/chrome/tests/browser_click_content.js +++ /dev/null @@ -1,128 +0,0 @@ -let testURL_click = chromeRoot + "browser_click_content.html"; - -let currentTab; -let element; -let clickPosition = { x: null, y: null}; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // This test is async - waitForExplicitFinish(); - - // Add new tab - currentTab = Browser.addTab(testURL_click, true); - ok(currentTab, "Tab Opened"); - - // Wait for the tab to load, then do the test - messageManager.addMessageListener("pageshow", function() { - if (currentTab.browser.currentURI.spec == testURL_click) { - messageManager.removeMessageListener("pageshow", arguments.callee); - testClickAndPosition(); - }}); -} - -function clickFired(aEvent) { - let [x, y] = browserViewToClient(aEvent.clientX, aEvent.clientY); - clickPosition.x = x; - clickPosition.y = y; -} - -function testClickAndPosition() { - // Do sanity tests - let uri = currentTab.browser.currentURI.spec; - is(uri, testURL_click, "URL Matches newly created Tab"); - - // Check click - element = currentTab.browser.contentDocument.getElementById("iframe-1"); - element.addEventListener("click", function(aEvent) { - element.removeEventListener("click", arguments.callee, true); - clickFired(aEvent); - is(aEvent.type, "click", "Click fired"); - checkClick(); - }, true); - - EventUtils.synthesizeMouseForContent(element, 1, 1, {}, window); -} - -function checkClick() { - // Check position - element = currentTab.browser.contentDocument.documentElement; - element.addEventListener("click", function(aEvent) { - element.removeEventListener("click", arguments.callee, true); - clickFired(aEvent); - checkPosition(); - }, true); - - let rect = getBoundingContentRect(element); - EventUtils.synthesizeMouse(element, 1, rect.height + 10, {}, window); -} - -function checkPosition() { - let rect = getBoundingContentRect(element); - is(clickPosition.x, 1, "X position is correct"); - is(clickPosition.y, rect.height + 10, "Y position is correct"); - - checkThickBorder(); -} - -function checkThickBorder() { - let frame = currentTab.browser.contentDocument.getElementById("iframe-2"); - let element = frame.contentDocument.getElementsByTagName("input")[0]; - - let frameRect = getBoundingContentRect(frame); - let frameLeftBorder = window.getComputedStyle(frame, "").borderLeftWidth; - let frameTopBorder = window.getComputedStyle(frame, "").borderTopWidth; - - let elementRect = getBoundingContentRect(element); - ok((frameRect.left + parseInt(frameLeftBorder)) < elementRect.left, "X position of nested element ok"); - ok((frameRect.top + parseInt(frameTopBorder)) < elementRect.top, "Y position of nested element ok"); - - close(); -} - -function close() { - // Close the tab - Browser.closeTab(currentTab); - - // We must finialize the tests - finish(); -} - -// XXX copied from chrome/content/content.js -function getBoundingContentRect(aElement) { - if (!aElement) - return new Rect(0, 0, 0, 0); - - let document = aElement.ownerDocument; - while(document.defaultView.frameElement) - document = document.defaultView.frameElement.ownerDocument; - - let content = document.defaultView; - let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - let scrollX = {}, scrollY = {}; - cwu.getScrollXY(false, scrollX, scrollY); - let offset = new Point(scrollX.value, scrollY.value); - let r = aElement.getBoundingClientRect(); - - // step out of iframes and frames, offsetting scroll values - for (let frame = aElement.ownerDocument.defaultView; frame != content; frame = frame.parent) { - // adjust client coordinates' origin to be top left of iframe viewport - let rect = frame.frameElement.getBoundingClientRect(); - let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth; - let top = frame.getComputedStyle(frame.frameElement, "").borderTopWidth; - offset.add(rect.left + parseInt(left), rect.top + parseInt(top)); - } - - return new Rect(r.left + offset.x, r.top + offset.y, r.width, r.height); -} - -function browserViewToClient(x, y) { - let container = document.getElementById("browsers"); - let containerBCR = container.getBoundingClientRect(); - - let x0 = Math.round(-containerBCR.left); - let y0 = Math.round(-containerBCR.top); - - return [x - x0, y - y0]; -} diff --git a/mobile/android/chrome/tests/browser_contacts.js b/mobile/android/chrome/tests/browser_contacts.js deleted file mode 100644 index 47d61ac93cf7..000000000000 --- a/mobile/android/chrome/tests/browser_contacts.js +++ /dev/null @@ -1,88 +0,0 @@ - -// pull in the Contacts service -Components.utils.import("resource:///modules/contacts.jsm"); - -let fac = Cc["@mozilla.org/satchel/form-autocomplete;1"].getService(Ci.nsIFormAutoComplete); -let fh = Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2); - -function test() { - ok(Contacts, "Contacts class exists"); - for (var fname in tests) { - tests[fname](); - } -} - -let MockContactsProvider = { - getContacts: function() { - let contacts = [ - { - fullName: "-Billy One", - emails: [], - phoneNumbers: ["999-888-7777"] - }, - { - fullName: "-Billy Two", - emails: ["billy.two@fake.com", "btwo@work.com"], - phoneNumbers: ["111-222-3333", "123-123-1234"] - }, - { - fullName: "-Joe Schmo", - emails: ["joeschmo@foo.com"], - phoneNumbers: ["555-555-5555"] - } - ]; - - return contacts; - } -}; - -// In case there are real contacts that could mess up our test counts -let preEmailCount = fac.autoCompleteSearch("email", "", null, null).matchCount; -let prePhoneCount = fac.autoCompleteSearch("tel", "", null, null).matchCount; - -Contacts.addProvider(MockContactsProvider); - -let tests = { - testBasicMatch: function() { - // Search for any emails - let results = fac.autoCompleteSearch("email", "", null, null); - is(results.matchCount, 3 + preEmailCount, "Found 3 emails for un-filtered search"); - - // Do some filtered searches - results = fac.autoCompleteSearch("email", "-Billy", null, null); - is(results.matchCount, 2, "Found 2 emails '-Billy'"); - - results = fac.autoCompleteSearch("tel", "-Billy", null, null); - is(results.matchCount, 3, "Found 3 phone numbers '-Billy'"); - - results = fac.autoCompleteSearch("skip", "-Billy", null, null); - is(results.matchCount, 0, "Found nothing for a non-contact field"); - - results = fac.autoCompleteSearch("phone", "-Jo", null, null); - is(results.matchCount, 1, "Found 1 phone number '-Jo'"); - }, - - testMixingData: function() { - // Add a simple value to the non-contact system - fh.addEntry("email", "super.cool@place.com"); - - let results = fac.autoCompleteSearch("email", "", null, null); - is(results.matchCount, 4 + preEmailCount, "Found 4 emails for un-filtered search"); - - let firstEmail = results.getValueAt(0); - is(firstEmail, "super.cool@place.com", "The non-contact entry is first"); - - fh.removeAllEntries(); - }, - - testFakeInputField: function() { - let attributes = ["type", "id", "class"]; - for (let i = 0; i < attributes.length; i++) { - let field = document.createElementNS("http://www.w3.org/1999/xhtml", "html:input"); - field.setAttribute(attributes[i], "tel"); - - let results = fac.autoCompleteSearch("", "-Jo", field, null); - is(results.matchCount, 1 + prePhoneCount, "Found 1 phone number -Jo"); - } - } -}; diff --git a/mobile/android/chrome/tests/browser_contentpopup.html b/mobile/android/chrome/tests/browser_contentpopup.html deleted file mode 100644 index 882759457815..000000000000 --- a/mobile/android/chrome/tests/browser_contentpopup.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - -

- - - - - - - - - - - - - - - diff --git a/mobile/android/chrome/tests/browser_contentpopup.js b/mobile/android/chrome/tests/browser_contentpopup.js deleted file mode 100644 index 305a7bf0f78e..000000000000 --- a/mobile/android/chrome/tests/browser_contentpopup.js +++ /dev/null @@ -1,89 +0,0 @@ -let testURL = chromeRoot + "browser_contentpopup.html"; -messageManager.loadFrameScript(chromeRoot + "remote_contentpopup.js", true); - -let newTab = null; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -function test() { - // This test is async - waitForExplicitFinish(); - - // Need to wait until the page is loaded - messageManager.addMessageListener("pageshow", function(aMessage) { - if (newTab && newTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - BrowserUI.closeAutoComplete(true); - setTimeout(runNextTest, 0); - } - }); - - waitForFirstPaint(function() { - newTab = Browser.addTab(testURL, true); - }); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - // Add any cleanup code here - - // Close our tab when finished - Browser.closeTab(newTab); - } - finally { - // We must finalize the tests - finish(); - } - } -} - -//------------------------------------------------------------------------------ -// Case: Show/Hide the content popup helper -gTests.push({ - desc: "Show/Hide the content popup helper", - - run: function() { - let popup = document.getElementById("form-helper-suggestions-container"); - popup.addEventListener("contentpopupshown", function(aEvent) { - aEvent.target.removeEventListener(aEvent.type, arguments.callee, false); - ok(!popup.hidden, "Content popup should be visible"); - waitFor(gCurrentTest.hidePopup, function() { - return FormHelperUI._open; - }); - }, false); - - AsyncTests.waitFor("TestRemoteAutocomplete:Click", - { id: "input-datalist-1" }, function(json) {}); - }, - - hidePopup: function() { - let popup = document.getElementById("form-helper-suggestions-container"); - popup.addEventListener("contentpopuphidden", function(aEvent) { - popup.removeEventListener("contentpopuphidden", arguments.callee, false); - ok(popup.hidden, "Content popup should be hidden"); - waitFor(gCurrentTest.finish, function() { - return !FormHelperUI._open; - }); - }, false); - - // Close the form assistant - FormHelperUI.hide(); - }, - - finish: function() { - runNextTest(); - } -}); - diff --git a/mobile/android/chrome/tests/browser_dragger.js b/mobile/android/chrome/tests/browser_dragger.js deleted file mode 100644 index 0b873ddc4ee0..000000000000 --- a/mobile/android/chrome/tests/browser_dragger.js +++ /dev/null @@ -1,89 +0,0 @@ -"use strict"; - -const testURL_01 = chromeRoot + "browser_blank_01.html"; -const testURL_01_Remote = serverRoot + "browser_blank_01.html"; - -function test() { - waitForExplicitFinish(); - runNextTest(); -} - -gTests.push({ - desc: "Test that kinetic panning does not open sidebars.", - tab: null, - - run: function() { - gCurrentTest.tab = Browser.addTab(testURL_01, true); - onMessageOnce(gCurrentTest.tab.browser.messageManager, "Browser:FirstPaint", gCurrentTest.checkPan); - }, - - checkPan: function() { - let browser = gCurrentTest.tab.browser; - let docWidth = browser.contentDocumentWidth * browser.scale; - let winWidth = window.innerWidth; - info("Browser document width is " + docWidth); - info("Window width is " + winWidth); - ok(docWidth <= winWidth, - "Sanity check. Blank document cannot be panned left or right."); - - function dragAndCheck(dx) { - let dragger = Elements.browsers.customDragger; - try { - dragger.dragStart(0, 0, null, null); - dragger.dragMove(dx, 0, null, true); - - let [leftVis, rightVis] = Browser.computeSidebarVisibility(); - is(leftVis, 0, "Left sidebar is not visible"); - is(rightVis, 0, "Right sidebar is not visible"); - } finally { - // Be fail tolerant and hide sidebars in case tests failed. - Browser.hideSidebars(); - dragger.dragStop(); - } - } - - dragAndCheck(-20); - dragAndCheck(20); - - Browser._doCloseTab(gCurrentTest.tab); - runNextTest(); - } -}); - -gTests.push({ - desc: "Test that urlbar cannot be panned in when content is captured.", - tab: null, - - run: function() { - gCurrentTest.tab = Browser.addTab(testURL_01_Remote, true); - Browser.selectedTab = gCurrentTest.tab; - onMessageOnce(gCurrentTest.tab.browser.messageManager, "MozScrolledAreaChanged", gCurrentTest.mouseMove); - }, - - mouseMove: function(json) { - let inputHandler = gCurrentTest.tab.browser.parentNode; - function fireMouseEvent(y, type) { - EventUtils.synthesizeMouse(inputHandler, 0, y, { type: type }); - } - - Browser.hideTitlebar(); - let rect = Elements.browsers.getBoundingClientRect(); - is(rect.top, 0, "Titlebar begins hidden"); - - let dragger = Elements.browsers.customDragger; - try { - dragger.contentCanCapture = true; - dragger.dragStart(0, 0, null, null); - dragger.dragMove(0, 20, null, true); - dragger.dragStop(); - } finally { - dragger.contentCanCapture = false; - } - - rect = Elements.browsers.getBoundingClientRect(); - is(rect.top, 0, "Titlebar is still hidden"); - - Browser._doCloseTab(gCurrentTest.tab); - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_escape.js b/mobile/android/chrome/tests/browser_escape.js deleted file mode 100644 index a08272725c94..000000000000 --- a/mobile/android/chrome/tests/browser_escape.js +++ /dev/null @@ -1,128 +0,0 @@ -/* ***** 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 Mobile Browser. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Matt Brubeck - * - * 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 ***** */ - -"use strict"; -const url1 = baseURI + "browser_blank_01.html"; -const url2 = baseURI + "browser_blank_02.html"; -const url3 = baseURI + "browser_blank_03.html"; -let tab1, tab2; - -function test() { - waitForExplicitFinish(); - testGoBack(); - - registerCleanupFunction(closeTabs); -} - -function testGoBack() { - tab1 = Browser.addTab("about:blank", true); - tab2 = Browser.addTab("about:blank", true, tab1); - let browser = tab2.browser; - - // Load each of these URLs, then use escape to step backward through them. - let urls = [url1, url2, url3]; - let i = 0, step = 1; - let expectedURI; - - function loadNextPage() { - expectedURI = urls[i]; - if (step == 1) { - // go forward - Browser.loadURI(expectedURI); - } else { - // go back by pressing the escape key - Browser.selectedBrowser.focus(); - EventUtils.synthesizeKey("VK_ESCAPE", {type: "keypress"}, window); - } - } - - browser.messageManager.addMessageListener("pageshow", function listener(aMessage) { - let uri = browser.currentURI.spec; - if (uri == "about:blank") { - loadNextPage(); - return; - } - is(uri, expectedURI, "Page " + i + " loaded"); - - if (i == urls.length - 1) - step = -1; // start going back when we get to the end - i += step; - - if (i >= 0) { - loadNextPage(); - //setTimeout(loadNextPage, 1000); - } else { - // All done. Go to the next test. - browser.messageManager.removeMessageListener("pageshow", listener); - closeTabs(); - testReturnToOwner(); - } - }); -} - -function testReturnToOwner() { - tab1 = Browser.addTab("about:blank", true); - tab2 = Browser.addTab("about:blank", true, tab1); - is(Browser.selectedTab, tab2, "tab2 is selected"); - EventUtils.sendKey("ESCAPE"); - is(Browser.selectedTab, tab1, "tab1 is selected"); - closeTabs(); - testContextMenu(); -} - -function testContextMenu() { - ContextHelper.showPopup({ - json: { - types: ['link'] - }, - target: Browser.selectedBrowser - }); - ok(ContextHelper.popupState, "Context menu is shown"); - Browser.selectedBrowser.focus(); - EventUtils.synthesizeKey("VK_ESCAPE", {type: "keypress"}, window); - ok(!ContextHelper.popupState, "Context menu is dismissed"); - finish(); -} - -function closeTabs() { - try { - Browser.closeTab(tab1); - Browser.closeTab(tab2); - } finally { - tab1 = tab2 = null; - } -} diff --git a/mobile/android/chrome/tests/browser_find.js b/mobile/android/chrome/tests/browser_find.js deleted file mode 100644 index 89d0392c1b92..000000000000 --- a/mobile/android/chrome/tests/browser_find.js +++ /dev/null @@ -1,39 +0,0 @@ -// Tests for the Find In Page UI - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - addEventListener("PopupChanged", popupOpened, false); - CommandUpdater.doCommand("cmd_menu"); -} - -function popupOpened() { - removeEventListener("PopupChanged", popupOpened, false); - - let menu = document.getElementById("appmenu"); - ok(!menu.hidden, "App menu is shown"); - - let navigator = document.getElementById("content-navigator"); - ok(!navigator.isActive, "Toolbar is closed"); - - addEventListener("PopupChanged", findOpened, false); - let item = document.getElementsByClassName("appmenu-findinpage-button")[0]; - item.click(); -} - -function findOpened() { - removeEventListener("PopupChanged", findOpened, false); - - let menu = document.getElementById("appmenu"); - ok(menu.hidden, "App menu is closed"); - - let navigator = document.getElementById("content-navigator"); - ok(navigator.isActive, "Toolbar is open"); - - is(navigator._previousButton.disabled, true, "Previous button should be disabled"); - is(navigator._nextButton.disabled, true, "Previous button should be disabled"); - - EventUtils.synthesizeKey("VK_ESCAPE", {}, window); - ok(menu.hidden, "Site menu is closed"); - ok(!navigator.isActive, "Toolbar is closed"); -} diff --git a/mobile/android/chrome/tests/browser_focus.html b/mobile/android/chrome/tests/browser_focus.html deleted file mode 100644 index 95550379da60..000000000000 --- a/mobile/android/chrome/tests/browser_focus.html +++ /dev/null @@ -1,7 +0,0 @@ - - - Focus/Activate test - - - - diff --git a/mobile/android/chrome/tests/browser_focus.js b/mobile/android/chrome/tests/browser_focus.js deleted file mode 100644 index 5b53f4339c48..000000000000 --- a/mobile/android/chrome/tests/browser_focus.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; -let testURL = chromeRoot + "browser_focus.html"; -let newTab = null; - -function test() { - waitForExplicitFinish(); - - registerCleanupFunction(function() { - try { - messageManager.sendAsyncMessage("Test:E10SFocusTestFinished", {}); - Browser.closeTab(newTab); - } finally { - newTab = null; - } - }); - - messageManager.addMessageListener("pageshow", function listener(aMessage) { - if (newTab && newTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener("pageshow", listener); - setTimeout(onTabLoaded, 0); - } - }); - - newTab = Browser.addTab(testURL, true); -} - -function onTabLoaded() { - // ensure that the is not already focused - newTab.browser.blur(); - messageManager.loadFrameScript(chromeRoot + "remote_focus.js", false); - testFocus(); -} - -function testFocus() { - onMessageOnce(messageManager, "Test:E10SFocusReceived", function() { - ok("Focus in triggered activateRemoteFrame as expected"); - testBlur(); - }); - newTab.browser.focus(); -} - -function testBlur() { - onMessageOnce(messageManager, "Test:E10SBlurReceived", function() { - ok("Blur in triggerered deactivateRemoteFrame as expected"); - endTest(); - }); - newTab.browser.blur(); -} - -function endTest() { - finish(); -} diff --git a/mobile/android/chrome/tests/browser_forms.html b/mobile/android/chrome/tests/browser_forms.html deleted file mode 100644 index 5566bbe5bb52..000000000000 --- a/mobile/android/chrome/tests/browser_forms.html +++ /dev/null @@ -1,51 +0,0 @@ - - - Browser Form Assistant - - - - - - - - - - text - -
click here
- - -
- - - dumb type - - -
div
- - - - - - - - - - - - - - - - - - - - - - diff --git a/mobile/android/chrome/tests/browser_forms.js b/mobile/android/chrome/tests/browser_forms.js deleted file mode 100644 index 37589eb19b07..000000000000 --- a/mobile/android/chrome/tests/browser_forms.js +++ /dev/null @@ -1,242 +0,0 @@ -let testURL = chromeRoot + "browser_forms.html"; -messageManager.loadFrameScript(chromeRoot + "remote_forms.js", true); - -let newTab = null; - -function test() { - // This test is async - waitForExplicitFinish(); - - // Need to wait until the page is loaded - messageManager.addMessageListener("pageshow", function(aMessage) { - if (newTab && newTab.browser.currentURI.spec != "about:blank") { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - setTimeout(onTabLoaded, 0); - } - }); - - // Add new tab to hold the page - newTab = Browser.addTab(testURL, true); -} - -function onTabLoaded() { - BrowserUI.closeAutoComplete(true); - testMouseEvents(); -} - -function testMouseEvents() { - // Sending a synthesized event directly on content should not work - we - // don't want web content to be able to open the form helper without the - // user consent, so we have to pass through the canvas tile-container - AsyncTests.waitFor("Test:Click", {}, function(json) { - is(json.result, false, "Form Assistant should stay closed"); - }); - - AsyncTests.waitFor("Test:Focus", { value: "#root" }, function(json) { - is(json.result, false, "Form Assistant should stay closed"); - }); - - AsyncTests.waitFor("Test:FocusRedirect", { value: "*[tabindex='0']" }, function(json) { - is(json.result, false, "Form Assistant should stay closed"); - testOpenUIWithSyncFocus(); - }); -}; - -function waitForFormAssist(aCallback) { - messageManager.addMessageListener("FormAssist:Show", function(aMessage) { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - setTimeout(function() { - ok(FormHelperUI._open, "Form Assistant should be open"); - setTimeout(aCallback, 0); - }); - }); -}; - -function testOpenUIWithSyncFocus() { - AsyncTests.waitFor("Test:Open", { value: "*[tabindex='0']" }, function(json) {}); - waitForFormAssist(testOpenUI); -}; - -function testOpenUI() { - AsyncTests.waitFor("Test:Open", { value: "*[tabindex='0']" }, function(json) {}); - waitForFormAssist(testOpenUIWithFocusRedirect); -}; - -function testOpenUIWithFocusRedirect() { - AsyncTests.waitFor("Test:OpenWithFocusRedirect", { value: "*[tabindex='0']" }, function(json) {}); - waitForFormAssist(testShowUIForSelect); -}; - -function testShowUIForSelect() { - AsyncTests.waitFor("Test:CanShowUI", { value: "#select"}, function(json) { - ok(json.result, "canShowUI for select element'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "#select", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for disabled select element'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "#option"}, function(json) { - ok(json.result, "canShowUI for option element'"); - }); - - AsyncTests.waitFor("Test:CanShowUISelect", { value: "#option", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for option element with a disabled parent select element'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "#option", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for disabled option element'"); - testShowUIForElements(); - }); -} - -function testShowUIForElements() { - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='1']" }, function(json) { - ok(json.result, "canShowUI for input type='text'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='1']", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for disabled input type='text'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='2']" }, function(json) { - ok(json.result, "canShowUI for input type='password'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='2']", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for disabled input type='password'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='8']" }, function(json) { - ok(json.result, "canShowUI for contenteditable div"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='8']", disabled: true }, function(json) { - is(json.result, false, "!canShowUI for disabled contenteditable div"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='3']" }, function(json) { - is(json.result, false, "!canShowUI for input type='submit'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='4']" }, function(json) { - is(json.result, false, "!canShowUI for input type='file'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='5']" }, function(json) { - is(json.result, false, "!canShowUI for input button type='submit'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='6']" }, function(json) { - is(json.result, false, "!canShowUI for input div@role='button'"); - }); - - AsyncTests.waitFor("Test:CanShowUI", { value: "*[tabindex='6']" }, function(json) { - is(json.result, false, "!canShowUI for input type='image'"); - }); - - // Open the Form Helper - AsyncTests.waitFor("Test:Open", { value: "*[tabindex='1']" }, function(json) { - ok(json.result, "Form Assistant should be open"); - testTabIndexNavigation(); - }); -}; - -function testTabIndexNavigation() { - AsyncTests.waitFor("Test:Previous", { value: "*[tabindex='0']" }, function(json) { - is(json.result, false, "Focus should not have changed"); - }); - - AsyncTests.waitFor("Test:Next", { value: "*[tabindex='2']" }, function(json) { - is(json.result, true, "Focus should be on element with tab-index : 2"); - }); - - AsyncTests.waitFor("Test:Previous", { value: "*[tabindex='1']" }, function(json) { - is(json.result, true, "Focus should be on element with tab-index : 1"); - }); - - AsyncTests.waitFor("Test:Next"); - AsyncTests.waitFor("Test:Next"); - AsyncTests.waitFor("Test:Next"); - AsyncTests.waitFor("Test:Next"); - AsyncTests.waitFor("Test:Next"); - - AsyncTests.waitFor("Test:Next", { value: "*[tabindex='7']" }, function(json) { - is(json.result, true, "Focus should be on element with tab-index : 7"); - }); - - AsyncTests.waitFor("Test:Next", { value: "*[tabindex='8']" }, function(json) { - is(json.result, true, "Focus should be on element with tab-index : 8"); - }); - - AsyncTests.waitFor("Test:Next", { value: "*[tabindex='0']" }, function(json) { - is(json.result, true, "Focus should be on element with tab-index : 0"); - }); - - let ids = ["next", "select", "dumb", "reset", "checkbox", "radio0", "radio4", "last", "last"]; - for (let i = 0; i < ids.length; i++) { - let id = ids[i]; - AsyncTests.waitFor("Test:Next", { value: "#" + id }, function(json) { - is(json.result, true, "Focus should be on element with #id: " + id + ""); - }); - }; - - FormHelperUI.hide(); - let container = document.getElementById("content-navigator"); - is(container.hidden, true, "Form Assistant should be close"); - - AsyncTests.waitFor("Test:Open", { value: "*[tabindex='0']" }, function(json) { - ok(FormHelperUI._open, "Form Assistant should be open"); - testFocusChanges(); - }); -}; - -function testFocusChanges() { - AsyncTests.waitFor("Test:Focus", { value: "*[tabindex='1']" }, function(json) { - ok(json.result, "Form Assistant should be open"); - }); - - AsyncTests.waitFor("Test:Focus", { value: "#select" }, function(json) { - ok(json.result, "Form Assistant should stay open"); - }); - - AsyncTests.waitFor("Test:Focus", { value: "*[type='hidden']" }, function(json) { - ok(json.result, "Form Assistant should stay open"); - loadNestedIFrames(); - }); -} - -function loadNestedIFrames() { - AsyncTests.waitFor("Test:Iframe", { }, function(json) { - is(json.result, true, "Iframe should have loaded"); - navigateIntoNestedIFrames(); - }); -} - -function navigateIntoNestedIFrames() { - AsyncTests.waitFor("Test:IframeOpen", { }, function(json) { - is(json.result, true, "Form Assistant should have been opened"); - }); - - AsyncTests.waitFor("Test:IframePrevious", { value: 0 }, function(json) { - is(json.result, true, "Focus should not have move"); - }); - - AsyncTests.waitFor("Test:IframeNext", { value: 1 }, function(json) { - is(json.result, true, "Focus should have move"); - }); - - AsyncTests.waitFor("Test:IframeNext", { value: 1 }, function(json) { - is(json.result, true, "Focus should not have move"); - - // Close the form assistant - FormHelperUI.hide(); - - // Close our tab when finished - Browser.closeTab(newTab); - - // We must finalize the tests - finish(); - }); -}; - diff --git a/mobile/android/chrome/tests/browser_formsZoom.html b/mobile/android/chrome/tests/browser_formsZoom.html deleted file mode 100644 index 36f641d0d0dd..000000000000 --- a/mobile/android/chrome/tests/browser_formsZoom.html +++ /dev/null @@ -1,66 +0,0 @@ - - - Browser Zoom Test - - -















-
-
-
- -
- - diff --git a/mobile/android/chrome/tests/browser_formsZoom.js b/mobile/android/chrome/tests/browser_formsZoom.js deleted file mode 100644 index d78a26771690..000000000000 --- a/mobile/android/chrome/tests/browser_formsZoom.js +++ /dev/null @@ -1,214 +0,0 @@ -let testURL_01 = chromeRoot + "browser_formsZoom.html"; -let testURL_02 = baseURI + "browser_formsZoom.html"; -messageManager.loadFrameScript(baseURI + "remote_formsZoom.js", true); - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - // Start the tests - runNextTest(); -} - -function waitForPageShow(aPageURL, aCallback) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (aMessage.target.currentURI.spec == aPageURL) { - messageManager.removeMessageListener("pageshow", arguments.callee); - setTimeout(function() { aCallback(); }, 0); - } - }); -}; - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - setTimeout(gCurrentTest.run, 0); - } - else { - // Cleanup. All tests are completed at this point - try { - // Add any cleanup code here - } - finally { - // We must finialize the tests - finish(); - } - } -} - -function waitForZoom(aCallback) { - if (AnimatedZoom.isZooming()) { - let self = this; - window.addEventListener("AnimatedZoomEnd", function() { - window.removeEventListener("AnimatedZoomEnd", arguments.callee, false); - setTimeout(aCallback, 0); - }, false); - } - else setTimeout(aCallback, 0); -} - -function isElementVisible(aElement) { - let elementRect = Rect.fromRect(aElement.rect); - let caretRect = Rect.fromRect(aElement.caretRect); - - let browser = getBrowser(); - let zoomRect = Rect.fromRect(browser.getBoundingClientRect()); - let scroll = browser.getRootView().getPosition(); - let browserRect = new Rect(scroll.x, scroll.y, zoomRect.width, zoomRect.height); - - info("CanZoom: " +Browser.selectedTab.allowZoom); - - info("Browser rect: " + browserRect + " - scale: " + browser.scale); - info("Element rect: " + elementRect + " - caret rect: " + caretRect); - info("Scale element rect: " + elementRect.clone().scale(browser.scale, browser.scale) + " - scale caretRect: " + caretRect.clone().scale(browser.scale, browser.scale)); - info("Resulting zoom rect: " + Browser._getZoomRectForPoint(elementRect.center().x, elementRect.y, browser.scale)); - - let isCaretSyncEnabled = Services.prefs.getBoolPref("formhelper.autozoom.caret"); - if (isCaretSyncEnabled) { - ok(browserRect.contains(caretRect.clone().scale(browser.scale, browser.scale)), "Caret rect should be completely visible"); - } - else { - elementRect = elementRect.clone().scale(browser.scale, browser.scale); - let resultRect = browserRect.intersect(elementRect); - ok(!resultRect.isEmpty() && elementRect.x > browserRect.x && elementRect.y > browserRect.y, "Element should be partially visible"); - } -} - - -//------------------------------------------------------------------------------ -// Case: Loading a page and Zoom into textarea field with caret sync disabled -gTests.push({ - desc: "Loading a page and Zoom into textarea field with caret sync enabled", - elements: ["textarea-1", "textarea-2", "textarea-3", "textarea-4"], - _currentTab: null, - - run: function() { - Services.prefs.setBoolPref("formhelper.autozoom.caret", false); - gCurrentTest._currentTab = BrowserUI.newTab(testURL_01); - - waitForPageShow(testURL_01, function() { gCurrentTest.zoomNext(); }); - }, - - zoomNext: function() { - let id = this.elements.shift(); - if (!id) { - BrowserUI.closeTab(); - runNextTest(); - return; - } - - info("Zooming to " + id); - AsyncTests.waitFor("FormAssist:Show", { id: id }, function(json) { - waitForZoom(function() { - isElementVisible(json.current); - gCurrentTest.zoomNext(); - }); - }); - } -}); - -//------------------------------------------------------------------------------ -// Case: Loading a page and Zoom into textarea field with caret sync enabled -gTests.push({ - desc: "Loading a page and Zoom into textarea field with caret sync enabled", - elements: ["textarea-1", "textarea-2", "textarea-3", "textarea-4"], - _currentTab: null, - - run: function() { - Services.prefs.setBoolPref("formhelper.autozoom.caret", true); - gCurrentTest._currentTab = BrowserUI.newTab(testURL_01); - - waitForPageShow(testURL_01, function() { gCurrentTest.zoomNext(); }); - }, - - zoomNext: function() { - let id = this.elements.shift(); - if (!id) { - BrowserUI.closeTab(); - runNextTest(); - return; - } - - AsyncTests.waitFor("FormAssist:Show", { id: id }, function(json) { - waitForZoom(function() { - isElementVisible(json.current); - gCurrentTest.zoomNext(); - }); - }); - } -}); - -//------------------------------------------------------------------------------ -// Case: Loading a remote page and Zoom into textarea field with caret sync disabled -gTests.push({ - desc: "Loading a remote page and Zoom into textarea field with caret sync disabled", - elements: ["textarea-1", "textarea-2", "textarea-3", "textarea-4"], - _currentTab: null, - - run: function() { - Services.prefs.setBoolPref("formhelper.autozoom.caret", false); - gCurrentTest._currentTab = BrowserUI.newTab(testURL_02); - - waitForPageShow(testURL_02, function() { gCurrentTest.zoomNext(); }); - }, - - zoomNext: function() { - let id = this.elements.shift(); - if (!id) { - BrowserUI.closeTab(); - runNextTest(); - return; - } - - AsyncTests.waitFor("FormAssist:Show", { id: id }, function(json) { - waitForZoom(function() { - isElementVisible(json.current); - gCurrentTest.zoomNext(); - }); - }); - } -}); - -//------------------------------------------------------------------------------ -// Case: Loading a remote page and Zoom into textarea field with caret sync enabled -gTests.push({ - desc: "Loading a remote page and Zoom into textarea field with caret sync enabled", - elements: ["textarea-1", "textarea-2"], - _currentTab: null, - - run: function() { - Services.prefs.setBoolPref("formhelper.autozoom.caret", true); - gCurrentTest._currentTab = BrowserUI.newTab(testURL_02); - - waitForPageShow(testURL_02, function() { gCurrentTest.zoomNext(); }); - }, - - zoomNext: function() { - let id = this.elements.shift(); - if (!id) { - todo(false, "textarea-3 caret should be synced, but for some reason it is not"); - todo(false, "textarea-4 caret should be synced, but for some reason it is not"); - BrowserUI.closeTab(); - runNextTest(); - return; - } - - AsyncTests.waitFor("FormAssist:Show", { id: id }, function(json) { - waitForZoom(function() { - isElementVisible(json.current); - gCurrentTest.zoomNext(); - }); - }); - } -}); - diff --git a/mobile/android/chrome/tests/browser_history.js b/mobile/android/chrome/tests/browser_history.js deleted file mode 100644 index dd4ad8061cea..000000000000 --- a/mobile/android/chrome/tests/browser_history.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Make sure history is being recorded when we visit websites. - */ - -var testURL_01 = baseURI + "browser_blank_01.html"; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - } - finally { - // We must finialize the tests - finish(); - } - } -} - -/** - * One-time observer callback. - */ -function waitForObserve(name, callback) { - var observerService = Cc["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - var observer = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), - observe: function(subject, topic, data) { - observerService.removeObserver(observer, name); - observer = null; - callback(subject, topic, data); - } - }; - - observerService.addObserver(observer, name, false); -} - -//------------------------------------------------------------------------------ - -gTests.push({ - desc: "Test history being added with page visit", - _currentTab: null, - - run: function() { - this._currentTab = Browser.addTab(testURL_01, true); - waitForObserve("uri-visit-saved", function(subject, topic, data) { - let uri = subject.QueryInterface(Ci.nsIURI); - ok(uri.spec == testURL_01, "URI was saved to history"); - Browser.closeTab(gCurrentTest._currentTab); - runNextTest(); - }); - } -}); diff --git a/mobile/android/chrome/tests/browser_install.xml b/mobile/android/chrome/tests/browser_install.xml deleted file mode 100644 index 3e96873c2afd..000000000000 --- a/mobile/android/chrome/tests/browser_install.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - Install Tests - Extension - addon1@tests.mozilla.org - 1.0 - http://example.com/icon.png - http://example.com/ - - - Test Creator - http://example.com/creator.html - - - Public - Test add-on - Test add-on - - - Fennec - {a23983c0-fd0e-11dc-95ff-0800200c9a66} - 0 - * - - - ALL - http://example.com/browser/mobile/chrome/tests/addons/browser_install1_1.xpi - - - - Install Tests 2 - Extension - addon2@tests.mozilla.org - 1.0 - http://example.com/icon.png - http://example.com/ - - - Test Creator - http://example.com/creator.html - - - Public - Test add-on 2 - Test add-on 2 - - - Fennec - {a23983c0-fd0e-11dc-95ff-0800200c9a66} - 0 - * - - - ALL - http://example.com/browser/mobile/chrome/tests/addons/browser_install1_2.xpi - - diff --git a/mobile/android/chrome/tests/browser_localepicker.js b/mobile/android/chrome/tests/browser_localepicker.js deleted file mode 100644 index 1acef76c559e..000000000000 --- a/mobile/android/chrome/tests/browser_localepicker.js +++ /dev/null @@ -1,282 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -const RELATIVE_DIR = "browser/mobile/chrome/tests/"; -const TESTROOT = "http://example.com/" + RELATIVE_DIR; -const PREF_GET_LOCALES = "extensions.getLocales.get.url"; - -var gAvailable = []; - -var restartObserver = { - observe: function(aSubject, aTopic, aData) { - // cancel restart requests - aSubject.QueryInterface(Ci.nsISupportsPRBool); - aSubject.data = true; - }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]) -} - -function test() { - Services.obs.addObserver(restartObserver, "quit-application-requested", false); - waitForExplicitFinish(); - Services.prefs.setCharPref(PREF_GET_LOCALES, TESTROOT + "locales_list.sjs?numvalid=2"); - - let chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Components.interfaces.nsIXULChromeRegistry); - chromeReg.QueryInterface(Ci.nsIToolkitChromeRegistry); - let availableLocales = chromeReg.getLocalesForPackage("browser"); - while (availableLocales.hasMore()) - gAvailable.push( availableLocales.getNext() ); - - - // in order to test restart notifications being shown, we much open the settings panel once - let settingsButton = document.getElementById("tool-panel-open"); - settingsButton.click(); - waitForAndContinue(runNextTest, function() { - return !document.getElementById("panel-container").hidden; - }); -} - -function end_test() { - BrowserUI.hidePanel(); - Services.prefs.clearUserPref(PREF_GET_LOCALES); - Services.obs.removeObserver(restartObserver, "quit-application-requested"); -} - -registerCleanupFunction(end_test); - -function CheckListLoad(aList, aLength) { - return function() { - return aList.childNodes.length == aLength; - } -} - -function CheckDeck(aDeck, aPanel) { - return function() { - return aDeck.selectedPanel == aPanel; - } -} - -function LocaleTest(aName, aOptions) { - var install = null; - return { - desc: aName, - win: null, - run: function lt_run() { - this.loadedWindow = this.loadedWindow.bind(this); - this.windowClosed = this.windowClosed.bind(this); - this.win = Services.ww.openWindow(aOptions.opener, "chrome://browser/content/localePicker.xul", "_browser", "chrome,dialog=no,all", null); - this.win.addEventListener("load", this.loadedWindow, false); - }, - - loadedWindow: function lt_loadedWindow() { - this.win.removeEventListener("load", this.loadedWindow, false); - if (aOptions.opener) - setTimeout(this.delayedLoadPicker.bind(this), 0); - else - setTimeout(this.delayedLoadMain.bind(this), 0); - }, - - delayedLoadMain: function lt_delayedLoadMain() { - let deck = this.win.document.getElementById("language-deck"); - let mainPage = this.win.document.getElementById("main-page"); - is(deck.selectedPanel, mainPage, "Deck is showing the main page"); - - if (aOptions.loadLocalesList) { - // load the locales list - let changeButton = this.win.document.getElementById("change-language"); - changeButton.click(); - this.delayedLoadPicker(); - } else { - // click the "Continue in English" button - let continueButton = this.win.document.getElementById("continue-in-button"); - ok(/english/i.test(continueButton.textContent), "Continue button says English"); - this.win.addEventListener("unload", this.windowClosed, false); - continueButton.click(); - } - }, - - delayedLoadPicker: function lt_delayedLoadPicker() { - let deck = this.win.document.getElementById("language-deck"); - let pickerPage = this.win.document.getElementById("picker-page"); - is(deck.selectedPanel, pickerPage, "Deck is showing the picker page"); - - let list = this.win.document.getElementById("language-list"); - // wait till the list shows the number of locales bundled with this build + the 2 from the downloaded list - waitForAndContinue(this.listLoaded.bind(this), CheckListLoad(list, gAvailable.length + 2)); - }, - - listLoaded: function() { - let continueButton = this.win.document.getElementById("continue-button"); - let cancelButton = this.win.document.getElementById("cancel-button"); - ok(/continue/i.test(continueButton.textContent), "Continue button has correct text"); - ok(/cancel/i.test(cancelButton.textContent), "Cancel button has correct text"); - - let list = this.win.document.getElementById("language-list"); - is(list.childNodes.length, gAvailable.length + 2, "List has correct number of children"); - - let nextSelected = null; - let selectedItem = null; - for(var i = 0; i < list.childNodes.length; i++) { - let child = list.childNodes[i]; - if (/english/i.test(child.textContent)) { - ok(child.hasAttribute("selected"), "English is initially selected"); - selectedItem = child; - } else { - ok(!child.hasAttribute("selected"), "Language is not selected"); - if (aOptions.selectAddon && child.textContent == aOptions.selectAddon.name) - nextSelected = child; - } - } - this.testInstallingItem(nextSelected); - }, - - testInstallingItem: function lt_testInstallingItem(aSelect) { - let continueButton = this.win.document.getElementById("continue-button"); - let cancelButton = this.win.document.getElementById("cancel-button"); - - if (aSelect) { - aSelect.click(); - is(continueButton.textContent, aOptions.selectAddon.continueButton, "Continue button says " + aOptions.selectAddon.continueButton); - is(cancelButton.textContent, aOptions.selectAddon.cancelButton, "Cancel button says " + aOptions.selectAddon.cancelButton); - let title = this.win.document.getElementById("picker-title"); - is(title.textContent, aOptions.selectAddon.title, "Title says " + aOptions.selectAddon.title); - continueButton.click(); - - let deck = this.win.document.getElementById("language-deck"); - let installerPage = this.win.document.getElementById("installer-page"); - is(deck.selectedPanel, installerPage, "Deck is showing the installer page"); - - let installingPage = this.win.document.getElementById("installer-page-installing"); - is(installerPage.selectedPanel, installingPage, "Installer is showing installing page"); - let installMsg = this.win.document.getElementById("installing-message"); - is(installMsg.textContent, aOptions.selectAddon.installMessage, "Installer is showing correct message"); - - if (aOptions.selectAddon.willFail) { - let failedPage = this.win.document.getElementById("installer-page-error"); - waitForAndContinue(this.installFailed.bind(this), CheckDeck(installerPage, failedPage)); - } else { - let install = aSelect.locale; - this.win.addEventListener("unload", this.windowClosed, false); - } - } else { - this.cancelList(); - } - }, - - installFailed: function lt_installFailed() { - let continueButton = this.win.document.getElementById("install-continue"); - is(continueButton.textContent, aOptions.selectAddon.installFailed, "Install failed button has correct label"); - continueButton.click(); - - let deck = this.win.document.getElementById("language-deck"); - let pickerPage = this.win.document.getElementById("picker-page"); - is(deck.selectedPanel, pickerPage, "Deck is showing the picker page"); - this.cancelList(); - }, - - cancelList: function lt_cancelList() { - this.win.addEventListener("unload", this.windowClosed, false); - - let cancelButton = this.win.document.getElementById("cancel-button"); - cancelButton.click(); - if (!aOptions.opener) { - // canceling out of the list, should revert back to english ui - let deck = this.win.document.getElementById("language-deck"); - let mainPage = this.win.document.getElementById("main-page"); - is(deck.selectedPanel, mainPage, "Deck is showing the main page again"); - let continueButton = this.win.document.getElementById("continue-in-button"); - ok(/english/i.test(continueButton.textContent), "Cancelling returned the UI to English"); - continueButton.click(); - } - }, - - windowClosed: function lt_windowClosed(aEvent) { - this.checkMainUI(aOptions.selectAddon); - - Services.prefs.clearUserPref("intl.locale.matchOS"); - Services.prefs.clearUserPref("general.useragent.locale"); - window.PreferencesView.hideRestart(); - - if (install) - install.uninstall(); - - runNextTest(); - }, - - checkMainUI: function(aAddon) { - let systemPref = ""; - let userAgentPref = ""; - try { - systemPref = Services.prefs.getBoolPref("intl.locale.matchOS"); - userAgentPref = Services.prefs.getCharPref("general.useragent.locale") - } catch(ex) { } - - let notification = document.getElementById("prefs-messages").getNotificationWithValue("restart-app"); - let showRestart = aAddon ? !aAddon.willFail : false; - is(!!notification, showRestart, "Restart message is " + (showRestart ? "" : "not ") + "shown"); - - // check that locale pref has been updated - let localeName = aAddon ? aAddon.locale : "en-US"; - is(systemPref, false, "Match system locale is false"); - is(userAgentPref, localeName, "User agent locale is " + localeName); - let buttonLabel = aAddon ? aAddon.localeName : "English (US)"; - is(document.getElementById("prefs-uilanguage-button").getAttribute("label"), buttonLabel, "Locale button says " + buttonLabel); - } - } -} - -let invalidInstall = { - name: "Test Locale 0", - installMessage: "INSTALLINGTest Locale 0", - continueButton: "CONTINUE", - cancelButton: "CANCEL", - title: "CHOOSELANGUAGE", - installFailed: "CONTINUE", - locale: "en-US", - localeName: "English (US)", - willFail: true -}; -let validInstall = { - name: "Test Locale 1", - installMessage: "INSTALLINGTest Locale 1", - continueButton: "CONTINUE", - cancelButton: "CANCEL", - title: "CHOOSELANGUAGE", - locale: "test1", - localeName: "test1", - willFail: false -} - -gTests.push(new LocaleTest("Load locale picker with no opener and continue", - { opener: null, - loadLocalesList: false, - selectAddon: null - })); - -gTests.push(new LocaleTest("Load locale picker with no opener and try to install an invalid language", - { opener: null, - loadLocalesList: true, - selectAddon: invalidInstall - })); - -gTests.push(new LocaleTest("Load locale picker with no opener and try to install a valid language", - { opener: null, - loadLocalesList: true, - selectAddon: validInstall - })); - -gTests.push(new LocaleTest("Load locale picker with opener and try to install an invalid language", - { opener: this.window, - loadLocalesList: true, - selectAddon: invalidInstall - })); - -gTests.push(new LocaleTest("Load locale picker with opener and try to install a valid language", - { opener: this.window, - loadLocalesList: true, - selectAddon: validInstall - })); diff --git a/mobile/android/chrome/tests/browser_localepicker_escape.js b/mobile/android/chrome/tests/browser_localepicker_escape.js deleted file mode 100644 index 4968d48c0504..000000000000 --- a/mobile/android/chrome/tests/browser_localepicker_escape.js +++ /dev/null @@ -1,44 +0,0 @@ -Components.utils.import("resource://gre/modules/Services.jsm"); - -var gWin; - -function test() { - waitForExplicitFinish(); - gWin = Services.ww.openWindow(window, "chrome://browser/content/localePicker.xul", "_browser", "chrome,dialog=no,all", null); - gWin.addEventListener("load", onload, false); -} - -function onload(aEvent) { - gWin.removeEventListener("load", onload, false); - ok(true, "Locale picker is opened."); - setTimeout(afterLoad, 0); -} - -function afterLoad() { - let ui = gWin.LocaleUI; - is(ui.selectedPanel, ui.pickerpage, "Picker page is selected."); - - ui.selectedPanel = ui.mainPage; - is(ui.selectedPanel, ui.mainPage, "Select the main page."); - sendEscape(); - is(ui.selectedPanel, ui.mainPage, "Main page is still selected (escape key does nothing)."); - - ui.selectedPanel = ui.installerPage; - is(ui.selectedPanel, ui.installerPage, "Select the installer page."); - sendEscape(); - is(ui.selectedPanel, ui.pickerpage, "Escape key goes back to the picker page."); - - gWin.addEventListener("unload", windowClosed, false); - sendEscape(); -} - -function windowClosed() { - gWin.removeEventListener("unload", windowClosed, false); - ok(true, "Locale picker is closed."); - finish(); -} - -function sendEscape() { - info("Sending escape key."); - EventUtils.synthesizeKey("VK_ESCAPE", { type: "keypress" }, gWin); -} diff --git a/mobile/android/chrome/tests/browser_localerepository.js b/mobile/android/chrome/tests/browser_localerepository.js deleted file mode 100644 index 63de102580bf..000000000000 --- a/mobile/android/chrome/tests/browser_localerepository.js +++ /dev/null @@ -1,39 +0,0 @@ -var localeList = serverRoot + "locales_list.sjs"; -var PREF_LOCALE_LIST = "extensions.getLocales.get.url"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/LocaleRepository.jsm"); - -function test() { - waitForExplicitFinish(); - runNextTest(); -} - -function end_test() { - Services.prefs.clearUserPref(PREF_LOCALE_LIST); -} - -registerCleanupFunction(end_test); - -gTests.push({ - desc: "Test getting a list of compatable locales", - run: function() { - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList); - LocaleRepository.getLocales(this.listLoaded); - }, - - listLoaded: function(aLocales) { - is(aLocales.length, 1, "Correct number of locales were found"); - isnot(aLocales[0].addon, null, "Locale has an addon"); - is(aLocales[0].xpiURL, "http://www.example.com/browser/mobile/chrome/tests/addons/browser_locale1.xpi", "Locale has correct xpi url"); - is(aLocales[0].xpiHash, null, "Locale has correct hash"); - - is(aLocales[0].addon.id, "langpack-test1@firefox-mobile.mozilla.org", "Locale has correct id"); - is(aLocales[0].addon.name, "Test Locale 1", "Locale has correct name"); - is(aLocales[0].addon.type, "language", "Locale has correct type"); - - is(aLocales[0].addon.targetLocale, "test1", "Locale has correct target locale"); - is(aLocales[0].addon.version, "1.0", "Locale has correct version"); - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_localerepository_buildid.js b/mobile/android/chrome/tests/browser_localerepository_buildid.js deleted file mode 100644 index 9a3689c565ae..000000000000 --- a/mobile/android/chrome/tests/browser_localerepository_buildid.js +++ /dev/null @@ -1,41 +0,0 @@ -var localeList = serverRoot + "locales_list.sjs"; -var PREF_LOCALE_LIST = "extensions.getLocales.get.url"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/LocaleRepository.jsm"); - -function test() { - waitForExplicitFinish(); - runNextTest(); -} - -function end_test() { - Services.prefs.clearUserPref(PREF_LOCALE_LIST); -} - -registerCleanupFunction(end_test); - -gTests.push({ - desc: "Test dynamically changing extensions.getLocales.get.url", - run: function() { - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?buildid=%BUILDID_EXPANDED%"); - LocaleRepository.getLocales(this.listLoaded.bind(this), {buildID: "00001122334455"}); - }, - - listLoaded: function(aLocales) { - is(aLocales.length, 1, "Correct number of locales were found"); - is(aLocales[0].addon.name, "0000-11-22-33-44-55", "Buildid was correctly replaced"); - - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?buildid=%BUILDID_EXPANDED%"); - LocaleRepository.getLocales(this.secondListLoaded.bind(this)); - }, - - secondListLoaded: function(aLocales) { - is(aLocales.length, 1, "Correct number of locales were found"); - - let buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime).appBuildID; - is(aLocales[0].addon.name.replace(/-/g, ""), buildID, "Buildid was correctly replaced"); - - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_localerepository_pref.js b/mobile/android/chrome/tests/browser_localerepository_pref.js deleted file mode 100644 index bc94c1280fc9..000000000000 --- a/mobile/android/chrome/tests/browser_localerepository_pref.js +++ /dev/null @@ -1,35 +0,0 @@ -var localeList = serverRoot + "locales_list.sjs"; -var PREF_LOCALE_LIST = "extensions.getLocales.get.url"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/LocaleRepository.jsm"); - -function test() { - waitForExplicitFinish(); - runNextTest(); -} - -function end_test() { - Services.prefs.clearUserPref(PREF_LOCALE_LIST); -} - -registerCleanupFunction(end_test); - -gTests.push({ - desc: "Test dynamically changing extensions.getLocales.get.url", - run: function() { - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList); - LocaleRepository.getLocales(this.listLoaded.bind(this)); - }, - - listLoaded: function(aLocales) { - is(aLocales.length, 1, "Correct number of locales were found"); - Services.prefs.setCharPref(PREF_LOCALE_LIST, localeList + "?numvalid=2"); - LocaleRepository.getLocales(this.secondListLoaded.bind(this)); - }, - - secondListLoaded: function(aLocales) { - is(aLocales.length, 2, "Correct number of locales were found"); - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_mainui.js b/mobile/android/chrome/tests/browser_mainui.js deleted file mode 100644 index 386858ade07d..000000000000 --- a/mobile/android/chrome/tests/browser_mainui.js +++ /dev/null @@ -1,27 +0,0 @@ -// Very basic tests for the main window UI - -const Cc = Components.classes; -const Ci = Components.interfaces; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - is(window.location.href, "chrome://browser/content/browser.xul", "Main window should be browser.xul"); - - window.focus(); - - let browser = Browser.selectedBrowser; - isnot(browser, null, "Should have a browser"); - - is(browser.currentURI.spec, Browser.selectedTab.browser.currentURI.spec, "selectedBrowser == selectedTab.browser"); - - testContentContainerSize(); -} - -function testContentContainerSize() { - let container = document.getElementById("content-viewport"); - - let rect = container.getBoundingClientRect(); - is(rect.width, window.innerWidth, "Content container is same width as window"); - is(rect.height, window.innerHeight, "Content container is same height as window"); -} diff --git a/mobile/android/chrome/tests/browser_navigation.js b/mobile/android/chrome/tests/browser_navigation.js deleted file mode 100644 index aa69a0ff7615..000000000000 --- a/mobile/android/chrome/tests/browser_navigation.js +++ /dev/null @@ -1,403 +0,0 @@ -var testURL_01 = chromeRoot + "browser_blank_01.html"; -var testURL_02 = chromeRoot + "browser_blank_02.html"; - -var titleURL = baseURI + "browser_title.sjs?"; -var pngURL = "data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw=="; - -// A queue to order the tests and a handle for each test -var gTests = []; -var gCurrentTest = null; - -var back = document.getElementById("tool-back"); -var forward = document.getElementById("tool-forward"); - -function pageLoaded(aURL) { - return function() { - let tab = gCurrentTest._currentTab; - return !tab.isLoading() && tab.browser.currentURI.spec == aURL; - } -} - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - // Start the tests - runNextTest(); -} - -function waitForPageShow(aPageURL, aCallback) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (aMessage.target.currentURI.spec == aPageURL) { - messageManager.removeMessageListener("pageshow", arguments.callee); - setTimeout(function() { aCallback(); }, 0); - } - }); -}; - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - try { - // Add any cleanup code here - } - finally { - // We must finialize the tests - finish(); - } - } -} - -//------------------------------------------------------------------------------ -// Case: Loading a page into the URLBar with VK_RETURN -gTests.push({ - desc: "Loading a page into the URLBar with VK_RETURN", - _currentTab: null, - - run: function() { - gCurrentTest._currentTab = BrowserUI.newTab(testURL_01); - - // Wait for the tab to load, then do the test - waitFor(gCurrentTest.onPageReady, pageLoaded(testURL_01)); - }, - - onPageReady: function() { - // Test the mode - let urlIcons = document.getElementById("urlbar-icons"); - is(urlIcons.getAttribute("mode"), "view", "URL Mode is set to 'view'"); - - // Test back button state - is(back.disabled, !gCurrentTest._currentTab.browser.canGoBack, "Back button check"); - - // Test forward button state - is(forward.disabled, !gCurrentTest._currentTab.browser.canGoForward, "Forward button check"); - - // Focus the url edit - let urlbarTitle = document.getElementById("urlbar-title"); - - // Wait for the awesomebar to load, then do the test - window.addEventListener("NavigationPanelShown", function() { - window.removeEventListener("NavigationPanelShown", arguments.callee, false); - setTimeout(gCurrentTest.onFocusReady, 0); - }, false); - EventUtils.synthesizeMouse(urlbarTitle, urlbarTitle.width / 2, urlbarTitle.height / 2, {}); - }, - - onFocusReady: function() { - // Test mode - let urlIcons = document.getElementById("urlbar-icons"); - is(urlIcons.getAttribute("mode"), "edit", "URL Mode is set to 'edit'"); - - // Test back button state - is(back.disabled, !gCurrentTest._currentTab.browser.canGoBack, "Back button check"); - - // Test forward button state - is(forward.disabled, !gCurrentTest._currentTab.browser.canGoForward, "Forward button check"); - - // Check button states (url edit is focused) - let search = document.getElementById("tool-search"); - let searchStyle = window.getComputedStyle(search, null); - is(searchStyle.visibility, "visible", "SEARCH is visible"); - - let stop = document.getElementById("tool-stop"); - let stopStyle = window.getComputedStyle(stop, null); - is(stopStyle.visibility, "collapse", "STOP is hidden"); - - let reload = document.getElementById("tool-reload"); - let reloadStyle = window.getComputedStyle(reload, null); - is(reloadStyle.visibility, "collapse", "RELOAD is hidden"); - - // Send the string and press return - EventUtils.synthesizeString(testURL_02, window); - - // It looks like there is a race condition somewhere that result having - // testURL_01 concatenate with testURL_02 as a urlbar value, so to - // workaround that we're waiting for the readonly state to be fully updated - function URLIsReadWrite() { - return BrowserUI._edit.readOnly == false; - } - - waitFor(function() { - // Wait for the tab to load, then do the test - waitFor(gCurrentTest.onPageFinish, pageLoaded(testURL_02)); - - setTimeout(function() { - is(BrowserUI._edit.value, testURL_02, "URL value should be equal to the string sent via synthesizeString"); - EventUtils.synthesizeKey("VK_RETURN", {}, window); - }, 0); - }, URLIsReadWrite); - }, - - onPageFinish: function() { - let urlIcons = document.getElementById("urlbar-icons"); - is(urlIcons.getAttribute("mode"), "view", "URL Mode is set to 'view'"); - - // Check button states (url edit is not focused) - let search = document.getElementById("tool-search"); - let searchStyle = window.getComputedStyle(search, null); - is(searchStyle.visibility, "collapse", "SEARCH is hidden"); - - let stop = document.getElementById("tool-stop"); - let stopStyle = window.getComputedStyle(stop, null); - is(stopStyle.visibility, "collapse", "STOP is hidden"); - - let reload = document.getElementById("tool-reload"); - let reloadStyle = window.getComputedStyle(reload, null); - is(reloadStyle.visibility, "visible", "RELOAD is visible"); - - let uri = gCurrentTest._currentTab.browser.currentURI.spec; - is(uri, testURL_02, "URL Matches newly created Tab"); - - // Go back in session - gCurrentTest._currentTab.browser.goBack(); - - // Wait for the tab to load, then do the test - waitFor(gCurrentTest.onPageBack, pageLoaded(testURL_01)); - }, - - onPageBack: function() { - // Test back button state - is(back.disabled, !gCurrentTest._currentTab.browser.canGoBack, "Back button check"); - - // Test forward button state - is(forward.disabled, !gCurrentTest._currentTab.browser.canGoForward, "Forward button check"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - runNextTest(); - } -}); - -// Bug 611327 ----------------------------------------------------------------- -// Check for urlbar label value -gTests.push({ - desc: "Check for urlbar label value on different cases", - _currentTab: null, - - run: function() { - gCurrentTest._currentTab = BrowserUI.newTab(titleURL + "no_title"); - waitForPageShow(titleURL + "no_title", gCurrentTest.onPageLoadWithoutTitle); - }, - - onPageLoadWithoutTitle: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, titleURL + "no_title", "The title should be equal to the URL"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - - gCurrentTest._currentTab = BrowserUI.newTab(titleURL + "english_title"); - waitForPageShow(titleURL + "english_title", gCurrentTest.onPageLoadWithTitle); - }, - - onPageLoadWithTitle: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, "English Title Page", "The title should be equal to the page title"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - - gCurrentTest._currentTab = BrowserUI.newTab(titleURL + "dynamic_title"); - messageManager.addMessageListener("pageshow", function(aMessage) { - messageManager.removeMessageListener("pageshow", arguments.callee); - gCurrentTest.onBeforePageTitleChanged(); - }); - - messageManager.addMessageListener("DOMTitleChanged", function(aMessage) { - messageManager.removeMessageListener("DOMTitleChanged", arguments.callee); - urlbarTitle.addEventListener("DOMAttrModified", function(aEvent) { - if (aEvent.attrName == "value") { - urlbarTitle.removeEventListener("DOMAttrModified", arguments.callee, false); - setTimeout(gCurrentTest.onPageTitleChanged, 0); - } - }, false); - }); - }, - - onBeforePageTitleChanged: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - isnot(urlbarTitle.value, "This is not a french title", "The title should not be equal to the new page title yet"); - }, - - onPageTitleChanged: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, "This is not a french title", "The title should be equal to the new page title"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - - gCurrentTest._currentTab = BrowserUI.newTab(titleURL + "redirect"); - waitForPageShow(titleURL + "no_title", gCurrentTest.onPageRedirect); - }, - - onPageRedirect: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, gCurrentTest._currentTab.browser.currentURI.spec, "The title should be equal to the redirected page url"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - - gCurrentTest._currentTab = BrowserUI.newTab(titleURL + "location"); - waitForPageShow(titleURL + "no_title", gCurrentTest.onPageLocation); - }, - - onPageLocation: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, gCurrentTest._currentTab.browser.currentURI.spec, "The title should be equal to the relocate page url"); - - BrowserUI.closeTab(gCurrentTest._currentTab); - - // Wait for the awesomebar to load, then do the test - window.addEventListener("NavigationPanelShown", function() { - window.removeEventListener("NavigationPanelShown", arguments.callee, false); - - setTimeout(function() { - EventUtils.synthesizeString(testURL_02, window); - EventUtils.synthesizeKey("VK_RETURN", {}, window); - - waitForPageShow(testURL_02, gCurrentTest.onUserTypedValue); - }, 0); - - }, false); - - gCurrentTest._currentTab = BrowserUI.newTab("about:blank"); - }, - - onUserTypedValue: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, "Browser Blank Page 02", "The title should be equal to the typed page url title"); - - // about:blank has been closed, so we need to close the last selected one - BrowserUI.closeTab(Browser.selectedTab); - - // Wait for the awesomebar to load, then do the test - window.addEventListener("NavigationPanelShown", function() { - window.removeEventListener("NavigationPanelShown", arguments.callee, false); - - EventUtils.synthesizeString("no_title", window); - - // Wait until the no_title result row is here - let popup = document.getElementById("popup_autocomplete"); - let result = null; - function hasResults() { - result = popup._items.childNodes[0]; - if (result) - return result.getAttribute("value") == (titleURL + "no_title"); - - return false; - }; - waitFor(function() { EventUtils.synthesizeMouse(result, result.width / 2, result.height / 2, {}); }, hasResults); - - urlbarTitle.addEventListener("DOMAttrModified", function(aEvent) { - if (aEvent.attrName == "value") { - urlbarTitle.removeEventListener("DOMAttrModified", arguments.callee, false); - is(urlbarTitle.value, titleURL + "no_title", "The title should be equal to the url of the clicked row"); - } - }, false); - - waitForPageShow(titleURL + "no_title", gCurrentTest.onUserSelectValue); - }, false); - - gCurrentTest._currentTab = BrowserUI.newTab("about:blank"); - }, - - onUserSelectValue: function() { - let urlbarTitle = document.getElementById("urlbar-title"); - is(urlbarTitle.value, Browser.selectedTab.browser.currentURI.spec, "The title should be equal to the clicked page url"); - - // about:blank has been closed, so we need to close the last selected one - BrowserUI.closeTab(Browser.selectedTab); - - //is(urlbarTitle.value, "Browser Blank Page 02", "The title of the second page must be displayed"); - runNextTest(); - } -}); - -// Case: Check for appearance of the favicon -gTests.push({ - desc: "Check for appearance of the favicon", - _currentTab: null, - - run: function() { - gCurrentTest._currentTab = BrowserUI.newTab(testURL_01); - waitForPageShow(testURL_01, gCurrentTest.onPageReady); - }, - - onPageReady: function() { - let favicon = document.getElementById("urlbar-favicon"); - is(favicon.src, "", "The default favicon must be loaded"); - BrowserUI.closeTab(gCurrentTest._currentTab); - - gCurrentTest._currentTab = BrowserUI.newTab(testURL_02); - waitForPageShow(testURL_02, gCurrentTest.onPageFinish); - }, - - onPageFinish: function(){ - let favicon = document.getElementById("urlbar-favicon"); - is(favicon.src, pngURL, "The page favicon must be loaded"); - BrowserUI.closeTab(gCurrentTest._currentTab); - runNextTest(); - } -}); - -// Bug 600707 - Back and forward buttons are updated when navigating within a page -// -// These tests use setTimeout instead of waitFor or addEventListener, because -// in-page navigation does not fire any loading events or progress -// notifications, and happens more or less instantly. -gTests.push({ - desc: "Navigating within a page via URI fragments", - _currentTab: null, - - run: function() { - gCurrentTest._currentTab = BrowserUI.newTab(testURL_01); - waitFor(gCurrentTest.onPageReady, pageLoaded(testURL_01)); - }, - - onPageReady: function() { - ok(back.disabled, "Can't go back"); - ok(forward.disabled, "Can't go forward"); - - messageManager.addMessageListener("Content:LocationChange", gCurrentTest.onFragmentLoaded); - Browser.loadURI(testURL_01 + "#fragment"); - }, - - onFragmentLoaded: function() { - messageManager.removeMessageListener("Content:LocationChange", arguments.callee); - - ok(!back.disabled, "Can go back"); - ok(forward.disabled, "Can't go forward"); - - messageManager.addMessageListener("Content:LocationChange", gCurrentTest.onBack); - CommandUpdater.doCommand("cmd_back"); - }, - - onBack: function() { - messageManager.removeMessageListener("Content:LocationChange", arguments.callee); - - ok(back.disabled, "Can't go back"); - ok(!forward.disabled, "Can go forward"); - - messageManager.addMessageListener("Content:LocationChange", gCurrentTest.onForward); - CommandUpdater.doCommand("cmd_forward"); - }, - - onForward: function() { - messageManager.removeMessageListener("Content:LocationChange", arguments.callee); - - ok(!back.disabled, "Can go back"); - ok(forward.disabled, "Can't go forward"); - - gCurrentTest.finish(); - }, - - finish: function() { - BrowserUI.closeTab(gCurrentTest._currentTab); - runNextTest(); - } -}); diff --git a/mobile/android/chrome/tests/browser_preferences_fulltoggle.js b/mobile/android/chrome/tests/browser_preferences_fulltoggle.js deleted file mode 100644 index 9ce68fbe22f9..000000000000 --- a/mobile/android/chrome/tests/browser_preferences_fulltoggle.js +++ /dev/null @@ -1,67 +0,0 @@ -// browser-chrome test for fennec preferences to toggle values while clicking on the preference name - -var gTests = []; -var gCurrentTest = null; - -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - finish(); - } -} - -// ----------------------------------------------------------------------------------------- -// Verify preferences and text -gTests.push({ - desc: "Verify full toggle on Preferences", - - run: function(){ - // 1.Click preferences to view prefs - document.getElementById("tool-panel-open").click(); - is(document.getElementById("panel-container").hidden, false, "Preferences should be visible"); - - var contentRegion = document.getElementById("prefs-content"); - - // Check for *Show images* - var imageRegion = document.getAnonymousElementByAttribute(contentRegion, "pref", "permissions.default.image"); - var imageValue = imageRegion.value; - var imageTitle = document.getAnonymousElementByAttribute(imageRegion, "class", "preferences-title"); - var imageButton = document.getAnonymousElementByAttribute(imageRegion, "anonid", "input"); - - var ibEvent = document.createEvent("MouseEvents"); - ibEvent.initEvent("TapSingle", true, false); - imageButton.dispatchEvent(ibEvent); - is(imageRegion.value, !imageValue, "Tapping on input control should change the value"); - - var itEvent = document.createEvent("MouseEvents"); - itEvent.initEvent("TapSingle", true, false); - imageTitle.dispatchEvent(itEvent); - is(imageRegion.value, imageValue, "Tapping on the title should change the value"); - - var irEvent = document.createEvent("MouseEvents"); - irEvent.initEvent("TapSingle", true, false); - imageRegion.dispatchEvent(irEvent); - is(imageRegion.value, !imageValue, "Tapping on the setting should change the value"); - - BrowserUI.hidePanel(); - is(document.getElementById("panel-container").hidden, true, "Preferences panel should be closed"); - runNextTest(); - } -}); - diff --git a/mobile/android/chrome/tests/browser_preferences_text.js b/mobile/android/chrome/tests/browser_preferences_text.js deleted file mode 100644 index de21f56fd5e0..000000000000 --- a/mobile/android/chrome/tests/browser_preferences_text.js +++ /dev/null @@ -1,131 +0,0 @@ -// Bug 571866 - --browser-chrome test for fennec preferences and text values - -var gTests = []; -var gCurrentTest = null; -var expected = { - "aboutButton": {"tagName": "button", "element_id": "prefs-about-button"}, - "homepage": {"element_id": "prefs-homepage", - "home_page": "prefs-homepage-default", - "blank_page": "prefs-homepage-none", - "current_page": "prefs-homepage-currentpage"}, - "doneButton": {"tagName": "button"}, - "contentRegion": {"element_id": "prefs-content"}, - "imageRegion": {"pref": "permissions.default.image", "anonid": "input", "localName": "checkbox"}, - "jsRegion": {"pref": "javascript.enabled", "anonid": "input", "localName": "checkbox"}, - "privacyRegion": {"element_id": "prefs-privacy" }, - "cookiesRegion": {"pref": "network.cookie.cookieBehavior", "anonid": "input", "localName": "checkbox"}, - "passwordsRegion": {"pref": "signon.rememberSignons", "anonid": "input", "localName": "checkbox"}, - "clearDataButton": {"element_id": "prefs-clear-data", "tagName": "button"} -}; - -function getPreferencesElements() { - let prefElements = {}; - prefElements.panelOpen = document.getElementById("tool-panel-open"); - prefElements.panelContainer = document.getElementById("panel-container"); - prefElements.homeButton = document.getElementById("prefs-homepage-options"); - prefElements.doneButton = document.getElementById("select-buttons-done"); - prefElements.homePageControl = document.getElementById("prefs-homepage"); - prefElements.selectContainer = document.getElementById("menulist-container"); - return prefElements; -} - -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - runNextTest(); -} -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Cleanup. All tests are completed at this point - finish(); - } -} - -// ----------------------------------------------------------------------------------------- -// Verify preferences and text -gTests.push({ - desc: "Verify Preferences and Text", - - run: function(){ - var prefs = getPreferencesElements(); - // 1.Click preferences to view prefs - prefs.panelOpen.click(); - - // 2. For each prefs *verify text *the button/option type *verify height of each field to be the same - is(prefs.panelContainer.hidden, false, "Preferences should be visible"); - - var prefsList = document.getElementById("prefs-messages"); - - // Check for *About page* - let about = expected.aboutButton; - var aboutRegion = document.getAnonymousElementByAttribute(prefsList, "title", "About Fennec"); - var aboutButton = document.getElementById(about.element_id); - is(aboutButton.tagName, about.tagName, "The About Fennec input must be a button"); - - // Check for *Startpage* - let homepage = expected.homepage; - var homepageRegion = document.getElementById(homepage.element_id); - prefs.homeButton.click(); - - is(prefs.selectContainer.hidden, false, "Homepage select dialog must be visible"); - - EventUtils.synthesizeKey("VK_ESCAPE", {}, window); - is(prefs.selectContainer.hidden, true, "Homepage select dialog must be closed"); - - let content = expected.contentRegion; - var contentRegion = document.getElementById(content.element_id); - - // Check for *Show images* - var images = expected.imageRegion; - var imageRegion = document.getAnonymousElementByAttribute(contentRegion, "pref", images.pref); - var imageButton = document.getAnonymousElementByAttribute(imageRegion, "anonid", images.anonid); - is(imageButton.localName, images.localName, "Show images checkbox check"); - // Checkbox or radiobutton? - - // Check for *Enable javascript* - let js = expected.jsRegion; - var jsRegion = document.getAnonymousElementByAttribute(contentRegion, "pref", js.pref); - var jsButton = document.getAnonymousElementByAttribute(jsRegion, "anonid", js.anonid); - is(jsButton.localName, js.localName, "Enable JavaScript checkbox check"); - // Checkbox or radiobutton? - - let privacyRegion = expected.privacyRegion; - var prefsPrivacy = document.getElementById(privacyRegion.element_id); - - // Check for *Allow cookies* - let cookies = expected.cookiesRegion; - var cookiesRegion = document.getAnonymousElementByAttribute(prefsPrivacy, "pref", cookies.pref); - var cookiesButton = document.getAnonymousElementByAttribute(cookiesRegion, "anonid", cookies.anonid); - is(cookiesButton.localName, cookies.localName, "Allow cookies checkbox check"); - // Checkbox or radiobutton? - - // Check for *Remember password* - let passwords = expected.passwordsRegion; - var passwordsRegion = document.getAnonymousElementByAttribute(prefsPrivacy, "pref", passwords.pref); - var passwordsButton = document.getAnonymousElementByAttribute(passwordsRegion, "anonid", passwords.anonid); - is(passwordsButton.localName, passwords.localName, "Allow cookies checkbox check"); - // Checkbox or radiobutton? - - // Check for *Clear Private Data* - let clearData = expected.clearDataButton; - var clearDataRegion = prefsPrivacy.lastChild; - var clearDataButton = document.getElementById(clearData.element_id); - is(clearDataButton.tagName, clearData.tagName, "Check for Clear Private Data button type"); - - BrowserUI.hidePanel(); - is(document.getElementById("panel-container").hidden, true, "Preferences panel should be closed"); - runNextTest(); - } -}); - diff --git a/mobile/android/chrome/tests/browser_rect.js b/mobile/android/chrome/tests/browser_rect.js deleted file mode 100644 index fb8be8cc4d25..000000000000 --- a/mobile/android/chrome/tests/browser_rect.js +++ /dev/null @@ -1,107 +0,0 @@ -function test() { - waitForExplicitFinish(); - - ok(Rect, "Rect class exists"); - - for (let test in tests) { - tests[test](); - } - - finish(); -} - -let tests = { - testGetDimensions: function() { - let r = new Rect(5, 10, 100, 50); - ok(r.left == 5, "rect has correct left value"); - ok(r.top == 10, "rect has correct top value"); - ok(r.right == 105, "rect has correct right value"); - ok(r.bottom == 60, "rect has correct bottom value"); - ok(r.width == 100, "rect has correct width value"); - ok(r.height == 50, "rect has correct height value"); - ok(r.x == 5, "rect has correct x value"); - ok(r.y == 10, "rect has correct y value"); - }, - - testIsEmpty: function() { - let r = new Rect(0, 0, 0, 10); - ok(r.isEmpty(), "rect with nonpositive width is empty"); - let r = new Rect(0, 0, 10, 0); - ok(r.isEmpty(), "rect with nonpositive height is empty"); - let r = new Rect(0, 0, 10, 10); - ok(!r.isEmpty(), "rect with positive dimensions is not empty"); - }, - - testRestrictTo: function() { - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(50, 50, 100, 100); - r1.restrictTo(r2); - ok(r1.equals(new Rect(50, 50, 60, 60)), "intersection is non-empty"); - - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(120, 120, 100, 100); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection is empty"); - - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(0, 0, 0, 0); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection of rect and empty is empty"); - - let r1 = new Rect(0, 0, 0, 0); - let r2 = new Rect(0, 0, 0, 0); - r1.restrictTo(r2); - ok(r1.isEmpty(), "intersection of empty and empty is empty"); - }, - - testExpandToContain: function() { - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(50, 50, 100, 100); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 140, 140)), "correct expandToContain on intersecting rectangles"); - - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(120, 120, 100, 100); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 210, 210)), "correct expandToContain on non-intersecting rectangles"); - - let r1 = new Rect(10, 10, 100, 100); - let r2 = new Rect(0, 0, 0, 0); - r1.expandToContain(r2); - ok(r1.equals(new Rect(10, 10, 100, 100)), "expandToContain of rect and empty is rect"); - - let r1 = new Rect(10, 10, 0, 0); - let r2 = new Rect(0, 0, 0, 0); - r1.expandToContain(r2); - ok(r1.isEmpty(), "expandToContain of empty and empty is empty"); - }, - - testSubtract: function testSubtract() { - function equals(rects1, rects2) { - return rects1.length == rects2.length && rects1.every(function(r, i) { - return r.equals(rects2[i]); - }); - } - - let r1 = new Rect(0, 0, 100, 100); - let r2 = new Rect(500, 500, 100, 100); - ok(equals(r1.subtract(r2), [r1]), "subtract area outside of region yields same region"); - - let r1 = new Rect(0, 0, 100, 100); - let r2 = new Rect(-10, -10, 50, 120); - ok(equals(r1.subtract(r2), [new Rect(40, 0, 60, 100)]), "subtracting vertical bar from edge leaves one rect"); - - let r1 = new Rect(0, 0, 100, 100); - let r2 = new Rect(-10, -10, 120, 50); - ok(equals(r1.subtract(r2), [new Rect(0, 40, 100, 60)]), "subtracting horizontal bar from edge leaves one rect"); - - let r1 = new Rect(0, 0, 100, 100); - let r2 = new Rect(40, 40, 20, 20); - ok(equals(r1.subtract(r2), [ - new Rect(0, 0, 40, 100), - new Rect(40, 0, 20, 40), - new Rect(40, 60, 20, 40), - new Rect(60, 0, 40, 100)]), - "subtracting rect in middle leaves union of rects"); - }, -}; diff --git a/mobile/android/chrome/tests/browser_rememberPassword.js b/mobile/android/chrome/tests/browser_rememberPassword.js deleted file mode 100644 index f2708a4b16e8..000000000000 --- a/mobile/android/chrome/tests/browser_rememberPassword.js +++ /dev/null @@ -1,60 +0,0 @@ -var testURL_01 = chromeRoot + "browser_blank_01.html"; - -// Tests for the Remember Password UI - -let gCurrentTab = null; -function test() { - waitForExplicitFinish(); - - messageManager.addMessageListener("pageshow", function() { - if (gCurrentTab.browser.currentURI.spec == testURL_01) { - messageManager.removeMessageListener("pageshow", arguments.callee); - pageLoaded(); - } - }); - - gCurrentTab = Browser.addTab(testURL_01, true); -} - -function pageLoaded() { - let iHandler = getIdentityHandler(); - let iPassword = document.getElementById("pageaction-password"); - let lm = getLoginManager(); - let host = gCurrentTab.browser.currentURI.prePath; - let nullSubmit = createLogin(host, host, null); - let nullForm = createLogin(host, null, "realm"); - - lm.removeAllLogins(); - - iHandler.show(); - is(iPassword.hidden, true, "Remember password hidden for no logins"); - iHandler.hide(); - - lm.addLogin(nullSubmit); - iHandler.show(); - is(iPassword.hidden, false, "Remember password shown for form logins"); - iPassword.click(); - is(iPassword.hidden, true, "Remember password hidden after click"); - is(lm.countLogins(host, "", null), 0, "Logins deleted when clicked"); - iHandler.hide(); - - lm.addLogin(nullForm); - iHandler.show(); - is(iPassword.hidden, false, "Remember password shown for protocol logins"); - iPassword.click(); - is(iPassword.hidden, true, "Remember password hidden after click"); - is(lm.countLogins(host, null, ""), 0, "Logins deleted when clicked"); - iHandler.hide(); - - Browser.closeTab(gCurrentTab); - finish(); -} - -function getLoginManager() { - return Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager); -} - -function createLogin(aHostname, aFormSubmitURL, aRealm) { - let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Components.interfaces.nsILoginInfo, "init"); - return new nsLoginInfo(aHostname, aFormSubmitURL, aRealm, "username", "password", "uname", "pword"); -} diff --git a/mobile/android/chrome/tests/browser_scroll.html b/mobile/android/chrome/tests/browser_scroll.html deleted file mode 100644 index e0f816a9617c..000000000000 --- a/mobile/android/chrome/tests/browser_scroll.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - scrollTo test - - - - -

scrollTo test

-

The urlbar should scroll out of view after this page loads.

- - diff --git a/mobile/android/chrome/tests/browser_scroll.js b/mobile/android/chrome/tests/browser_scroll.js deleted file mode 100644 index 5445280589bc..000000000000 --- a/mobile/android/chrome/tests/browser_scroll.js +++ /dev/null @@ -1,19 +0,0 @@ -// Test behavior of window.scrollTo during page load (bug 654122). -"use strict"; - -var gTab; -registerCleanupFunction(function() Browser.closeTab(gTab)); - -const TEST_URL = baseURI + "browser_scroll.html"; - -function test() { - waitForExplicitFinish(); - gTab = Browser.addTab(TEST_URL, true); - onMessageOnce(gTab.browser.messageManager, "Browser:FirstPaint", function() { - executeSoon(function() { - let rect = Elements.browsers.getBoundingClientRect(); - is(rect.top, 0, "Titlebar is hidden."); - finish(); - }); - }); -} diff --git a/mobile/android/chrome/tests/browser_scrollbar.js b/mobile/android/chrome/tests/browser_scrollbar.js deleted file mode 100644 index 231b6fde4c65..000000000000 --- a/mobile/android/chrome/tests/browser_scrollbar.js +++ /dev/null @@ -1,181 +0,0 @@ -let testURL_01 = baseURI + "browser_scrollbar.sjs?"; - -let gCurrentTest = null; -let gTests = []; -let gOpenedTabs = []; // for cleanup - -//------------------------------------------------------------------------------ -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Close the awesome panel just in case - AwesomeScreen.activePanel = null; - finish(); - } -} - -function waitForPageShow(aPageURL, aCallback) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (aMessage.target.currentURI.spec == aPageURL) { - messageManager.removeMessageListener("pageshow", arguments.callee); - - setTimeout(aCallback, 0); - } - }); -}; - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // This test is async - waitForExplicitFinish(); - runNextTest(); -} - -let horizontalScrollbar = document.getElementById("horizontal-scroller"); -let verticalScrollbar = document.getElementById("vertical-scroller"); - -function checkScrollbars(aHorizontalVisible, aVerticalVisible, aHorizontalPosition, aVerticalPosition) { - let browser = getBrowser(); - let width = browser.getBoundingClientRect().width; - let height = browser.getBoundingClientRect().height; - EventUtils.synthesizeMouse(browser, width / 2, height / 4, { type: "mousedown" }); - EventUtils.synthesizeMouse(browser, width / 2, height * 3 / 4, { type: "mousemove" }); - - let horizontalVisible = horizontalScrollbar.hasAttribute("panning"), - verticalVisible = verticalScrollbar.hasAttribute("panning"); - is(horizontalVisible, aHorizontalVisible, "The horizontal scrollbar should be " + (aHorizontalVisible ? "visible" : "hidden")); - is(verticalVisible, aVerticalVisible, "The vertical scrollbar should be " + (aVerticalVisible ? "visible" : "hidden")); - - EventUtils.synthesizeMouse(browser, width / 2, height * 3 / 4, { type: "mouseup" }); -} - -function checkScrollbarsPosition(aX) { - let browser = getBrowser(); - let width = browser.getBoundingClientRect().width; - let height = browser.getBoundingClientRect().height; - EventUtils.synthesizeMouse(browser, width / 2, height / 4, { type: "mousedown" }); - EventUtils.synthesizeMouse(browser, width / 2, height * 3 / 4, { type: "mousemove" }); - - let verticalRect = verticalScrollbar.getBoundingClientRect(); - let margin = parseInt(verticalScrollbar.getAttribute("end")); - let matches = verticalScrollbar.style.MozTransform.match(/^translate\(([-0-9]+)px/); - let translateX = matches ? parseInt(matches[1]) : 0; - let expectedPosition = window.innerWidth - aX - margin + translateX; - is(verticalRect.right, expectedPosition, "The vertical scrollbar should be position to " + expectedPosition + " (got " + verticalRect.right + ")"); - - EventUtils.synthesizeMouse(browser, width / 2, height * 3 / 4, { type: "mouseup" }); -} - -gTests.push({ - desc: "Testing visibility of scrollbars", - - run: function() { - waitForPageShow(testURL_01 + "blank", gCurrentTest.checkNotScrollable); - gOpenedTabs.push(Browser.addTab(testURL_01 + "blank", true)); - }, - - checkNotScrollable: function() { - checkScrollbars(false, false); - - waitForPageShow(testURL_01 + "horizontal", gCurrentTest.checkHorizontalScrollable); - gOpenedTabs.push(Browser.addTab(testURL_01 + "horizontal", true)); - }, - - checkHorizontalScrollable: function() { - checkScrollbars(true, false); - - waitForPageShow(testURL_01 + "vertical", gCurrentTest.checkVerticalScrollable); - gOpenedTabs.push(Browser.addTab(testURL_01 + "vertical", true)); - }, - - checkVerticalScrollable: function() { - checkScrollbars(false, true); - - waitForPageShow(testURL_01 + "both", gCurrentTest.checkBothScrollable); - gOpenedTabs.push(Browser.addTab(testURL_01 + "both", true)); - }, - - checkBothScrollable: function() { - checkScrollbars(true, true); - Elements.browsers.addEventListener("PanFinished", function(aEvent) { - Elements.browsers.removeEventListener("PanFinished", arguments.callee, false); - setTimeout(function() { - Browser.hideSidebars(); - }, 0); - runNextTest(); - }, false); - } -}); - -gTests.push({ - desc: "Testing position of scrollbars", - - run: function() { - waitForPageShow(testURL_01 + "vertical", gCurrentTest.checkScrollbarsPosition); - gOpenedTabs.push(Browser.addTab(testURL_01 + "vertical", true)); - }, - - checkScrollbarsPosition: function() { - let [,, tabsWidth, controlsWidth] = Browser.computeSidebarVisibility(); - - checkScrollbarsPosition(0); - - // Show the left sidebar and ensure scrollbar is visible - Browser.controlsScrollboxScroller.scrollTo(0, 0); - checkScrollbarsPosition(-tabsWidth); - - // Show the right sidebar and ensure scrollbar is visible - Browser.controlsScrollboxScroller.scrollTo(tabsWidth + controlsWidth, 0); - checkScrollbarsPosition(controlsWidth); - - gCurrentTest.finish(); - }, - - finish: function() { - Elements.browsers.addEventListener("PanFinished", function(aEvent) { - Elements.browsers.removeEventListener("PanFinished", arguments.callee, false); - setTimeout(function() { - Browser.hideSidebars(); - }, 0); - runNextTest(); - }, false); - } -}); - - -gTests.push({ - desc: "Check scrollbar visibility when the touch sequence is cancelled", - - run: function() { - waitForPageShow(testURL_01 + "both", gCurrentTest.checkVisibility); - gOpenedTabs.push(Browser.addTab(testURL_01 + "both", true)); - }, - - checkVisibility: function() { - let browser = getBrowser(); - let width = browser.getBoundingClientRect().width; - let height = browser.getBoundingClientRect().height; - EventUtils.synthesizeMouse(browser, width / 2, height / 4, { type: "mousedown" }); - EventUtils.synthesizeMouse(browser, width / 2, height * 3 / 4, { type: "mousemove" }); - - let event = document.createEvent("Events"); - event.initEvent("CancelTouchSequence", true, false); - document.dispatchEvent(event); - - let horizontalVisible = horizontalScrollbar.hasAttribute("panning"), - verticalVisible = verticalScrollbar.hasAttribute("panning"); - is(horizontalVisible, false, "The horizontal scrollbar should be hidden when a canceltouchsequence is fired"); - is(verticalVisible, false, "The vertical scrollbar should be hidden should be hidden when a canceltouchsequence is called"); - - for (let iTab=0; iTab"); - response.write(""); - - let body = "" + query + ""; - switch (query) { - case "blank": - response.write("This is a not a scrollable page"); - break; - case "horizontal": - response.write("This is a horizontally scrollable page"); - body += "\n
Browser scrollbar test
"; - break; - case "vertical": - response.write("This is a vertically scrollable page"); - body += "\n
Browser scrollbar test
"; - break; - case "both": - response.write("This is a scrollable page in both directions"); - body += "\n
Browser scrollbar test
"; - break; - default: - break; - } - response.write("" + body + ""); -} diff --git a/mobile/android/chrome/tests/browser_select.html b/mobile/android/chrome/tests/browser_select.html deleted file mode 100644 index 4de8ead4e201..000000000000 --- a/mobile/android/chrome/tests/browser_select.html +++ /dev/null @@ -1,99 +0,0 @@ - -Browser Blank Page 01 - - - -
- onchange: (selectedIndex) [value] -
- - -
- - - -
-
- - -
- onchange: (selectedIndex) [value] -
- - -
-
- - -
-
- -
OptGroup Combobox:
- -
-
- - -
- -

-
-
-
diff --git a/mobile/android/chrome/tests/browser_select.js b/mobile/android/chrome/tests/browser_select.js
deleted file mode 100644
index ccf0fd29959b..000000000000
--- a/mobile/android/chrome/tests/browser_select.js
+++ /dev/null
@@ -1,87 +0,0 @@
-let testURL = chromeRoot + "browser_select.html";
-let new_tab = null;
-
-//------------------------------------------------------------------------------
-// Entry point (must be named "test")
-function test() {
-  // This test is async
-  waitForExplicitFinish();
-
-  // Add new tab to hold the 
-  
-
-  
- -
- - - diff --git a/mobile/android/chrome/tests/browser_tapping.js b/mobile/android/chrome/tests/browser_tapping.js deleted file mode 100644 index 12c203a9e651..000000000000 --- a/mobile/android/chrome/tests/browser_tapping.js +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Testing the tapping interactions: - * single tap, double tap & long tap - */ - -let testURL = chromeRoot + "browser_tap_content.html"; - -let gTests = []; -let gCurrentTest = null; -let gCurrentTab; - -const kDoubleClickIntervalPlus = kDoubleClickInterval + 100; - -let gEvents = []; -function dumpEvents(aEvent) { - if (aEvent.target != gCurrentTab.browser.parentNode) - return; - - gEvents.push(aEvent.type); -} - -function clearEvents() { - gEvents = []; -} - -function checkEvents(aEvents) { - if (aEvents.length != gEvents.length) { - info("---- event check: failed length (" + aEvents.length + " != " + gEvents.length + ")\n"); - info("---- expected: [" + aEvents.join(",") + "] actual: [" + gEvents.join(",") + "]\n"); - return false; - } - - for (let i=0; i 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - window.removeEventListener("TapSingle", dumpEvents, true); - window.removeEventListener("TapDouble", dumpEvents, true); - window.removeEventListener("TapLong", dumpEvents, true); - - SelectionHelper.enabled = true; - Browser.closeTab(gCurrentTab); - - finish(); - } -} - -//------------------------------------------------------------------------------ -// Case: Test the double tap behavior -gTests.push({ - desc: "Test the double tap behavior", - - run: function() { - let inputHandler = gCurrentTab.browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - // Should fire "TapSingle" - info("Test good single tap"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 2, {}); - - // We wait a bit because of the delay allowed for double clicking on device - // where it is not native - setTimeout(function() { - ok(checkEvents(["TapSingle"]), "Fired a good single tap"); - clearEvents(); - gCurrentTest.doubleTapTest(); - }, kDoubleClickIntervalPlus); - }, - - doubleTapTest: function() { - let inputHandler = gCurrentTab.browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - // Should fire "TapDouble" - info("Test good double tap"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 2, {}); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 2, {}); - - setTimeout(function() { - let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2); - if (sysInfo.get("device")) - todo(checkEvents(["TapDouble"]), "Fired a good double tap"); - else - ok(checkEvents(["TapDouble"]), "Fired a good double tap"); - - clearEvents(); - - gCurrentTest.doubleTapFailTest(); - }, kDoubleClickIntervalPlus); - }, - - doubleTapFailTest: function() { - let inputHandler = gCurrentTab.browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - // Should fire "TapSingle", "TapSingle" - info("Test two single taps in different locations"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 3, height / 3, {}); - EventUtils.synthesizeMouse(document.documentElement, width * 2 / 3, height * 2 / 3, {}); - - setTimeout(function() { - ok(checkEvents(["TapSingle", "TapSingle"]), "Fired two single taps in different places, not a double tap"); - clearEvents(); - - gCurrentTest.tapPanTest(); - }, 500); - }, - - tapPanTest: function() { - let inputHandler = gCurrentTab.browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - info("Test a pan - non-tap event"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 3, { type: "mousedown" }); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height * 2 / 3, { type: "mousemove" }); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height * 2 / 3, { type: "mouseup" }); - ok(checkEvents([]), "Fired a pan which should be seen as a non event"); - clearEvents(); - - setTimeout(function() { gCurrentTest.longTapFailTest(); }, 500); - }, - - longTapFailTest: function() { - let inputHandler = gCurrentTab.browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - info("Test a long pan - non-tap event"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 3, { type: "mousedown" }); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height * 2 / 3, { type: "mousemove" }); - setTimeout(function() { - EventUtils.synthesizeMouse(document.documentElement, width / 2, height * 2 / 3, { type: "mouseup" }); - ok(checkEvents([]), "Fired a pan + delay which should be seen as a non-event"); - clearEvents(); - - window.addEventListener("PanFinished", function() { - window.removeEventListener("PanFinished", arguments.callee, true); - setTimeout(gCurrentTest.longTapPassTest, 0); - }, true); - }, 500); - }, - - longTapPassTest: function() { - let browser = gCurrentTab.browser; - let inputHandler = browser.parentNode; - let width = inputHandler.getBoundingClientRect().width; - let height = inputHandler.getBoundingClientRect().height; - - window.addEventListener("TapLong", function() { - window.removeEventListener("TapLong", arguments.callee, true); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 2, { type: "mouseup" }); - ok(checkEvents(["TapLong"]), "Fired a good long tap"); - clearEvents(); - }, true); - - browser.messageManager.addMessageListener("Browser:ContextMenu", function(aMessage) { - browser.messageManager.removeMessageListener(aMessage.name, arguments.callee); - setTimeout(gCurrentTest.contextPlainLinkTest, 0); - }); - - info("Test a good long pan"); - clearEvents(); - EventUtils.synthesizeMouse(document.documentElement, width / 2, height / 2, { type: "mousedown" }); - }, - - contextPlainLinkTest: function() { - waitForContextMenu(function(aJSON) { - is(aJSON.linkTitle, "A blank page - nothing interesting", "Text content should be the content of the second link"); - ok(checkContextTypes(["link", "link-openable"]), "Plain link context types"); - }, gCurrentTest.contextPlainImageTest); - - let browser = gCurrentTab.browser; - let linkDisabled = browser.contentDocument.getElementById("link-disabled"); - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - linkDisabled.dispatchEvent(event); - - let link = browser.contentDocument.getElementById("link-single"); - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - link.dispatchEvent(event); - }, - - contextPlainImageTest: function() { - waitForContextMenu(function() { - ok(checkContextTypes(["image","image-shareable","image-loaded", "content-text"]), "Plain image context types"); - }, gCurrentTest.contextNestedImageTest); - - let browser = gCurrentTab.browser; - let img = browser.contentDocument.getElementById("img-single"); - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - img.dispatchEvent(event); - }, - - contextNestedImageTest: function() { - waitForContextMenu(function() { - ok(checkContextTypes(["link","image","image-shareable","image-loaded","link-openable"]), "Nested image context types"); - }, runNextTest); - - let browser = gCurrentTab.browser; - let img = browser.contentDocument.getElementById("img-nested"); - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - img.dispatchEvent(event); - } -}); - diff --git a/mobile/android/chrome/tests/browser_tapping_edit.js b/mobile/android/chrome/tests/browser_tapping_edit.js deleted file mode 100644 index b1e4c139a476..000000000000 --- a/mobile/android/chrome/tests/browser_tapping_edit.js +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Testing the context menus on editboxes: - * plain and url - */ - -let testURL = chromeRoot + "browser_tap_contentedit.html"; - -let gTests = []; -let gCurrentTest = null; -let gCurrentTab; - -const kDoubleClickIntervalPlus = kDoubleClickInterval + 100; - -let gEvents = []; -function dumpEvents(aEvent) { - if (aEvent.target != gCurrentTab.browser.parentNode) - return; - - gEvents.push(aEvent.type); -} - -function clearEvents() { - gEvents = []; -} - -function checkEvents(aEvents) { - if (aEvents.length != gEvents.length) { - info("---- event check: failed length (" + aEvents.length + " != " + gEvents.length + ")\n"); - info("---- expected: [" + aEvents.join(",") + "] actual: [" + gEvents.join(",") + "]\n"); - return false; - } - - for (let i=0; i 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); - - window.removeEventListener("TapSingle", dumpEvents, true); - window.removeEventListener("TapDouble", dumpEvents, true); - window.removeEventListener("TapLong", dumpEvents, true); - - SelectionHelper.enabled = true; - Browser.closeTab(gCurrentTab); - - finish(); - } -} - -//------------------------------------------------------------------------------ -gTests.push({ - desc: "Test empty plain textbox", - - run: function() { - waitForContextMenu(function(aJSON) { - ok(checkContextTypes(["input-text"]), "Editbox with no text, no selection and no clipboard"); - }, runNextTest); - - let browser = gCurrentTab.browser; - let plainEdit = browser.contentDocument.getElementById("plain-edit"); - plainEdit.readOnly = false; - plainEdit.value = ""; - - // Try very hard to keep "paste" from if the clipboard has data - let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); - plainEdit.readOnly = true; - - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - plainEdit.dispatchEvent(event); - } -}); - -//------------------------------------------------------------------------------ -gTests.push({ - desc: "Test plain textbox with text fully selected", - - run: function() { - waitForContextMenu(function(aJSON) { - ok(checkContextTypes(["input-text", "copy"]), "Editbox with text and full selection, but no clipboard"); - }, runNextTest); - - let browser = gCurrentTab.browser; - let plainEdit = browser.contentDocument.getElementById("plain-edit"); - plainEdit.readOnly = false; - plainEdit.value = "Every time we fix a bug, Stuart call's the President"; - let plainEdit = plainEdit.QueryInterface(Ci.nsIDOMNSEditableElement); - plainEdit.editor.selectAll(); - - // Try very hard to keep "paste" from if the clipboard has data - let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); - plainEdit.readOnly = true; - - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - plainEdit.dispatchEvent(event); - } -}); - -//------------------------------------------------------------------------------ -gTests.push({ - desc: "Test plain textbox with text no selection", - - run: function() { - waitForContextMenu(function(aJSON) { - ok(checkContextTypes(["input-text", "copy-all", "select-all"]), "Editbox with text, but no selection and no clipboard"); - }, runNextTest); - - let browser = gCurrentTab.browser; - let plainEdit = browser.contentDocument.getElementById("plain-edit"); - plainEdit.readOnly = false; - plainEdit.value = "Every time we fix a bug, Stuart call's the President"; - plainEdit.selectionStart = 0; - plainEdit.selectionEnd = 0; - - // Try very hard to keep "paste" from if the clipboard has data - let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); - plainEdit.readOnly = true; - - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - plainEdit.dispatchEvent(event); - } -}); - -//------------------------------------------------------------------------------ -gTests.push({ - desc: "Test plain textbox with text no selection and text on clipboard", - - run: function() { - waitForContextMenu(function(aJSON) { - ok(checkContextTypes(["input-text", "copy-all", "select-all", "paste"]), "Editbox with text and clipboard, but no selection"); - }, runNextTest); - - let browser = gCurrentTab.browser; - let plainEdit = browser.contentDocument.getElementById("plain-edit"); - plainEdit.readOnly = false; - plainEdit.value = "Every time we fix a bug, Stuart call's the President"; - plainEdit.selectionStart = 0; - plainEdit.selectionEnd = 0; - - // Put some data on the clipboard to get "paste" to be active - let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); - clipboard.copyString("We are testing Firefox"); - - let event = content.document.createEvent("PopupEvents"); - event.initEvent("contextmenu", true, true); - plainEdit.dispatchEvent(event); - } -}); - -//------------------------------------------------------------------------------ -gTests.push({ - desc: "Test that tapping on input box causes mouse events to fire", - - run: function() { - let browser = gCurrentTab.browser; - let plainEdit = browser.contentDocument.getElementById("plain-edit"); - plainEdit.blur(); - plainEdit.value = ''; - - let eventArray = ['mouseover', 'mousedown', 'mouseup', 'click']; - - while (eventArray.length > 0) { - let currentEventType = eventArray.shift(); - browser.contentWindow.addEventListener(currentEventType, function(e) { - browser.contentWindow.removeEventListener(currentEventType, arguments.callee, true); - ok(e.target == plainEdit, e.type + " should fire over input id=" + plainEdit.id); - plainEdit.value += e.type + ' '; - - if (e.type == 'click') { - ok(plainEdit.value == 'mouseover mousedown mouseup click ', - 'Events should fire in this order: mouseover mousedown mouseup click '); - runNextTest(); - } - } , true); - } - - EventUtils.synthesizeMouse(plainEdit, browser.getBoundingClientRect().left + plainEdit.getBoundingClientRect().left + 2, - browser.getBoundingClientRect().top + plainEdit.getBoundingClientRect().top + 2, {}); - } -}); - diff --git a/mobile/android/chrome/tests/browser_test.js b/mobile/android/chrome/tests/browser_test.js deleted file mode 100644 index c0a987eb4c04..000000000000 --- a/mobile/android/chrome/tests/browser_test.js +++ /dev/null @@ -1,20 +0,0 @@ -// Tests for the test functions in head.js - -function test() { - waitForExplicitFinish(); - testWaitForAndContinue(); -} - -function testWaitForAndContinue() { - waitForAndContinue(function() { - ok(true, "continues on success") - testWaitForAndContinue2(); - }, function() true); -} - -function testWaitForAndContinue2() { - waitForAndContinue(function() { - ok(true, "continues on failure"); - finish(); - }, function() false); -} diff --git a/mobile/android/chrome/tests/browser_thumbnails.js b/mobile/android/chrome/tests/browser_thumbnails.js deleted file mode 100644 index 59ac82d731e0..000000000000 --- a/mobile/android/chrome/tests/browser_thumbnails.js +++ /dev/null @@ -1,155 +0,0 @@ -// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- -/* - * ***** 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 Mobile Browser. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Wes Johnston - * - * 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 ***** */ - -let testURL_blank = baseURI + "browser_blank_01.html"; - -const DEFAULT_WIDTH = 800; - -function testURL(n) { - if (n < 0) - return testURL_blank; - - return baseURI + "browser_viewport.sjs?" + encodeURIComponent(gTestData[n].metadata); -} - -function scaleRatio(n) { - if ("scaleRatio" in gTestData[n]) - return gTestData[n].scaleRatio; - return 150; // Default value matches our main target hardware (N900, Nexus One, etc.) -} - -let currentTab; - -let loadURL = function loadURL(aPageURL) { - BrowserUI.goToURI(aPageURL); -}; - -let gTestData = [ - { metadata: "", width: DEFAULT_WIDTH, scale: 1 }, - { metadata: "width=device-width, initial-scale=1" }, - { metadata: "width=device-width" }, - { metadata: "width=320, initial-scale=1" }, - { metadata: "initial-scale=1.0, user-scalable=no" }, - { metadata: "width=200,height=500" }, - { metadata: "width=2000, minimum-scale=0.75" }, - { metadata: "width=100, maximum-scale=2.0" }, - { metadata: "width=2000, initial-scale=0.75" }, - { metadata: "width=20000, initial-scale=100" }, - { metadata: "XHTML" }, - /* testing opening and switching between pages without a viewport */ - { metadata: "style=width:400px;margin:0px;" }, - { metadata: "style=width:1000px;margin:0px;" }, - { metadata: "style=width:800px;margin:0px;" }, - { metadata: "style=width:800px;height:300px;margin:0px;" }, - { metadata: "style=width:800px;height:1000px;margin:0px;" }, -]; - - - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -let gCurrentTest = -1; -let secondPass = false; -let oldRendererFactory; -let gDevice = null; -function test() { - oldRendererFactory = rendererFactory; - rendererFactory = newRendererFactory; - - // if we are on desktop, we can run tests in both portrait and landscape modes - // on devices we should just use the current orientation - let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2); - gDevice = sysInfo.get("device"); - if (gDevice != null) - secondPass = true; - - // This test is async - waitForExplicitFinish(); - - currentTab = Browser.addTab("about:blank", true); - ok(currentTab, "Tab Opened"); - - startTest(gCurrentTest); -} - -function startTest(n) { - let url = testURL(gCurrentTest); - info("Testing: " + url) - loadURL(url); -} - -function newRendererFactory(aBrowser, aCanvas) { - let wrapper = {}; - let ctx = aCanvas.MozGetIPCContext("2d"); - let draw = function(browser, aLeft, aTop, aWidth, aHeight, aColor, aFlags) { - is(aLeft, 0,"Thumbnail drawn at x=0"); - is(aTop, 0,"Thumbnail drawn at y=0"); - ok(aWidth <= browser.contentDocumentWidth, "Thumbnail ok width: " + aWidth + " <= " + browser.contentDocumentWidth); - ok(aHeight <= browser.contentDocumentHeight,"Thumbnail ok height:" + aHeight + " <= " + browser.contentDocumentHeight); - finishTest(); - }; - wrapper.checkBrowser = function(browser) { - return browser.contentWindow; - }; - wrapper.drawContent = function(callback) { - callback(ctx, draw); - }; - - return wrapper; -}; - -function finishTest() { - gCurrentTest++; - if (gCurrentTest < gTestData.length) { - startTest(gCurrentTest); - } else if (secondPass) { - - if (gDevice == null) - window.top.resizeTo(480,800); - - Browser.closeTab(currentTab); - rendererFactory = oldRendererFactory; - finish(); - } else { - secondPass = true; - gCurrentTest = -1; - window.top.resizeTo(800,480); - startTest(gCurrentTest); - } -} diff --git a/mobile/android/chrome/tests/browser_title.sjs b/mobile/android/chrome/tests/browser_title.sjs deleted file mode 100644 index a523c1de5de6..000000000000 --- a/mobile/android/chrome/tests/browser_title.sjs +++ /dev/null @@ -1,67 +0,0 @@ -/* ***** 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 Mobile Browser. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Aditya Rao - * Vivien Nicolas <21@vingtetun.org> - * - * 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 ***** */ - -function handleRequest(request, response) { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html", false); - - let action = ""; - let query = decodeURIComponent(request.queryString || ""); - response.write(""); - - switch (query) { - case "no_title": - break; - case "english_title": - response.write("English Title Page"); - break; - case "dynamic_title": - response.write("This is an english title page"); - response.write(""); - break; - case "redirect": - response.write(""); - break; - case "location": - response.write(""); - break; - default: - break; - } - response.write("" + query + ""); -} diff --git a/mobile/android/chrome/tests/browser_upgrade.rdf b/mobile/android/chrome/tests/browser_upgrade.rdf deleted file mode 100644 index bfde13200e03..000000000000 --- a/mobile/android/chrome/tests/browser_upgrade.rdf +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - -
  • - - 2.0 - - - toolkit@mozilla.org - 0 - * - http://example.com/browser/mobile/chrome/tests/addons/browser_install1_3.xpi - - - -
  • -
    -
    -
    - - - - -
  • - - 1.0 - - - mochikit@mozilla.org - 0 - * - - - -
  • -
    -
    -
    - -
    diff --git a/mobile/android/chrome/tests/browser_viewport.js b/mobile/android/chrome/tests/browser_viewport.js deleted file mode 100644 index bb95cc2eb6d2..000000000000 --- a/mobile/android/chrome/tests/browser_viewport.js +++ /dev/null @@ -1,209 +0,0 @@ -// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- -/* - * ***** 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 Mobile Browser. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Mark Finkle - * Matt Brubeck - * - * 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 ***** */ - -let testURL_blank = baseURI + "browser_blank_01.html"; - -const DEFAULT_WIDTH = 800; - -function testURL(n) { - return baseURI + "browser_viewport.sjs" + - "?metadata=" + encodeURIComponent(gTestData[n].metadata || "") + - "&style=" + encodeURIComponent(gTestData[n].style || "") + - "&xhtml=" + encodeURIComponent(!!gTestData[n].xhtml); -} - -function scaleRatio(n) { - if ("scaleRatio" in gTestData[n]) - return gTestData[n].scaleRatio; - return 150; // Default value matches our main target hardware (N900, Nexus One, etc.) -} - -let currentTab; - -let loadURL = function loadURL(aPageURL, aCallback, aScale) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (aMessage.target.currentURI.spec == aPageURL) { - messageManager.removeMessageListener(aMessage.name, arguments.callee); - - waitFor(aCallback, function() { - return !aScale || aScale == aMessage.target.scale; - }); - } - }); - - BrowserUI.goToURI(aPageURL); -}; - -// XXX Tests do not yet run correctly in portrait. -window.resizeTo(800, 480); - -let gTestData = [ - { metadata: "", width: DEFAULT_WIDTH, scale: 1 }, - { metadata: "width=device-width, initial-scale=1", width: 533.33, scale: 1.5 }, - { metadata: "width=device-width", width: 533.33, scale: 1.5 }, - { metadata: "width=device-width, initial-scale=1", scaleRatio: 100, width: 800, scale: 1 }, - { metadata: "width=320, initial-scale=1", width: 533.33, scale: 1.5 }, - { metadata: "initial-scale=1.0, user-scalable=no", width: 533.33, scale: 1.5, disableZoom: true }, - { metadata: "initial-scale=1.0, user-scalable=0", width: 533.33, scale: 1.5, disableZoom: true }, - { metadata: "initial-scale=1.0, user-scalable=false", width: 533.33, scale: 1.5, disableZoom: true }, - { metadata: "initial-scale=1.0, user-scalable=NO", width: 533.33, scale: 1.5, disableZoom: false }, // values are case-sensitive - { metadata: "width=200,height=500", width: 200, scale: 4 }, - { metadata: "width=2000, minimum-scale=0.75", width: 2000, scale: 1.125, minScale: 1.125 }, - { metadata: "width=100, maximum-scale=2.0", width: 266.67, scale: 3, maxScale: 3 }, - { metadata: "width=2000, initial-scale=0.75", width: 2000, scale: 1.125 }, - { metadata: "width=20000, initial-scale=100", width: 10000, scale: 4 }, - { xhtml: true, width: 533.33, scale: 1.5, disableZoom: false }, - /* testing spaces between arguments (bug 572696) */ - { metadata: "width= 2000, minimum-scale=0.75", width: 2000, scale: 1.125 }, - { metadata: "width = 2000, minimum-scale=0.75", width: 2000, scale: 1.125 }, - { metadata: "width = 2000 , minimum-scale=0.75", width: 2000, scale: 1.125 }, - { metadata: "width = 2000 , minimum-scale =0.75", width: 2000, scale: 1.125 }, - { metadata: "width = 2000 , minimum-scale = 0.75", width: 2000, scale: 1.125 }, - { metadata: "width = 2000 , minimum-scale = 0.75", width: 2000, scale: 1.125 }, - /* testing opening and switching between pages without a viewport */ - { style: "width:400px;margin:0px;", width: DEFAULT_WIDTH, scale: 1 }, - { style: "width:2000px;margin:0px;", width: 980, scale: window.innerWidth/2000 }, - { style: "width:800px;margin:0px;", width: DEFAULT_WIDTH, scale: 1 }, -]; - - -//------------------------------------------------------------------------------ -// Entry point (must be named "test") -function test() { - // This test is async - waitForExplicitFinish(); - requestLongerTimeout(2); - - currentTab = Browser.addTab("about:blank", true); - ok(currentTab, "Tab Opened"); - - startTest(0); -} - -function startTest(n) { - info(JSON.stringify(gTestData[n])); - BrowserUI.goToURI(testURL_blank); - loadURL(testURL_blank, verifyBlank(n)); - Services.prefs.setIntPref("browser.viewport.scaleRatio", scaleRatio(n)); -} - -function verifyBlank(n) { - return function() { - // Do sanity tests - let uri = currentTab.browser.currentURI.spec; - is(uri, testURL_blank, "URL Matches blank page " + n); - - waitFor(function() { - loadURL(testURL(n), verifyTest(n), gTestData[n].scale); - }, function() { - return currentTab.browser.contentWindowWidth == DEFAULT_WIDTH; - }); - } -} - -function is_approx(actual, expected, fuzz, description) { - ok(Math.abs(actual - expected) <= fuzz, - description + " [got " + actual + ", expected " + expected + "]"); -} - -function verifyTest(n) { - let assumedWidth = 480; - if (!Util.isPortrait()) - assumedWidth = 800; - - return function() { - is(window.innerWidth, assumedWidth, "Test assumes window width is " + assumedWidth + "px"); - - // Do sanity tests - let uri = currentTab.browser.currentURI.spec; - is(uri, testURL(n), "URL is " + testURL(n)); - - let data = gTestData[n]; - let actualWidth = currentTab.browser.contentWindowWidth; - is_approx(actualWidth, parseFloat(data.width), .01, "Viewport width=" + data.width); - - let zoomLevel = getBrowser().scale; - is_approx(zoomLevel, parseFloat(data.scale), .01, "Viewport scale=" + data.scale); - - // Test zooming - if (data.disableZoom) { - ok(!currentTab.allowZoom, "Zoom disabled"); - - Browser.zoom(-1); - is(getBrowser().scale, zoomLevel, "Zoom in does nothing"); - - Browser.zoom(1); - is(getBrowser().scale, zoomLevel, "Zoom out does nothing"); - } - else { - ok(Browser.selectedTab.allowZoom, "Zoom enabled"); - } - - - if (data.minScale) { - do { // Zoom out until we can't go any farther. - zoomLevel = getBrowser().scale; - Browser.zoom(1); - } while (getBrowser().scale != zoomLevel); - ok(getBrowser().scale >= data.minScale, "Zoom out limited"); - } - - if (data.maxScale) { - do { // Zoom in until we can't go any farther. - zoomLevel = getBrowser().scale; - Browser.zoom(-1); - } while (getBrowser().scale != zoomLevel); - ok(getBrowser().scale <= data.maxScale, "Zoom in limited"); - } - - finishTest(n); - } -} - -function finishTest(n) { - Services.prefs.clearUserPref("browser.viewport.scaleRatio"); - if (n + 1 < gTestData.length) { - startTest(n + 1); - } else { - window.resizeTo(480, 800); - Browser.closeTab(currentTab); - finish(); - } -} diff --git a/mobile/android/chrome/tests/browser_viewport.sjs b/mobile/android/chrome/tests/browser_viewport.sjs deleted file mode 100644 index e7351a3f6754..000000000000 --- a/mobile/android/chrome/tests/browser_viewport.sjs +++ /dev/null @@ -1,65 +0,0 @@ -/* ***** 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 Mobile Browser. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Matt Brubeck - * - * 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 ***** */ - - function decodeQuery(query) { - let result = {}; - query.split("&").forEach(function(pair) { - let [key, val] = pair.split("="); - result[key] = decodeURIComponent(val); - }); - return result; - } - -function handleRequest(request, response) { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/html", false); - - let params = decodeQuery(request.queryString || ""); - - if (params.xhtml == "true") { - response.write(""); - response.write(""); - } - response.write("Browser Viewport Test"); - if (params.metadata) - response.write(""); - response.write(" "); -} diff --git a/mobile/android/chrome/tests/browser_vkb.js b/mobile/android/chrome/tests/browser_vkb.js deleted file mode 100644 index d20efe6c75a2..000000000000 --- a/mobile/android/chrome/tests/browser_vkb.js +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Check VKB show/hide behavior - */ -let testURL_01 = chromeRoot + "browser_forms.html"; -messageManager.loadFrameScript(chromeRoot + "remote_vkb.js", true); - -/* ============================= Tests Utils =============================== */ -let gTests = []; -let gCurrentTest = null; - -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - // Close the awesome panel just in case - AwesomeScreen.activePanel = null; - finish(); - } -} - -function test() { - // The "runNextTest" approach is async, so we need to call "waitForExplicitFinish()" - // We call "finish()" when the tests are finished - waitForExplicitFinish(); - - // Start the tests - if ("gTimeout" in window) - setTimeout(runNextTest, gTimeout); - else - runNextTest(); -} -/* ============================ End Utils ================================== */ - -Components.utils.import("resource://gre/modules/Services.jsm"); -let VKBStateHasChanged = false; -let VKBObserver = { - _enabled: false, - observe: function(aTopic, aSubject, aData) { - if (this._enabled != parseInt(aData)) { - this._enabled = parseInt(aData); - VKBstateHasChanged = true; - } - } -}; -Services.obs.addObserver(VKBObserver, "ime-enabled-state-changed", false); - -function waitForVKBChange(aCallback, aState) { - waitForAndContinue(aCallback, function() { - if (VKBStateHasChanged) { - VKBStateHasChanged = false; - return true; - } - - return VKBStateHasChanged; - }); -} - -let newTab = null; - -function waitForPageShow(aPageURL, aCallback) { - messageManager.addMessageListener("pageshow", function(aMessage) { - if (aMessage.target.currentURI.spec == aPageURL) { - messageManager.removeMessageListener("pageshow", arguments.callee); - setTimeout(function() { aCallback(); }, 0); - } - }); -}; - -function dragElement(element, x1, y1, x2, y2) { - EventUtils.synthesizeMouse(element, x1, y1, { type: "mousedown" }); - EventUtils.synthesizeMouse(element, x2, y2, { type: "mousemove" }); - EventUtils.synthesizeMouse(element, x2, y2, { type: "mouseup" }); -} - -//------------------------------------------------------------------------------ -// Case: Test interactions with a VKB from content -gTests.push({ - desc: "Test interactions with a VKB from content", - run: function() { - waitForPageShow(testURL_01, gCurrentTest.focusContentInputField); - - newTab = Browser.addTab(testURL_01, true); - ok(newTab, "Tab Opened"); - }, - - focusContentInputField: function() { - is(VKBObserver._enabled, false, "Initially the VKB should be closed"); - - AsyncTests.waitFor("Test:FocusRoot", {}, function(json) { - waitForVKBChange(gCurrentTest.showLeftSidebar); - }) - }, - - showLeftSidebar: function() { - is(VKBObserver._enabled, true, "When focusing an input field the VKB should be opened"); - - let browsers = document.getElementById("browsers"); - dragElement(browsers, window.innerWidth / 2, window.innerHeight / 2, 1000, 1000); - waitForVKBChange(gCurrentTest.showRightSidebar); - }, - - showRightSidebar: function() { - is(VKBObserver._enabled, true, "When pannning to the leftSidebar the VKB state should not changed"); - - let browsers = document.getElementById("browsers"); - dragElement(browsers, window.innerWidth / 2, window.innerHeight / 2, -1000, -1000); - waitForVKBChange(gCurrentTest.changeTab); - }, - - changeTab: function() { - is(VKBObserver._enabled, true, "When panning to the right sidebar the VKB state should not changed"); - - let firstTab = document.getElementById("tabs").children.firstChild; - BrowserUI.selectTab(firstTab); - waitForVKBChange(gCurrentTest.prepareOpenRightPanel); - }, - - prepareOpenRightPanel: function() { - is(VKBObserver._enabled, false, "Switching tab should close the VKB"); - - BrowserUI.selectTab(newTab); - - // Give back the focus to the content input and launch and check - // interaction with the right panel - AsyncTests.waitFor("Test:FocusRoot", {}, function(json) { - waitForVKBChange(gCurrentTest.openRightPanel); - }); - }, - - openRightPanel: function() { - is(VKBObserver._enabled, true, "Re-cliking on an input field should re-open the VKB"); - - let toolsButton = document.getElementById("tool-panel-open"); - let rect = toolsButton.getBoundingClientRect(); - EventUtils.synthesizeMouse(toolsButton, rect.width / 2, rect.height / 2, {}); - waitForVKBChange(function() { - is(VKBObserver._enabled, false, "Opening the right panel should close the VKB"); - BrowserUI.hidePanel(); - Browser.hideSidebars(); - BrowserUI.closeTab(newTab); - Services.obs.removeObserver(VKBObserver, "ime-enabled-state-changed"); - runNextTest(); - }); - } -}); diff --git a/mobile/android/chrome/tests/head.js b/mobile/android/chrome/tests/head.js deleted file mode 100644 index 965858ec96f7..000000000000 --- a/mobile/android/chrome/tests/head.js +++ /dev/null @@ -1,122 +0,0 @@ -/*============================================================================= - Common Helpers functions -=============================================================================*/ - -const kDefaultWait = 2000; -// Wait for a condition and call a supplied callback if condition is met within -// alloted time. If condition is not met, cause a hard failure, stopping the test. -function waitFor(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > kDefaultWait) - throw "waitFor timeout"; - setTimeout(waitFor, 50, callback, test, timeout); -}; - -// Wait for a condition and call a supplied callback if condition is met within -// alloted time. If condition is not met, continue anyway. Use this helper if the -// callback will test for the outcome, but not stop the entire test. -function waitForAndContinue(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > kDefaultWait) { - callback(); - return; - } - setTimeout(waitForAndContinue, 50, callback, test, timeout); -}; - -// Listen for the specified message once, then remove the listener. -function onMessageOnce(aMessageManager, aName, aCallback) { - aMessageManager.addMessageListener(aName, function onMessage(aMessage) { - aMessageManager.removeMessageListener(aName, onMessage); - setTimeout(function() { - aCallback(aMessage); - }, 0); - }); -}; - -// This function is useful for debugging one test where you need to wait for -// application to be ready -function waitForFirstPaint(aCallback) { - function hasFirstPaint() { - let startupInfo = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup).getStartupInfo(); - return ("firstPaint" in startupInfo); - } - - if (!hasFirstPaint()) { - waitFor(aCallback, hasFirstPaint, Date.now() + 3000); - return; - } - - aCallback(); -}; - -function makeURI(spec) { - return Services.io.newURI(spec, null, null); -}; - -EventUtils.synthesizeString = function synthesizeString(aString, aWindow) { - for (let i = 0; i < aString.length; i++) { - EventUtils.synthesizeKey(aString.charAt(i), {}, aWindow); - } -}; - -EventUtils.synthesizeMouseForContent = function synthesizeMouseForContent(aElement, aOffsetX, aOffsetY, aEvent, aWindow) { - let container = document.getElementById("browsers"); - let rect = container.getBoundingClientRect(); - - EventUtils.synthesizeMouse(aElement, rect.left + aOffsetX, rect.top + aOffsetY, aEvent, aWindow); -}; - -let AsyncTests = { - _tests: {}, - waitFor: function(aMessage, aData, aCallback) { - messageManager.addMessageListener(aMessage, this); - if (!this._tests[aMessage]) - this._tests[aMessage] = []; - - this._tests[aMessage].push(aCallback || function() {}); - setTimeout(function() { - Browser.selectedBrowser.messageManager.sendAsyncMessage(aMessage, aData || { }); - }, 0); - }, - - receiveMessage: function(aMessage) { - let test = this._tests[aMessage.name]; - let callback = test.shift(); - if (callback) - callback(aMessage.json); - } -}; - -let gCurrentTest = null; -let gTests = []; - -// Iterating tests by shifting test out one by one as runNextTest is called. -function runNextTest() { - // Run the next test until all tests completed - if (gTests.length > 0) { - gCurrentTest = gTests.shift(); - info(gCurrentTest.desc); - gCurrentTest.run(); - } - else { - finish(); - } -} - -let serverRoot = "http://example.com/browser/mobile/chrome/tests/"; -let baseURI = "http://mochi.test:8888/browser/mobile/chrome/tests/"; - -let chromeRoot = getRootDirectory(gTestPath); -messageManager.loadFrameScript(chromeRoot + "remote_head.js", true); -messageManager.loadFrameScript("chrome://mochikit/content/tests/SimpleTest/EventUtils.js", true); diff --git a/mobile/android/chrome/tests/locales_list.sjs b/mobile/android/chrome/tests/locales_list.sjs deleted file mode 100644 index 5843a82450c2..000000000000 --- a/mobile/android/chrome/tests/locales_list.sjs +++ /dev/null @@ -1,121 +0,0 @@ -let fennecID = "{a23983c0-fd0e-11dc-95ff-0800200c9a66}"; -Components.utils.import("resource://gre/modules/Services.jsm"); - -function getLocale(aLocaleParams, aAppParams) { - let l = { - TARGETLOCALE: "test{IDNUMBER}", - NAME: "Test Locale {IDNUMBER}", - VERSION: "1.0", - INSTALL: "http://www.example.com/browser/mobile/chrome/tests/addons/browser_locale{IDNUMBER}.xpi", - TYPENUMBER: 5, - TYPENAME: "Language Pack (Application)", - IDNUMBER: "", - }; - let a = { - APPNAME: "Fennec", - MINVERSION: "4.0", MAXVERSION: "*", - APPID: fennecID - }; - - if (aLocaleParams) { - for (var entry in aLocaleParams) { - l[entry] = aLocaleParams[entry]; - } - } - - if (aAppParams) { - for (var entry in aAppParams) { - a[entry] = aAppParams[entry]; - } - } - - l.app = a; - return l; -} - -let appTemplate = "" + -"{APPNAME}" + - "{MINVERSION}" + - "{MAXVERSION}" + - "{APPID}" + -""; - -let template = ""+ - "{TARGETLOCALE}" + - "{NAME}"+ - "{TYPENAME}"+ - "langpack-{TARGETLOCALE}@firefox-mobile.mozilla.org"+ - "{VERSION}"+ - "Public"+ - "{APPS}"+ - "ALL"+ - "{INSTALL}\n" + - "title=TITLE\n" + - "continueIn=CONTINUEIN%S\n" + - "name=NAME\n" + - "choose=CHOOSE\n" + - "chooseLanguage=CHOOSELANGUAGE\n" + - "cancel=CANCEL\n" + - "continue=CONTINUE\n" + - "installing=INSTALLING%S\n" + - "installerror=INSTALLERROR\n" + - "loading=LOADING" + - ""+ -""; - -function handleRequest(request, response) { - - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/xml", false); - - response.write(""); - response.write(""); - - let locales = []; - let query = decodeURIComponent(request.queryString || "").split("="); - switch(query[0]) { - case "numvalid": - let numValid = parseInt(query[1]); - for (let i = 0; i < numValid; i++) { - locales.push( getLocale({IDNUMBER: i}) ); - } - break; - case "buildid": - locales.push( getLocale({IDNUMBER: 1, NAME: query[1]}) ); - break; - default : - locales.push( getLocale({IDNUMBER: 1}) ); - /* These locales should fail in the LocaleRepository */ - locales.push( getLocale({IDNUMBER: 1}) ); // no duplicate ids - locales.push( getLocale({IDNUMBER: 2, INSTALL: "INVALID_URL"}) ); - locales.push( getLocale({IDNUMBER: 3}, {APPID: "INVALID_ID"}) ); - locales.push( getLocale({IDNUMBER: 3}, {MAXVERSION: "0"}) ); - locales.push( getLocale({IDNUMBER: 4, TARGETLOCALE: ""}) ); - locales.push( getLocale({IDNUMBER: 5, NAME: ""}) ); - locales.push( getLocale({IDNUMBER: 6, VERSION: ""}) ); - locales.push( getLocale({IDNUMBER: 7, TYPENUMBER: ""}) ); - break; - } - - for(var i = 0; i < locales.length; i++) { - let t = template; - t = t.replace(/{TARGETLOCALE}/g, locales[i].TARGETLOCALE); - t = t.replace(/{NAME}/, locales[i].NAME); - t = t.replace(/{VERSION}/, locales[i].VERSION); - t = t.replace(/{INSTALL}/, locales[i].INSTALL); - t = t.replace(/{TYPENUMBER}/, locales[i].TYPENUMBER); - t = t.replace(/{TYPENAME}/, locales[i].TYPENAME); - t = t.replace(/{IDNUMBER}/g, locales[i].IDNUMBER) - - let a = appTemplate; - a = a.replace(/{APPNAME}/, locales[i].app.APPNAME); - a = a.replace(/{MINVERSION}/, locales[i].app.MINVERSION); - a = a.replace(/{MAXVERSION}/, locales[i].app.MAXVERSION); - a = a.replace(/{APPID}/, locales[i].app.APPID); - - t = t.replace(/{APPS}/, a); - response.write(t); - } - - response.write(""); -} diff --git a/mobile/android/chrome/tests/mock_autocomplete.json b/mobile/android/chrome/tests/mock_autocomplete.json deleted file mode 100644 index ef5e43d6fa55..000000000000 --- a/mobile/android/chrome/tests/mock_autocomplete.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "version": 1, - "result": { - "searchResult": 4, - "RESULT_NOMATCH_ONGOING": 5, - "RESULT_SUCCESS_ONGOING": 6, - "searchString": "", - "defaultIndex": 0, - "errorDescription": "", - "matchCount": 5, - "RESULT_IGNORED": 1, - "RESULT_FAILURE": 2, - "RESULT_NOMATCH": 3, - "RESULT_SUCCESS": 4, - "data": [["http://example.com/a", "A", "favicon", "http://example.com/a/favicon.png"], - ["http://example.com/b", "B", "favicon", "http://example.com/b/favicon.png"], - ["http://example.com/c", "C", "favicon", "http://example.com/c/favicon.png"], - ["http://example.com/d", "D", "bookmark", "http://example.com/d/favicon.png"], - ["http://example.com/e", "E", "boolmark", "http://example.com/e/favicon.png"] - ] - } -} diff --git a/mobile/android/chrome/tests/remote_autocomplete.js b/mobile/android/chrome/tests/remote_autocomplete.js deleted file mode 100644 index 991671aa6ef4..000000000000 --- a/mobile/android/chrome/tests/remote_autocomplete.js +++ /dev/null @@ -1,22 +0,0 @@ -dump("====================== Content Script Loaded =======================\n"); - -let assistant = Content.formAssistant; - -AsyncTests.add("TestRemoteAutocomplete:Click", function(aMessage, aJson) { - let element = content.document.getElementById(aJson.id); - assistant.open(element); - return true; -}); - -AsyncTests.add("TestRemoteAutocomplete:Check", function(aMessage, aJson) { - let element = content.document.getElementById(aJson.id); - return element.value; -}); - -AsyncTests.add("TestRemoteAutocomplete:Reset", function(aMessage, aJson) { - gFocusManager.focusedElement = null; - let element = content.document.getElementById(aJson.id); - element.value = ""; - return true; -}); - diff --git a/mobile/android/chrome/tests/remote_contentpopup.js b/mobile/android/chrome/tests/remote_contentpopup.js deleted file mode 100644 index f2156d700c5d..000000000000 --- a/mobile/android/chrome/tests/remote_contentpopup.js +++ /dev/null @@ -1,18 +0,0 @@ -dump("====================== Content Script Loaded =======================\n"); - -let assistant = Content.formAssistant; - -AsyncTests.add("TestRemoteAutocomplete:Click", function(aMessage, aJson) { - let element = content.document.getElementById(aJson.id); - assistant.open(element); - assistant._executeDelayed(function(assistant) { - sendAsyncMessage("FormAssist:AutoComplete", assistant._getJSON()); - }); - return true; -}); - -AsyncTests.add("TestRemoteAutocomplete:Check", function(aMessage, aJson) { - let element = content.document.getElementById(aJson.id); - return element.value; -}); - diff --git a/mobile/android/chrome/tests/remote_focus.js b/mobile/android/chrome/tests/remote_focus.js deleted file mode 100644 index d3c4544c2715..000000000000 --- a/mobile/android/chrome/tests/remote_focus.js +++ /dev/null @@ -1,16 +0,0 @@ -function focusReceived() { - sendAsyncMessage("Test:E10SFocusReceived"); -} - -function blurReceived() { - sendAsyncMessage("Test:E10SBlurReceived"); -} - -addEventListener("focus", focusReceived, true); -addEventListener("blur", blurReceived, true); - -addMessageListener("Test:E10SFocusTestFinished", function testFinished() { - removeEventListener("focus", focusReceived, true); - removeEventListener("blur", blurReceived, true); - removeMessageListener("Test:E10SFocusTestFinished", testFinished); -}); diff --git a/mobile/android/chrome/tests/remote_forms.js b/mobile/android/chrome/tests/remote_forms.js deleted file mode 100644 index 36779f5ae150..000000000000 --- a/mobile/android/chrome/tests/remote_forms.js +++ /dev/null @@ -1,171 +0,0 @@ -dump("====================== Content Script Loaded =======================\n"); - -let assistant = Content.formAssistant; - -// Copied from http://mxr.mozilla.org/mozilla-central/source/testing/mochitest/tests/SimpleTest/EventUtils.js -// except the netscape.security.PrivilegeManager.enablePrivilege call -function sendMouseEvent(aEvent, aTarget, aWindow) { - if (['click', 'mousedown', 'mouseup', 'mouseover', 'mouseout'].indexOf(aEvent.type) == -1) { - throw new Error("sendMouseEvent doesn't know about event type '" + aEvent.type + "'"); - } - - if (!aWindow) { - aWindow = window; - } - - if (!(aTarget instanceof Element)) { - aTarget = aWindow.document.getElementById(aTarget); - } - - let event = aWindow.document.createEvent('MouseEvent'); - - let typeArg = aEvent.type; - let canBubbleArg = true; - let cancelableArg = true; - let viewArg = aWindow; - let detailArg = aEvent.detail || (aEvent.type == 'click' || - aEvent.type == 'mousedown' || - aEvent.type == 'mouseup' ? 1 : 0); - let screenXArg = aEvent.screenX || 0; - let screenYArg = aEvent.screenY || 0; - let clientXArg = aEvent.clientX || 0; - let clientYArg = aEvent.clientY || 0; - let ctrlKeyArg = aEvent.ctrlKey || false; - let altKeyArg = aEvent.altKey || false; - let shiftKeyArg = aEvent.shiftKey || false; - let metaKeyArg = aEvent.metaKey || false; - let buttonArg = aEvent.button || 0; - let relatedTargetArg = aEvent.relatedTarget || null; - - event.initMouseEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg, - screenXArg, screenYArg, clientXArg, clientYArg, - ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, - buttonArg, relatedTargetArg); - - aTarget.dispatchEvent(event); -} - -AsyncTests.add("Test:Click", function(aMessage, aJson) { - sendMouseEvent({type: "click"}, "root", content); - return assistant._open; -}); - -AsyncTests.add("Test:Focus", function(aMessage, aJson) { - let targetElement = content.document.querySelector(aJson.value); - targetElement.focus(); - assistant._executeDelayed(function() { - sendAsyncMessage(aMessage, { result: assistant._open }); - }); -}); - -AsyncTests.add("Test:FocusRedirect", function(aMessage, aJson) { - let element = content.document.querySelector(aJson.value); - element.addEventListener("focus", function(aEvent) { - element.removeEventListener("focus", arguments.callee, false); - content.document.getElementById("root").focus(); - }, false); - element.focus(); - - assistant._executeDelayed(function() { - sendAsyncMessage(aMessage, { result: assistant._open }); - }); -}); - -// It should be only 2 ways to open the FormAssistant, the first one is -// by manually synchronizing the focus to the form helper and the other -// one is by a user click on an authorized element -AsyncTests.add("Test:OpenUIWithSyncFocus", function(aMessage, aJson) { - let element = content.document.querySelector(aJson.value); - - assistant._open = false; - assitant.focusSync = true; - element.focus(); - assistant._executeDelayed(function() { - assistant.focusSync = false; - sendAsyncMessage(aMessage, { result: assistant._open }); - }); -}); - -AsyncTests.add("Test:Open", function(aMessage, aJson) { - let element = content.document.querySelector(aJson.value); - assistant._open = false; - return assistant.open(element); -}); - -AsyncTests.add("Test:OpenWithFocusRedirect", function(aMessage, aJson) { - let element = content.document.querySelector(aJson.value); - assistant._open = false; - assistant.focusSync = true; - assistant.open(element); - assistant._executeDelayed(function() { - assistant.focusSync = false; - sendAsyncMessage(aMessage, { result: assistant._open }); - }); -}); - -AsyncTests.add("Test:CanShowUI", function(aMessage, aJson) { - let element = content.document.querySelector(aJson.value); - element.disabled = aJson.disabled; - assistant._open = false; - let open = assistant.open(element); - element.disabled = false; - return open; -}); - -AsyncTests.add("Test:CanShowUISelect", function(aMessage, aJson) { - let select = content.document.getElementById("select"); - select.disabled = aJson.disabled; - - let element = content.document.querySelector(aJson.value); - assistant._open = false; - let open = assistant.open(element); - select.disabled = false; - return open; -}); - -AsyncTests.add("Test:Previous", function(aMessage, aJson) { - let targetElement = content.document.querySelector(aJson.value); - assistant.currentIndex--; - return (assistant.currentElement == targetElement); -}); - -AsyncTests.add("Test:Next", function(aMessage, aJson) { - let targetElement = content.document.querySelector(aJson.value); - assistant.currentIndex++; - return (assistant.currentElement == targetElement); -}); - -// ============= iframe navigation ================== -let iframe = null; -let iframeInputs = null; -AsyncTests.add("Test:Iframe", function(aMessage, aJson) { - iframe = content.document.createElement("iframe"); - iframe.setAttribute("src", "data:text/html;charset=utf-8,%3Ciframe%20src%3D%22data%3Atext/html%3Bcharset%3Dutf-8%2C%253Cinput%253E%253Cbr%253E%253Cinput%253E%250A%22%3E%3C/iframe%3E"); - iframe.setAttribute("width", "300"); - iframe.setAttribute("height", "100"); - - iframe.addEventListener("load", function() { - iframe.removeEventListener("load", arguments.callee, false); - iframeInputs = iframe.contentDocument - .querySelector("iframe").contentDocument - .getElementsByTagName("input"); - sendAsyncMessage(aMessage, { result: true }); - }, false); - - content.document.body.appendChild(iframe); -}); - -AsyncTests.add("Test:IframeOpen", function(aMessage, aJson) { - return assistant.open(iframeInputs[0]); -}); - -AsyncTests.add("Test:IframePrevious", function(aMessage, aJson) { - assistant.currentIndex--; - return (assistant.currentElement == iframeInputs[aJson.value]); -}); - -AsyncTests.add("Test:IframeNext", function(aMessage, aJson) { - assistant.currentIndex++; - return (assistant.currentElement == iframeInputs[aJson.value]); -}); - diff --git a/mobile/android/chrome/tests/remote_formsZoom.js b/mobile/android/chrome/tests/remote_formsZoom.js deleted file mode 100644 index 74cffac37d9c..000000000000 --- a/mobile/android/chrome/tests/remote_formsZoom.js +++ /dev/null @@ -1,9 +0,0 @@ -dump("====================== Content Script Loaded =======================\n"); - -let assistant = Content.formAssistant; - -AsyncTests.add("FormAssist:Show", function(aMessage, aJson) { - let element = content.document.getElementById(aJson.id); - assistant.open(element); -}); - diff --git a/mobile/android/chrome/tests/remote_head.js b/mobile/android/chrome/tests/remote_head.js deleted file mode 100644 index 157d2e7b8252..000000000000 --- a/mobile/android/chrome/tests/remote_head.js +++ /dev/null @@ -1,35 +0,0 @@ -// XXX Those constants are here because EventUtils.js need them -window = content.document.defaultView.wrappedJSObject; -Element = Components.interfaces.nsIDOMElement; -netscape = window.netscape; - -let AsyncTests = { - _tests: [], - - add: function(aMessage, aCallback) { - addMessageListener(aMessage, this); - this._tests.push({ name: aMessage, callback: aCallback }); - }, - - receiveMessage: function(aMessage) { - let rv = { }; - let name = aMessage.name; - try { - let tests = this._tests; - for (let i = 0; i < tests.length; i++) { - if (tests[i].name == name) { - rv.result = tests[i].callback(name, aMessage.json); - break; - } - } - // Don't send test callback if rv.result == undefined, this allow to - // use a custom callback - if (rv.result != undefined) - sendAsyncMessage(name, rv); - } - catch(e) { - dump("receiveMessage: " + name + " - " + e + "\n"); - } - } -}; - diff --git a/mobile/android/chrome/tests/remote_vkb.js b/mobile/android/chrome/tests/remote_vkb.js deleted file mode 100644 index eb6b8283afc6..000000000000 --- a/mobile/android/chrome/tests/remote_vkb.js +++ /dev/null @@ -1,6 +0,0 @@ -dump("====================== Content Script Loaded =======================\n"); - -AsyncTests.add("Test:FocusRoot", function(aMessage, aJson) { - content.document.getElementById("root").focus(); - return true; -}); diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh index 1de42e51365e..0709cf005d98 100644 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -38,7 +38,7 @@ MOZ_APP_BASENAME=Fennec MOZ_APP_VENDOR=Mozilla -MOZ_APP_VERSION=13.0a1 +MOZ_APP_VERSION=14.0a1 MOZ_APP_UA_NAME=Firefox MOZ_BRANDING_DIRECTORY=mobile/android/branding/unofficial diff --git a/mobile/android/makefiles.sh b/mobile/android/makefiles.sh index 1e27c17a1960..30578d80bf9d 100644 --- a/mobile/android/makefiles.sh +++ b/mobile/android/makefiles.sh @@ -58,9 +58,3 @@ if [ ! "$LIBXUL_SDK" ]; then mobile/android/components/build/Makefile " fi - -if [ "$ENABLE_TESTS" ]; then - add_makefiles " - mobile/android/chrome/tests/Makefile - " -fi diff --git a/mobile/android/sync/java-sources.mn b/mobile/android/sync/java-sources.mn index f4c2e943b26f..95b0ad3737ea 100644 --- a/mobile/android/sync/java-sources.mn +++ b/mobile/android/sync/java-sources.mn @@ -1 +1 @@ -sync/AlreadySyncingException.java sync/CollectionKeys.java sync/CredentialsSource.java sync/crypto/CryptoException.java sync/crypto/CryptoInfo.java sync/crypto/HKDF.java sync/crypto/HMACVerificationException.java sync/crypto/KeyBundle.java sync/crypto/MissingCryptoInputException.java sync/crypto/NoKeyBundleException.java sync/CryptoRecord.java sync/DelayedWorkTracker.java sync/delegates/ClientsDataDelegate.java sync/delegates/FreshStartDelegate.java sync/delegates/GlobalSessionCallback.java sync/delegates/InfoCollectionsDelegate.java sync/delegates/KeyUploadDelegate.java sync/delegates/MetaGlobalDelegate.java sync/delegates/WipeServerDelegate.java sync/ExtendedJSONObject.java sync/GlobalSession.java sync/HTTPFailureException.java sync/InfoCollections.java sync/jpake/BigIntegerHelper.java sync/jpake/Gx3OrGx4IsZeroOrOneException.java sync/jpake/IncorrectZkpException.java sync/jpake/JPakeClient.java sync/jpake/JPakeCrypto.java sync/jpake/JPakeJson.java sync/jpake/JPakeNoActivePairingException.java sync/jpake/JPakeNumGenerator.java sync/jpake/JPakeNumGeneratorRandom.java sync/jpake/JPakeParty.java sync/jpake/JPakeRequest.java sync/jpake/JPakeRequestDelegate.java sync/jpake/JPakeResponse.java sync/jpake/stage/CompleteStage.java sync/jpake/stage/ComputeFinalStage.java sync/jpake/stage/ComputeKeyVerificationStage.java sync/jpake/stage/ComputeStepOneStage.java sync/jpake/stage/ComputeStepTwoStage.java sync/jpake/stage/DecryptDataStage.java sync/jpake/stage/GetChannelStage.java sync/jpake/stage/GetRequestStage.java sync/jpake/stage/JPakeStage.java sync/jpake/stage/PutRequestStage.java sync/jpake/stage/VerifyPairingStage.java sync/jpake/Zkp.java sync/KeyBundleProvider.java sync/Logger.java sync/MetaGlobal.java sync/MetaGlobalException.java sync/MetaGlobalMissingEnginesException.java sync/MetaGlobalNotSetException.java sync/middleware/Crypto5MiddlewareRepository.java sync/middleware/Crypto5MiddlewareRepositorySession.java sync/middleware/MiddlewareRepository.java sync/middleware/MiddlewareRepositorySession.java sync/net/BaseResource.java sync/net/CompletedEntity.java sync/net/HandleProgressException.java sync/net/Resource.java sync/net/ResourceDelegate.java sync/net/SyncResourceDelegate.java sync/net/SyncResponse.java sync/net/SyncStorageCollectionRequest.java sync/net/SyncStorageCollectionRequestDelegate.java sync/net/SyncStorageRecordRequest.java sync/net/SyncStorageRequest.java sync/net/SyncStorageRequestDelegate.java sync/net/SyncStorageRequestIncrementalDelegate.java sync/net/SyncStorageResponse.java sync/net/TLSSocketFactory.java sync/net/WBOCollectionRequestDelegate.java sync/net/WBORequestDelegate.java sync/NoCollectionKeysSetException.java sync/NodeAuthenticationException.java sync/NonArrayJSONException.java sync/NonObjectJSONException.java sync/NullClusterURLException.java sync/PrefsSource.java sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java sync/repositories/android/AndroidBrowserBookmarksRepository.java sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java sync/repositories/android/AndroidBrowserHistoryDataAccessor.java sync/repositories/android/AndroidBrowserHistoryDataExtender.java sync/repositories/android/AndroidBrowserHistoryRepository.java sync/repositories/android/AndroidBrowserHistoryRepositorySession.java sync/repositories/android/AndroidBrowserPasswordsDataAccessor.java sync/repositories/android/AndroidBrowserPasswordsRepository.java sync/repositories/android/AndroidBrowserPasswordsRepositorySession.java sync/repositories/android/AndroidBrowserRepository.java sync/repositories/android/AndroidBrowserRepositoryDataAccessor.java sync/repositories/android/AndroidBrowserRepositorySession.java sync/repositories/android/BrowserContractHelpers.java sync/repositories/android/CachedSQLiteOpenHelper.java sync/repositories/android/ClientsDatabase.java sync/repositories/android/ClientsDatabaseAccessor.java sync/repositories/android/FennecTabsRepository.java sync/repositories/android/PasswordColumns.java sync/repositories/android/RepoUtils.java sync/repositories/BookmarkNeedsReparentingException.java sync/repositories/BookmarksRepository.java sync/repositories/ConstrainedServer11Repository.java sync/repositories/delegates/DeferrableRepositorySessionCreationDelegate.java sync/repositories/delegates/DeferredRepositorySessionBeginDelegate.java sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java sync/repositories/delegates/DeferredRepositorySessionFinishDelegate.java sync/repositories/delegates/DeferredRepositorySessionStoreDelegate.java sync/repositories/delegates/RepositorySessionBeginDelegate.java sync/repositories/delegates/RepositorySessionCleanDelegate.java sync/repositories/delegates/RepositorySessionCreationDelegate.java sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java sync/repositories/delegates/RepositorySessionFinishDelegate.java sync/repositories/delegates/RepositorySessionGuidsSinceDelegate.java sync/repositories/delegates/RepositorySessionStoreDelegate.java sync/repositories/delegates/RepositorySessionWipeDelegate.java sync/repositories/domain/BookmarkRecord.java sync/repositories/domain/BookmarkRecordFactory.java sync/repositories/domain/ClientRecord.java sync/repositories/domain/ClientRecordFactory.java sync/repositories/domain/HistoryRecord.java sync/repositories/domain/HistoryRecordFactory.java sync/repositories/domain/PasswordRecord.java sync/repositories/domain/Record.java sync/repositories/domain/TabsRecord.java sync/repositories/HashSetStoreTracker.java sync/repositories/HistoryRepository.java sync/repositories/IdentityRecordFactory.java sync/repositories/InactiveSessionException.java sync/repositories/InvalidBookmarkTypeException.java sync/repositories/InvalidRequestException.java sync/repositories/InvalidSessionTransitionException.java sync/repositories/MultipleRecordsForGuidException.java sync/repositories/NoContentProviderException.java sync/repositories/NoGuidForIdException.java sync/repositories/NoStoreDelegateException.java sync/repositories/NullCursorException.java sync/repositories/ParentNotFoundException.java sync/repositories/ProfileDatabaseException.java sync/repositories/RecordFactory.java sync/repositories/RecordFilter.java sync/repositories/Repository.java sync/repositories/RepositorySession.java sync/repositories/RepositorySessionBundle.java sync/repositories/Server11Repository.java sync/repositories/Server11RepositorySession.java sync/repositories/StoreTracker.java sync/repositories/StoreTrackingRepositorySession.java sync/setup/activities/AccountActivity.java sync/setup/activities/SetupFailureActivity.java sync/setup/activities/SetupSuccessActivity.java sync/setup/activities/SetupSyncActivity.java sync/setup/Constants.java sync/setup/SyncAuthenticatorService.java sync/stage/AndroidBrowserBookmarksServerSyncStage.java sync/stage/AndroidBrowserHistoryServerSyncStage.java sync/stage/CheckPreconditionsStage.java sync/stage/CompletedStage.java sync/stage/EnsureClusterURLStage.java sync/stage/EnsureKeysStage.java sync/stage/FennecTabsServerSyncStage.java sync/stage/FetchInfoCollectionsStage.java sync/stage/FetchMetaGlobalStage.java sync/stage/GlobalSyncStage.java sync/stage/NoSuchStageException.java sync/stage/NoSyncIDException.java sync/stage/ServerSyncStage.java sync/stage/SyncClientsEngineStage.java sync/StubActivity.java sync/syncadapter/SyncAdapter.java sync/syncadapter/SyncService.java sync/SyncConfiguration.java sync/SyncConfigurationException.java sync/SyncException.java sync/synchronizer/ConcurrentRecordConsumer.java sync/synchronizer/RecordConsumer.java sync/synchronizer/RecordsChannel.java sync/synchronizer/RecordsChannelDelegate.java sync/synchronizer/RecordsConsumerDelegate.java sync/synchronizer/SerialRecordConsumer.java sync/synchronizer/SessionNotBegunException.java sync/synchronizer/Synchronizer.java sync/synchronizer/SynchronizerDelegate.java sync/synchronizer/SynchronizerSession.java sync/synchronizer/SynchronizerSessionDelegate.java sync/synchronizer/UnbundleError.java sync/synchronizer/UnexpectedSessionException.java sync/SynchronizerConfiguration.java sync/SynchronizerConfigurations.java sync/ThreadPool.java sync/UnexpectedJSONException.java sync/UnknownSynchronizerConfigurationVersionException.java sync/Utils.java +sync/AlreadySyncingException.java sync/CollectionKeys.java sync/CredentialsSource.java sync/crypto/CryptoException.java sync/crypto/CryptoInfo.java sync/crypto/HKDF.java sync/crypto/HMACVerificationException.java sync/crypto/KeyBundle.java sync/crypto/MissingCryptoInputException.java sync/crypto/NoKeyBundleException.java sync/CryptoRecord.java sync/DelayedWorkTracker.java sync/delegates/ClientsDataDelegate.java sync/delegates/FreshStartDelegate.java sync/delegates/GlobalSessionCallback.java sync/delegates/InfoCollectionsDelegate.java sync/delegates/KeyUploadDelegate.java sync/delegates/MetaGlobalDelegate.java sync/delegates/WipeServerDelegate.java sync/ExtendedJSONObject.java sync/GlobalSession.java sync/HTTPFailureException.java sync/InfoCollections.java sync/jpake/BigIntegerHelper.java sync/jpake/Gx3OrGx4IsZeroOrOneException.java sync/jpake/IncorrectZkpException.java sync/jpake/JPakeClient.java sync/jpake/JPakeCrypto.java sync/jpake/JPakeJson.java sync/jpake/JPakeNoActivePairingException.java sync/jpake/JPakeNumGenerator.java sync/jpake/JPakeNumGeneratorRandom.java sync/jpake/JPakeParty.java sync/jpake/JPakeRequest.java sync/jpake/JPakeRequestDelegate.java sync/jpake/JPakeResponse.java sync/jpake/stage/CompleteStage.java sync/jpake/stage/ComputeFinalStage.java sync/jpake/stage/ComputeKeyVerificationStage.java sync/jpake/stage/ComputeStepOneStage.java sync/jpake/stage/ComputeStepTwoStage.java sync/jpake/stage/DecryptDataStage.java sync/jpake/stage/GetChannelStage.java sync/jpake/stage/GetRequestStage.java sync/jpake/stage/JPakeStage.java sync/jpake/stage/PutRequestStage.java sync/jpake/stage/VerifyPairingStage.java sync/jpake/Zkp.java sync/KeyBundleProvider.java sync/Logger.java sync/MetaGlobal.java sync/MetaGlobalException.java sync/MetaGlobalMissingEnginesException.java sync/MetaGlobalNotSetException.java sync/middleware/Crypto5MiddlewareRepository.java sync/middleware/Crypto5MiddlewareRepositorySession.java sync/middleware/MiddlewareRepository.java sync/middleware/MiddlewareRepositorySession.java sync/net/BaseResource.java sync/net/CompletedEntity.java sync/net/HandleProgressException.java sync/net/Resource.java sync/net/ResourceDelegate.java sync/net/SyncResourceDelegate.java sync/net/SyncResponse.java sync/net/SyncStorageCollectionRequest.java sync/net/SyncStorageCollectionRequestDelegate.java sync/net/SyncStorageRecordRequest.java sync/net/SyncStorageRequest.java sync/net/SyncStorageRequestDelegate.java sync/net/SyncStorageRequestIncrementalDelegate.java sync/net/SyncStorageResponse.java sync/net/TLSSocketFactory.java sync/net/WBOCollectionRequestDelegate.java sync/net/WBORequestDelegate.java sync/NoCollectionKeysSetException.java sync/NodeAuthenticationException.java sync/NonArrayJSONException.java sync/NonObjectJSONException.java sync/NullClusterURLException.java sync/PrefsSource.java sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java sync/repositories/android/AndroidBrowserBookmarksRepository.java sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java sync/repositories/android/AndroidBrowserHistoryDataAccessor.java sync/repositories/android/AndroidBrowserHistoryDataExtender.java sync/repositories/android/AndroidBrowserHistoryRepository.java sync/repositories/android/AndroidBrowserHistoryRepositorySession.java sync/repositories/android/AndroidBrowserPasswordsDataAccessor.java sync/repositories/android/AndroidBrowserPasswordsRepository.java sync/repositories/android/AndroidBrowserPasswordsRepositorySession.java sync/repositories/android/AndroidBrowserRepository.java sync/repositories/android/AndroidBrowserRepositoryDataAccessor.java sync/repositories/android/AndroidBrowserRepositorySession.java sync/repositories/android/BrowserContractHelpers.java sync/repositories/android/CachedSQLiteOpenHelper.java sync/repositories/android/ClientsDatabase.java sync/repositories/android/ClientsDatabaseAccessor.java sync/repositories/android/FennecTabsRepository.java sync/repositories/android/PasswordColumns.java sync/repositories/android/RepoUtils.java sync/repositories/BookmarkNeedsReparentingException.java sync/repositories/BookmarksRepository.java sync/repositories/ConstrainedServer11Repository.java sync/repositories/delegates/DeferrableRepositorySessionCreationDelegate.java sync/repositories/delegates/DeferredRepositorySessionBeginDelegate.java sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java sync/repositories/delegates/DeferredRepositorySessionFinishDelegate.java sync/repositories/delegates/DeferredRepositorySessionStoreDelegate.java sync/repositories/delegates/RepositorySessionBeginDelegate.java sync/repositories/delegates/RepositorySessionCleanDelegate.java sync/repositories/delegates/RepositorySessionCreationDelegate.java sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java sync/repositories/delegates/RepositorySessionFinishDelegate.java sync/repositories/delegates/RepositorySessionGuidsSinceDelegate.java sync/repositories/delegates/RepositorySessionStoreDelegate.java sync/repositories/delegates/RepositorySessionWipeDelegate.java sync/repositories/domain/BookmarkRecord.java sync/repositories/domain/BookmarkRecordFactory.java sync/repositories/domain/ClientRecord.java sync/repositories/domain/ClientRecordFactory.java sync/repositories/domain/HistoryRecord.java sync/repositories/domain/HistoryRecordFactory.java sync/repositories/domain/PasswordRecord.java sync/repositories/domain/Record.java sync/repositories/domain/TabsRecord.java sync/repositories/HashSetStoreTracker.java sync/repositories/HistoryRepository.java sync/repositories/IdentityRecordFactory.java sync/repositories/InactiveSessionException.java sync/repositories/InvalidBookmarkTypeException.java sync/repositories/InvalidRequestException.java sync/repositories/InvalidSessionTransitionException.java sync/repositories/MultipleRecordsForGuidException.java sync/repositories/NoContentProviderException.java sync/repositories/NoGuidForIdException.java sync/repositories/NoStoreDelegateException.java sync/repositories/NullCursorException.java sync/repositories/ParentNotFoundException.java sync/repositories/ProfileDatabaseException.java sync/repositories/RecordFactory.java sync/repositories/RecordFilter.java sync/repositories/Repository.java sync/repositories/RepositorySession.java sync/repositories/RepositorySessionBundle.java sync/repositories/Server11Repository.java sync/repositories/Server11RepositorySession.java sync/repositories/StoreTracker.java sync/repositories/StoreTrackingRepositorySession.java sync/setup/activities/AccountActivity.java sync/setup/activities/SetupFailureActivity.java sync/setup/activities/SetupSuccessActivity.java sync/setup/activities/SetupSyncActivity.java sync/setup/Constants.java sync/setup/SyncAccounts.java sync/setup/SyncAuthenticatorService.java sync/stage/AndroidBrowserBookmarksServerSyncStage.java sync/stage/AndroidBrowserHistoryServerSyncStage.java sync/stage/CheckPreconditionsStage.java sync/stage/CompletedStage.java sync/stage/EnsureClusterURLStage.java sync/stage/EnsureKeysStage.java sync/stage/FennecTabsServerSyncStage.java sync/stage/FetchInfoCollectionsStage.java sync/stage/FetchMetaGlobalStage.java sync/stage/GlobalSyncStage.java sync/stage/NoSuchStageException.java sync/stage/NoSyncIDException.java sync/stage/ServerSyncStage.java sync/stage/SyncClientsEngineStage.java sync/StubActivity.java sync/syncadapter/SyncAdapter.java sync/syncadapter/SyncService.java sync/SyncConfiguration.java sync/SyncConfigurationException.java sync/SyncException.java sync/synchronizer/ConcurrentRecordConsumer.java sync/synchronizer/RecordConsumer.java sync/synchronizer/RecordsChannel.java sync/synchronizer/RecordsChannelDelegate.java sync/synchronizer/RecordsConsumerDelegate.java sync/synchronizer/SerialRecordConsumer.java sync/synchronizer/SessionNotBegunException.java sync/synchronizer/Synchronizer.java sync/synchronizer/SynchronizerDelegate.java sync/synchronizer/SynchronizerSession.java sync/synchronizer/SynchronizerSessionDelegate.java sync/synchronizer/UnbundleError.java sync/synchronizer/UnexpectedSessionException.java sync/SynchronizerConfiguration.java sync/SynchronizerConfigurations.java sync/ThreadPool.java sync/UnexpectedJSONException.java sync/UnknownSynchronizerConfigurationVersionException.java sync/Utils.java diff --git a/mobile/android/themes/core/aboutAddons.css b/mobile/android/themes/core/aboutAddons.css index efa774d99f14..c0833cbb1798 100644 --- a/mobile/android/themes/core/aboutAddons.css +++ b/mobile/android/themes/core/aboutAddons.css @@ -79,13 +79,6 @@ body { color: #999999; } -.addon-item:not([optionsURL]) .options-header, -.addon-item[optionsURL=""] .options-header, -.addon-item:not([optionsURL]) .options-box, -.addon-item[optionsURL=""] .options-box { - display: none; -} - .inner { background-image: url("chrome://browser/skin/images/row-bg-light.png"); min-height: 70px; @@ -176,3 +169,135 @@ body[dir="ltr"] .favicon { .addon-item[isDisabled="true"] .favicon { opacity: 0.3; } + +.options-header { + font-weight: bold; + padding: 18px 24px; +} + +.options-box { + margin: 0 12px; +} + +.addon-item:not([optionsURL]) .options-header, +.addon-item[optionsURL=""] .options-header, +.addon-item:not([optionsURL]) .options-box, +.addon-item[optionsURL=""] .options-box { + display: none; +} + +setting { + padding: 18px 12px; + border-top: 2px solid; + -moz-border-top-colors: #bac2ac #ffffff; + -moz-box-align: center; + -moz-box-sizing: border-box; + width: 100%; +} + +setting > vbox { + -moz-box-flex: 1; +} + +.preferences-title { + font-weight: bold; +} + +.preferences-description:empty { + display: none; +} + +/* Put setting textboxes on a separate row */ +setting[type="integer"], +setting[type="string"] { + -moz-box-align: stretch; + -moz-box-orient: vertical; +} + +.preferences-alignment > textbox { + margin-top: 12px; + font-size: 22px !important; +} + +checkbox { + -moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox-with-spacing") !important; +} + +.checkbox-check { + border: 2px transparent; + -moz-border-top-colors: -moz-initial; + -moz-border-right-colors: -moz-initial; + -moz-border-bottom-colors: -moz-initial; + -moz-border-left-colors: -moz-initial; + -moz-box-sizing: border-box; + width: 48px; + height: 48px; + background: url("chrome://browser/skin/images/checkbox_unchecked.png") no-repeat 50% 50%; +} + +setting:active checkbox > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/checkbox_unchecked_pressed.png"); +} + +checkbox[disabled="true"] > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/checkbox_unchecked_disabled.png"); +} + +checkbox[checked="true"] > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/checkbox_checked.png"); +} + +setting:active checkbox[checked="true"] > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/checkbox_checked_pressed.png"); +} + +checkbox[checked="true"][disabled="true"] > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/checkbox_checked_disabled.png"); +} + + +/* XBL bindings */ + +settings { + -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings"); +} + +setting { + display: none; +} + +setting[type="bool"] { + display: -moz-box; + -moz-binding: url("chrome://browser/content/bindings/settings.xml#setting-fulltoggle-bool"); +} + +setting[type="bool"][localized="true"] { + display: -moz-box; + -moz-binding: url("chrome://browser/content/bindings/settings.xml#setting-fulltoggle-localized-bool"); +} + +setting[type="boolint"] { + display: -moz-box; + -moz-binding: url("chrome://browser/content/bindings/settings.xml#setting-fulltoggle-boolint"); +} + +setting[type="integer"] { + display: -moz-box; + -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-integer"); +} + +setting[type="control"] { + display: -moz-box; + -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-control"); +} + +setting[type="string"] { + display: -moz-box; + -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-string"); +} + +setting[type="radio"], +setting[type="menulist"] { + display: -moz-box; + -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-multi"); +} diff --git a/mobile/android/themes/core/images/checkbox_checked.png b/mobile/android/themes/core/images/checkbox_checked.png new file mode 100644 index 000000000000..e87e6146b04b Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_checked.png differ diff --git a/mobile/android/themes/core/images/checkbox_checked_disabled.png b/mobile/android/themes/core/images/checkbox_checked_disabled.png new file mode 100644 index 000000000000..62843d9c81e7 Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_checked_disabled.png differ diff --git a/mobile/android/themes/core/images/checkbox_checked_pressed.png b/mobile/android/themes/core/images/checkbox_checked_pressed.png new file mode 100644 index 000000000000..688a8282ef31 Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_checked_pressed.png differ diff --git a/mobile/android/themes/core/images/checkbox_unchecked.png b/mobile/android/themes/core/images/checkbox_unchecked.png new file mode 100644 index 000000000000..c34c4dff247d Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_unchecked.png differ diff --git a/mobile/android/themes/core/images/checkbox_unchecked_disabled.png b/mobile/android/themes/core/images/checkbox_unchecked_disabled.png new file mode 100644 index 000000000000..7c3990603057 Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_unchecked_disabled.png differ diff --git a/mobile/android/themes/core/images/checkbox_unchecked_pressed.png b/mobile/android/themes/core/images/checkbox_unchecked_pressed.png new file mode 100644 index 000000000000..bcbac43be0e7 Binary files /dev/null and b/mobile/android/themes/core/images/checkbox_unchecked_pressed.png differ diff --git a/mobile/android/themes/core/jar.mn b/mobile/android/themes/core/jar.mn index bd542193db0e..e8cac0857dfa 100644 --- a/mobile/android/themes/core/jar.mn +++ b/mobile/android/themes/core/jar.mn @@ -22,6 +22,12 @@ chrome.jar: skin/images/arrowleft-16.png (images/arrowleft-16.png) skin/images/arrowright-16.png (images/arrowright-16.png) skin/images/arrowdown-16.png (images/arrowdown-16.png) + skin/images/checkbox_checked.png (images/checkbox_checked.png) + skin/images/checkbox_checked_disabled.png (images/checkbox_checked_disabled.png) + skin/images/checkbox_checked_pressed.png (images/checkbox_checked_pressed.png) + skin/images/checkbox_unchecked.png (images/checkbox_unchecked.png) + skin/images/checkbox_unchecked_disabled.png (images/checkbox_unchecked_disabled.png) + skin/images/checkbox_unchecked_pressed.png (images/checkbox_unchecked_pressed.png) skin/images/dropmarker.svg (images/dropmarker.svg) skin/images/popup-selected-item-hdpi.png (images/popup-selected-item-hdpi.png) skin/images/errorpage-warning.png (images/errorpage-warning.png) @@ -69,6 +75,12 @@ chrome.jar: skin/gingerbread/images/arrowleft-16.png (gingerbread/images/arrowleft-16.png) skin/gingerbread/images/arrowright-16.png (gingerbread/images/arrowright-16.png) skin/gingerbread/images/arrowdown-16.png (gingerbread/images/arrowdown-16.png) + skin/gingerbread/images/checkbox_checked.png (images/checkbox_checked.png) + skin/gingerbread/images/checkbox_checked_disabled.png (images/checkbox_checked_disabled.png) + skin/gingerbread/images/checkbox_checked_pressed.png (images/checkbox_checked_pressed.png) + skin/gingerbread/images/checkbox_unchecked.png (images/checkbox_unchecked.png) + skin/gingerbread/images/checkbox_unchecked_disabled.png (images/checkbox_unchecked_disabled.png) + skin/gingerbread/images/checkbox_unchecked_pressed.png (images/checkbox_unchecked_pressed.png) skin/gingerbread/images/dropmarker.svg (images/dropmarker.svg) skin/gingerbread/images/popup-selected-item-hdpi.png (gingerbread/images/popup-selected-item-hdpi.png) skin/gingerbread/images/throbber.png (gingerbread/images/throbber.png) @@ -113,6 +125,12 @@ chrome.jar: skin/honeycomb/images/arrowleft-16.png (honeycomb/images/arrowleft-16.png) skin/honeycomb/images/arrowright-16.png (honeycomb/images/arrowright-16.png) skin/honeycomb/images/arrowdown-16.png (honeycomb/images/arrowdown-16.png) + skin/honeycomb/images/checkbox_checked.png (images/checkbox_checked.png) + skin/honeycomb/images/checkbox_checked_disabled.png (images/checkbox_checked_disabled.png) + skin/honeycomb/images/checkbox_checked_pressed.png (images/checkbox_checked_pressed.png) + skin/honeycomb/images/checkbox_unchecked.png (images/checkbox_unchecked.png) + skin/honeycomb/images/checkbox_unchecked_disabled.png (images/checkbox_unchecked_disabled.png) + skin/honeycomb/images/checkbox_unchecked_pressed.png (images/checkbox_unchecked_pressed.png) skin/honeycomb/images/dropmarker.svg (images/dropmarker.svg) skin/honeycomb/images/popup-selected-item-hdpi.png (honeycomb/images/popup-selected-item-hdpi.png) skin/honeycomb/images/throbber.png (honeycomb/images/throbber.png) diff --git a/mobile/xul/confvars.sh b/mobile/xul/confvars.sh index 53f1f3b3da29..84034c69d0ab 100644 --- a/mobile/xul/confvars.sh +++ b/mobile/xul/confvars.sh @@ -38,7 +38,7 @@ MOZ_APP_BASENAME=Fennec MOZ_APP_VENDOR=Mozilla -MOZ_APP_VERSION=13.0a1 +MOZ_APP_VERSION=14.0a1 MOZ_BRANDING_DIRECTORY=mobile/xul/branding/unofficial MOZ_OFFICIAL_BRANDING_DIRECTORY=mobile/xul/branding/official diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 9c82e6e77c47..68b47bce24a2 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -667,7 +667,7 @@ pref("javascript.options.typeinference", true); pref("javascript.options.mem.high_water_mark", 128); pref("javascript.options.mem.max", -1); pref("javascript.options.mem.gc_per_compartment", true); -pref("javascript.options.mem.gc_incremental", true); +pref("javascript.options.mem.gc_incremental", false); pref("javascript.options.mem.gc_incremental_slice_ms", 10); pref("javascript.options.mem.log", false); pref("javascript.options.gc_on_memory_pressure", true); diff --git a/mozglue/android/APKOpen.cpp b/mozglue/android/APKOpen.cpp index ba39c6861c14..f5e19df19059 100644 --- a/mozglue/android/APKOpen.cpp +++ b/mozglue/android/APKOpen.cpp @@ -729,7 +729,6 @@ static int loadSQLiteLibs(const char *apkName) static mozglueresult loadNSSLibs(const char *apkName) { - __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs"); chdir(getenv("GRE_HOME")); #ifdef MOZ_OLD_LINKER @@ -739,7 +738,7 @@ loadNSSLibs(const char *apkName) } #endif - Zip *zip = new Zip(apkName); + RefPtr zip = new Zip(apkName); if (!lib_mapping) { lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping)); } @@ -778,14 +777,11 @@ loadNSSLibs(const char *apkName) #undef MOZLOAD #endif - delete zip; - #ifdef MOZ_CRASHREPORTER free(file_ids); file_ids = NULL; #endif - __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs 2"); if (!nss_handle) { __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libnss3!"); return FAILURE; @@ -801,7 +797,6 @@ loadNSSLibs(const char *apkName) return FAILURE; } - __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "loadNSSLibs 3"); return setup_nss_functions(nss_handle, nspr_handle, plc_handle); } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index c0d2fff0fc52..ee901cce07f3 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -333,7 +333,9 @@ HttpChannelParent::RecvUpdateAssociatedContentSecurity(const PRInt32& high, // Bug 621446 investigation, we don't want conditional PR_Aborts bellow to be // merged to a single address. +#ifdef _MSC_VER #pragma warning(disable : 4068) +#endif #pragma GCC optimize ("O0") bool diff --git a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul index 27774929ce35..0b6ed554b50d 100644 --- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul @@ -44,7 +44,7 @@ let areJsCompartmentsPresent = false; let isSandboxLocationShown = false; - let areInnerWindowsPresent = false; + let areWindowObjectsPresent = false; let isPlacesPresent = false; let isImagesPresent = false; let isXptiWorkingSetPresent = false; @@ -72,8 +72,8 @@ // Check the presence of some other notable reporters. } else if (aPath.search(/^explicit\/js\/compartment\(/) >= 0) { areJsCompartmentsPresent = true; - } else if (aPath.search(/^explicit\/window-objects\/.*inner-window\(/) >= 0) { - areInnerWindowsPresent = true; + } else if (aPath.search(/^explicit\/window-objects\/top\(/) >= 0) { + areWindowObjectsPresent = true; } else if (aPath.search(/^explicit\/storage\/sqlite\/places.sqlite/) >= 0) { isPlacesPresent = true; } else if (aPath.search(/^explicit\/images/) >= 0) { @@ -131,7 +131,7 @@ ok(areJsCompartmentsPresent, "js compartments are present"); ok(isSandboxLocationShown, "sandbox locations are present"); - ok(areInnerWindowsPresent, "inner-windows are present"); + ok(areWindowObjectsPresent, "window objects are present"); ok(isPlacesPresent, "places is present"); ok(isImagesPresent, "images is present"); ok(isXptiWorkingSetPresent, "xpti-working-set is present"); diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js index d9e94cb86a91..82663d9a6cef 100644 --- a/toolkit/components/search/nsSearchService.js +++ b/toolkit/components/search/nsSearchService.js @@ -43,6 +43,7 @@ const Cc = Components.classes; const Cr = Components.results; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); const PERMS_FILE = 0644; const PERMS_DIRECTORY = 0755; @@ -76,6 +77,19 @@ const SEARCH_ENGINE_CHANGED = "engine-changed"; const SEARCH_ENGINE_LOADED = "engine-loaded"; const SEARCH_ENGINE_CURRENT = "engine-current"; +// The following constants are left undocumented in nsIBrowserSearchService.idl +// For the moment, they are meant for testing/debugging purposes only. + +/** + * Topic used for events involving the service itself. + */ +const SEARCH_SERVICE_TOPIC = "browser-search-service"; + +/** + * Sent whenever metadata is fully written to disk. + */ +const SEARCH_SERVICE_METADATA_WRITTEN = "write-metadata-to-disk-complete"; + const SEARCH_TYPE_MOZSEARCH = Ci.nsISearchEngine.TYPE_MOZSEARCH; const SEARCH_TYPE_OPENSEARCH = Ci.nsISearchEngine.TYPE_OPENSEARCH; const SEARCH_TYPE_SHERLOCK = Ci.nsISearchEngine.TYPE_SHERLOCK; @@ -218,6 +232,12 @@ __defineGetter__("gPrefSvc", function() { getService(Ci.nsIPrefBranch); }); +__defineGetter__("FileUtils", function() { + delete this.FileUtils; + Components.utils.import("resource://gre/modules/FileUtils.jsm"); + return FileUtils; +}); + __defineGetter__("NetUtil", function() { delete this.NetUtil; Components.utils.import("resource://gre/modules/NetUtil.jsm"); @@ -309,6 +329,64 @@ function ENSURE_WARN(assertion, message, resultCode) { throw Components.Exception(message, resultCode); } +/** + * A delayed treatment that may be delayed even further. + * + * Use this for instance if you write data to a file and you expect + * that you may have to rewrite data very soon afterwards. With + * |Lazy|, the treatment is delayed by a few milliseconds and, + * should a new change to the data occur during this period, + * 1/ only the final version of the data is actually written; + * 2/ a further grace delay is added to take into account other + * changes. + * + * @constructor + * @param {Function} code The code to execute after the delay. + * @param {number=} delay An optional delay, in milliseconds. + */ +function Lazy(code, delay) { + LOG("Lazy: Creating a Lazy"); + this._callback = + (function(){ + code(); + this._timer = null; + }).bind(this); + this._delay = delay || LAZY_SERIALIZE_DELAY; + this._timer = null; +} +Lazy.prototype = { + /** + * Start (or postpone) treatment. + */ + go: function Lazy_go() { + LOG("Lazy_go: starting"); + if (this._timer) { + LOG("Lazy_go: reusing active timer"); + this._timer.delay = this._delay; + } else { + LOG("Lazy_go: creating timer"); + this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + this._timer. + initWithCallback(this._callback, + this._delay, + Ci.nsITimer.TYPE_ONE_SHOT); + } + }, + /** + * Perform any postponed treatment immediately. + */ + flush: function Lazy_flush() { + LOG("Lazy_flush: starting"); + if (!this._timer) { + return; + } + this._timer.cancel(); + this._timer = null; + this._callback(); + } +}; + + function loadListener(aChannel, aEngine, aCallback) { this._channel = aChannel; this._bytes = []; @@ -718,6 +796,12 @@ function notifyAction(aEngine, aVerb) { } } +function parseJsonFromStream(aInputStream) { + const json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); + const data = json.decodeFromStream(aInputStream, aInputStream.available()); + return data; +} + /** * Simple object representing a name/value pair. */ @@ -2576,6 +2660,7 @@ SearchService.prototype = { }, _loadEngines: function SRCH_SVC__loadEngines() { + LOG("_loadEngines: start"); // See if we have a cache file so we don't have to parse a bunch of XML. let cache = {}; let cacheEnabled = getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true); @@ -2633,8 +2718,11 @@ SearchService.prototype = { return; } + LOG("_loadEngines: loading from cache directories"); for each (let dir in cache.directories) this._loadEnginesFromCache(dir); + + LOG("_loadEngines: done"); }, _readCacheFile: function SRCH_SVC__readCacheFile(aFile) { @@ -2810,7 +2898,7 @@ SearchService.prototype = { try { this._convertSherlockFile(addedEngine, fileURL.fileBaseName); } catch (ex) { - LOG("_loadEnginesFromDir: Failed to convert: " + fileURL.path + "\n" + ex); + LOG("_loadEnginesFromDir: Failed to convert: " + fileURL.path + "\n" + ex + "\n" + ex.stack); // The engine couldn't be converted, mark it as read-only addedEngine._readOnly = true; } @@ -2907,23 +2995,29 @@ SearchService.prototype = { _saveSortedEngineList: function SRCH_SVC_saveSortedEngineList() { // We only need to write the prefs. if something has changed. + LOG("SRCH_SVC_saveSortedEngineList: starting"); if (!this._needToSetOrderPrefs) return; + LOG("SRCH_SVC_saveSortedEngineList: something to do"); + // Set the useDB pref to indicate that from now on we should use the order // information stored in the database. gPrefSvc.setBoolPref(BROWSER_SEARCH_PREF + "useDBForOrder", true); var engines = this._getSortedEngines(true); - var values = []; - var names = []; + let instructions = []; for (var i = 0; i < engines.length; ++i) { - names[i] = "order"; - values[i] = i + 1; + instructions.push( + {key: "order", + value: i+1, + engine: engines[i] + }); } - engineMetadataService.setAttrs(engines, names, values); + engineMetadataService.setAttrs(instructions); + LOG("SRCH_SVC_saveSortedEngineList: done"); }, _buildSortedEngineList: function SRCH_SVC_buildSortedEngineList() { @@ -2936,6 +3030,7 @@ SearchService.prototype = { // information from the engineMetadataService instead of the default // prefs. if (getBoolPref(BROWSER_SEARCH_PREF + "useDBForOrder", false)) { + LOG("_buildSortedEngineList: using db for order"); for each (engine in this._engines) { var orderNumber = engineMetadataService.getAttr(engine, "order"); @@ -3434,7 +3529,7 @@ SearchService.prototype = { this._batchTimer.cancel(); this._buildCache(); } - engineMetadataService.closeDB(); + engineMetadataService.flush(); break; } }, @@ -3499,135 +3594,216 @@ SearchService.prototype = { }; var engineMetadataService = { - get mDB() { - var engineDataTable = "id INTEGER PRIMARY KEY, engineid STRING, name STRING, value STRING"; - var file = getDir(NS_APP_USER_PROFILE_50_DIR); - file.append("search.sqlite"); - var dbService = Cc["@mozilla.org/storage/service;1"]. - getService(Ci.mozIStorageService); - var db; - try { - db = dbService.openDatabase(file); - } catch (ex) { - if (ex.result == 0x8052000b) { /* NS_ERROR_FILE_CORRUPTED */ - // delete and try again - file.remove(false); - db = dbService.openDatabase(file); - } else { - throw ex; + /** + * @type {nsIFile|null} The file holding the metadata. + */ + get _jsonFile() { + delete this._jsonFile; + return this._jsonFile = FileUtils.getFile(NS_APP_USER_PROFILE_50_DIR, + ["search-metadata.json"]); + }, + + /** + * Lazy getter for the file containing json data. + */ + get _store() { + delete this._store; + return this._store = this._loadStore(); + }, + + // Perform loading the first time |_store| is accessed. + _loadStore: function() { + let jsonFile = this._jsonFile; + if (!jsonFile.exists()) { + LOG("loadStore: search-metadata.json does not exist"); + + // First check to see whether there's an existing SQLite DB to migrate + let store = this._migrateOldDB(); + if (store) { + // Commit the migrated store to disk immediately + LOG("Committing the migrated store to disk"); + this._commit(store); + return store; } + + // Migration failed, or this is a first-run - just use an empty store + return {}; } + LOG("loadStore: attempting to load store from JSON file"); try { - db.createTable("engine_data", engineDataTable); - } catch (ex) { - // Fails if the table already exists, which is fine + return parseJsonFromStream(NetUtil.newChannel(jsonFile).open()); + } catch (x) { + LOG("loadStore failed to load file: "+x); + return {}; } - - delete this.mDB; - return this.mDB = db; - }, - - get mGetData() { - delete this.mGetData; - return this.mGetData = this.mDB.createStatement( - "SELECT value FROM engine_data WHERE engineid = :engineid AND name = :name"); - }, - get mDeleteData() { - delete this.mDeleteData; - return this.mDeleteData = this.mDB.createStatement( - "DELETE FROM engine_data WHERE engineid = :engineid AND name = :name"); - }, - get mInsertData() { - delete this.mInsertData; - return this.mInsertData = this.mDB.createStatement( - "INSERT INTO engine_data (engineid, name, value) " + - "VALUES (:engineid, :name, :value)"); }, getAttr: function epsGetAttr(engine, name) { - // attr names must be lower case - name = name.toLowerCase(); - - var stmt = this.mGetData; - stmt.reset(); - var pp = stmt.params; - pp.engineid = engine._id; - pp.name = name; - - var value = null; - if (stmt.executeStep()) - value = stmt.row.value; - stmt.reset(); - return value; - }, - - setAttr: function epsSetAttr(engine, name, value) { - // attr names must be lower case - name = name.toLowerCase(); - - this.mDB.beginTransaction(); - - var pp = this.mDeleteData.params; - pp.engineid = engine._id; - pp.name = name; - this.mDeleteData.executeStep(); - this.mDeleteData.reset(); - - pp = this.mInsertData.params; - pp.engineid = engine._id; - pp.name = name; - pp.value = value; - this.mInsertData.executeStep(); - this.mInsertData.reset(); - - this.mDB.commitTransaction(); - }, - - setAttrs: function epsSetAttrs(engines, names, values) { - this.mDB.beginTransaction(); - - for (var i = 0; i < engines.length; i++) { - // attr names must be lower case - var name = names[i].toLowerCase(); - - var pp = this.mDeleteData.params; - pp.engineid = engines[i]._id; - pp.name = names[i]; - this.mDeleteData.executeStep(); - this.mDeleteData.reset(); - - pp = this.mInsertData.params; - pp.engineid = engines[i]._id; - pp.name = names[i]; - pp.value = values[i]; - this.mInsertData.executeStep(); - this.mInsertData.reset(); + let record = this._store[engine._id]; + if (!record) { + return null; } - this.mDB.commitTransaction(); + // attr names must be lower case + return record[name.toLowerCase()]; }, - deleteEngineData: function epsDelData(engine, name) { + _setAttr: function epsSetAttr(engine, name, value) { // attr names must be lower case name = name.toLowerCase(); - - var pp = this.mDeleteData.params; - pp.engineid = engine._id; - pp.name = name; - this.mDeleteData.executeStep(); - this.mDeleteData.reset(); + let db = this._store; + let record = db[engine._id]; + if (!record) { + record = db[engine._id] = {}; + } + if (record[name] != value) { + record[name] = value; + return true; + } + return false; }, - closeDB: function epsCloseDB() { - ["mInsertData", "mDeleteData", "mGetData"].forEach(function(aStmt) { - if (Object.getOwnPropertyDescriptor(this, aStmt).value !== undefined) - this[aStmt].finalize(); - }, this); - if (Object.getOwnPropertyDescriptor(this, "mDB").value !== undefined) - this.mDB.close(); - } -} + /** + * Set one metadata attribute for an engine. + * + * If an actual change has taken place, the attribute is committed + * automatically (and lazily), using this._commit. + * + * @param {nsISearchEngine} engine The engine to update. + * @param {string} key The name of the attribute. Case-insensitive. In + * the current implementation, this _must not_ conflict with properties + * of |Object|. + * @param {*} value A value to store. + */ + setAttr: function epsSetAttr(engine, key, value) { + if (this._setAttr(engine, key, value)) { + this._commit(); + } + }, + + /** + * Bulk set metadata attributes for a number of engines. + * + * If actual changes have taken place, the store is committed + * automatically (and lazily), using this._commit. + * + * @param {Array.<{engine: nsISearchEngine, key: string, value: *}>} changes + * The list of changes to effect. See |setAttr| for the documentation of + * |engine|, |key|, |value|. + */ + setAttrs: function epsSetAttrs(changes) { + let self = this; + let changed = false; + changes.forEach(function(change) { + changed |= self._setAttr(change.engine, change.key, change.value); + }); + if (changed) { + this._commit(); + } + }, + + /** + * Flush any waiting write. + */ + flush: function epsFlush() { + if (this._lazyWriter) { + this._lazyWriter.flush(); + } + }, + + /** + * Migrate search.sqlite + * + * Notes: + * - we do not remove search.sqlite after migration, so as to allow + * downgrading and forensics; + */ + _migrateOldDB: function SRCH_SVC_EMS_migrate() { + LOG("SRCH_SVC_EMS_migrate start"); + let sqliteFile = FileUtils.getFile(NS_APP_USER_PROFILE_50_DIR, + ["search.sqlite"]); + if (!sqliteFile.exists()) { + LOG("SRCH_SVC_EMS_migrate search.sqlite does not exist"); + return null; + } + let store = {}; + try { + LOG("SRCH_SVC_EMS_migrate Migrating data from SQL"); + const sqliteDb = Services.storage.openDatabase(sqliteFile); + const statement = sqliteDb.createStatement("SELECT * from engine_data"); + while (statement.executeStep()) { + let row = statement.row; + let engine = row.engineid; + let name = row.name; + let value = row.value; + if (!store[engine]) { + store[engine] = {}; + } + store[engine][name] = value; + } + statement.finalize(); + sqliteDb.close(); + } catch (ex) { + LOG("SRCH_SVC_EMS_migrate failed: " + ex); + return null; + } + return store; + }, + + /** + * Commit changes to disk, asynchronously. + * + * Calls to this function are actually delayed by LAZY_SERIALIZE_DELAY + * (= 100ms). If the function is called again before the expiration of + * the delay, commits are merged and the function is again delayed by + * the same amount of time. + * + * @param aStore is an optional parameter specifying the object to serialize. + * If not specified, this._store is used. + */ + _commit: function epsCommit(aStore) { + LOG("epsCommit: start"); + + let store = aStore || this._store; + if (!store) { + LOG("epsCommit: nothing to do"); + return; + } + + if (!this._lazyWriter) { + LOG("epsCommit: initializing lazy writer"); + let jsonFile = this._jsonFile; + function writeCommit() { + LOG("epsWriteCommit: start"); + let ostream = FileUtils. + openSafeFileOutputStream(jsonFile, + MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE); + + // Obtain a converter to convert our data to a UTF-8 encoded input stream. + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. + createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let callback = function(result) { + if (Components.isSuccessCode(result)) { + gObsSvc.notifyObservers(null, + SEARCH_SERVICE_TOPIC, + SEARCH_SERVICE_METADATA_WRITTEN); + } + LOG("epsWriteCommit: done " + result); + }; + // Asynchronously copy the data to the file. + let istream = converter.convertToInputStream(JSON.stringify(store)); + NetUtil.asyncCopy(istream, ostream, callback); + } + this._lazyWriter = new Lazy(writeCommit); + } + LOG("epsCommit: (re)setting timer"); + this._lazyWriter.go(); + }, + _lazyWriter: null, +}; const SEARCH_UPDATE_LOG_PREFIX = "*** Search update: "; diff --git a/toolkit/components/search/tests/xpcshell/data/chrome.manifest b/toolkit/components/search/tests/xpcshell/data/chrome.manifest index ac459af7e013..ec412e05081f 100644 --- a/toolkit/components/search/tests/xpcshell/data/chrome.manifest +++ b/toolkit/components/search/tests/xpcshell/data/chrome.manifest @@ -1 +1,3 @@ locale testsearchplugin ar jar:jar:searchTest.jar!/chrome/searchTest.jar!/ +content testsearchplugin ./ + diff --git a/toolkit/components/search/tests/xpcshell/data/engine.src b/toolkit/components/search/tests/xpcshell/data/engine.src new file mode 100644 index 000000000000..bd5fff1793d4 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/data/engine.src @@ -0,0 +1,18 @@ + + + + + + + diff --git a/toolkit/components/search/tests/xpcshell/data/engine.xml b/toolkit/components/search/tests/xpcshell/data/engine.xml new file mode 100644 index 000000000000..aba350f4f430 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/data/engine.xml @@ -0,0 +1,18 @@ + + +Test search engine +A test search engine (based on Google search) +UTF-8 +data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA + + + + + + + + + + +http://www.google.com/ + diff --git a/toolkit/components/search/tests/xpcshell/data/ico-size-16x16-png.ico b/toolkit/components/search/tests/xpcshell/data/ico-size-16x16-png.ico new file mode 100644 index 000000000000..442ab4dc8093 Binary files /dev/null and b/toolkit/components/search/tests/xpcshell/data/ico-size-16x16-png.ico differ diff --git a/toolkit/components/search/tests/xpcshell/data/search-metadata.json b/toolkit/components/search/tests/xpcshell/data/search-metadata.json new file mode 100644 index 000000000000..656247aa7b35 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/data/search-metadata.json @@ -0,0 +1,28 @@ +{ + "[app]/amazondotcom.xml": { + "used": 0, + "order": 4 + }, + "[app]/eBay.xml": { + "used": 0, + "order": 1 + }, + "[app]/wikipedia.xml": { + "used": 0, + "order": 6 + }, + "[app]/twitter.xml": { + "used": 0, + "order": 7 + }, + "[app]/google.xml": { + "used": 1, + "order": 2 + }, + "[app]/bing.xml": { + "order": 5 + }, + "[app]/yahoo.xml": { + "order": 3 + } +} diff --git a/toolkit/components/search/tests/xpcshell/data/search.sqlite b/toolkit/components/search/tests/xpcshell/data/search.sqlite new file mode 100644 index 000000000000..983bb831a8ae Binary files /dev/null and b/toolkit/components/search/tests/xpcshell/data/search.sqlite differ diff --git a/toolkit/components/search/tests/xpcshell/head_search.js b/toolkit/components/search/tests/xpcshell/head_search.js index 110d94547b88..2b45f0f135c8 100644 --- a/toolkit/components/search/tests/xpcshell/head_search.js +++ b/toolkit/components/search/tests/xpcshell/head_search.js @@ -1,37 +1,10 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et: */ -/* ***** 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 Initial Developer of the Original Code is POTI Inc. - * Portions created by the Initial Developer are Copyright (C) 2007 - * 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 ***** */ + +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1"; const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}"); @@ -90,3 +63,49 @@ function createAppInfo(id, name, version, platformVersion) // Need to create and register a profile folder. var gProfD = do_get_profile(); +function dumpn(text) +{ + dump(text+"\n"); +} + +/** + * Clean the profile of any metadata files left from a previous run. + */ +function removeMetadata() +{ + let file = gProfD.clone(); + file.append("search-metadata.json"); + if (file.exists()) { + file.remove(false); + } + + file = gProfD.clone(); + file.append("search.sqlite"); + if (file.exists()) { + file.remove(false); + } +} + +/** + * Run some callback once metadata has been committed to disk. + */ +function afterCommit(callback) +{ + let obs = function(result, topic, verb) { + if (verb == "write-metadata-to-disk-complete") { + callback(result); + } else { + dump("TOPIC: " + topic+ "\n"); + } + } + Services.obs.addObserver(obs, "browser-search-service", false); +} + +function parseJsonFromStream(aInputStream) { + const json = Cc["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON); + const data = json.decodeFromStream(aInputStream, aInputStream.available()); + return data; +} + +Services.prefs.setBoolPref("browser.search.log", true); +//Otherwise, error logs contain no useful data diff --git a/toolkit/components/search/tests/xpcshell/test_645970.js b/toolkit/components/search/tests/xpcshell/test_645970.js index 811dd2b4a35b..6a9b99c4b55f 100644 --- a/toolkit/components/search/tests/xpcshell/test_645970.js +++ b/toolkit/components/search/tests/xpcshell/test_645970.js @@ -33,16 +33,6 @@ * * ***** END LICENSE BLOCK ***** */ -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); - - -var gPrefService = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService) - .QueryInterface(Ci.nsIPrefBranch); /** * Test nsSearchService with nested jar: uris */ @@ -52,15 +42,13 @@ function run_test() { do_load_manifest("data/chrome.manifest"); let url = "chrome://testsearchplugin/locale/searchplugins/"; - gPrefService.setCharPref("browser.search.jarURIs", url); + Services.prefs.setCharPref("browser.search.jarURIs", url); - gPrefService.setBoolPref("browser.search.loadFromJars", true); + Services.prefs.setBoolPref("browser.search.loadFromJars", true); // The search service needs to be started after the jarURIs pref has been // set in order to initiate it correctly - let searchService = Cc["@mozilla.org/browser/search-service;1"] - .getService(Ci.nsIBrowserSearchService); - let engine = searchService.getEngineByName("bug645970"); + let engine = Services.search.getEngineByName("bug645970"); do_check_neq(engine, null); Services.obs.notifyObservers(null, "quit-application", null); } diff --git a/toolkit/components/search/tests/xpcshell/test_migratedb.js b/toolkit/components/search/tests/xpcshell/test_migratedb.js new file mode 100644 index 000000000000..906818970f90 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/test_migratedb.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * test_migratedb: Start search engine + * - without search-metadata.json + * - with search.sqlite + * + * Ensure that nothing explodes. + */ + +function run_test() +{ + removeMetadata(); + + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2"); + + let search_sqlite = do_get_file("data/search.sqlite"); + search_sqlite.copyTo(gProfD, "search.sqlite"); + + let search = Services.search; + + do_test_pending(); + afterCommit( + function() + { + //Check that search-metadata.json has been created + let metadata = gProfD.clone(); + metadata.append("search-metadata.json"); + do_check_true(metadata.exists()); + + removeMetadata(); + do_test_finished(); + } + ); + + search.getEngines(); +} diff --git a/toolkit/components/search/tests/xpcshell/test_nodb.js b/toolkit/components/search/tests/xpcshell/test_nodb.js new file mode 100644 index 000000000000..dd6f07df6edf --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/test_nodb.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * test_nodb: Start search engine + * - without search-metadata.json + * - without search.sqlite + * + * Ensure that : + * - nothing explodes; + * - no search-metadata.json is created. + */ + + +function run_test() +{ + removeMetadata(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2"); + + let search = Services.search; // Cause service initialization + + do_test_pending(); + do_timeout(500, + function() + { + // Check that search-metadata.json has not been created + // Note that we cannot du much better than a timeout for + // checking a non-event. + let metadata = gProfD.clone(); + metadata.append("search-metadata.json"); + do_check_true(!metadata.exists()); + removeMetadata(); + + do_test_finished(); + } + ); +} diff --git a/toolkit/components/search/tests/xpcshell/test_nodb_pluschanges.js b/toolkit/components/search/tests/xpcshell/test_nodb_pluschanges.js new file mode 100644 index 000000000000..062ecad9ff91 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/test_nodb_pluschanges.js @@ -0,0 +1,87 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + + +/* + * test_nodb: Start search engine + * - without search-metadata.json + * - without search.sqlite + * + * Ensure that : + * - nothing explodes; + * - if we change the order, search-metadata.json is created; + * - this search-medata.json can be parsed; + * - the order stored in search-metadata.json is consistent. + * + * Notes: + * - we install the search engines of test "test_downloadAndAddEngines.js" + * to ensure that this test is independent from locale, commercial agreements + * and configuration of Firefox. + */ + +do_load_httpd_js(); + +function run_test() +{ + removeMetadata(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2"); + do_load_manifest("data/chrome.manifest"); + + let httpServer = new nsHttpServer(); + httpServer.start(4444); + httpServer.registerDirectory("/", do_get_cwd()); + + let search = Services.search; + + function observer(aSubject, aTopic, aData) { + if ("engine-added" == aData) { + let engine1 = search.getEngineByName("Test search engine"); + let engine2 = search.getEngineByName("Sherlock test search engine"); + dumpn("Got engine 2: "+engine2); + if(engine1 && engine2) + { + search.moveEngine(engine1, 0); + search.moveEngine(engine2, 1); + do_timeout(0, + function() { + // Force flush + // Note: the timeout is needed, to avoid some reentrency + // issues in nsSearchService. + search.QueryInterface(Ci.nsIObserver). + observe(observer, "quit-application", ""); + }); + afterCommit( + function() + { + // Check that search-metadata.json has been created + let metadata = gProfD.clone(); + metadata.append("search-metadata.json"); + do_check_true(metadata.exists()); + + // Check that the entries are placed as specified correctly + let stream = NetUtil.newChannel(metadata).open(); + let json = parseJsonFromStream(stream); + do_check_eq(json["[app]/test-search-engine.xml"].order, 1); + do_check_eq(json["[profile]/sherlock-test-search-engine.xml"].order, 2); + httpServer.stop(function() {}); + stream.close(); // Stream must be closed under Windows + removeMetadata(); + do_test_finished(); + } + ); + } + } + }; + Services.obs.addObserver(observer, "browser-search-engine-modified", + false); + + do_test_pending(); + + search.addEngine("http://localhost:4444/data/engine.xml", + Ci.nsISearchEngine.DATA_XML, + null, false); + search.addEngine("http://localhost:4444/data/engine.src", + Ci.nsISearchEngine.DATA_TEXT, + "http://localhost:4444/data/ico-size-16x16-png.ico", + false); +} diff --git a/toolkit/components/search/tests/xpcshell/xpcshell.ini b/toolkit/components/search/tests/xpcshell/xpcshell.ini index 5c7a961fc084..7f215e0d6ba0 100644 --- a/toolkit/components/search/tests/xpcshell/xpcshell.ini +++ b/toolkit/components/search/tests/xpcshell/xpcshell.ini @@ -2,4 +2,7 @@ head = head_search.js tail = +[test_nodb.js] +[test_nodb_pluschanges.js] +[test_migratedb.js] [test_645970.js] diff --git a/toolkit/content/license.html b/toolkit/content/license.html index 27775536b334..17b2bebc3510 100644 --- a/toolkit/content/license.html +++ b/toolkit/content/license.html @@ -94,6 +94,7 @@
  • Skia License
  • Snappy License
  • Sparkle License
  • +
  • Suitable Systems License
  • SunSoft License
  • University of California License
  • University of Cambridge License
  • @@ -2234,6 +2235,59 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +
    + +

    Suitable Systems License

    + +

    This license applies to certain files in the directory + dom/system/cocoa/.

    + +
    +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
    +	
    +or contact
    +	Daniel Griscom
    +	Suitable Systems
    +	1 Centre Street, Suite 204
    +	Wakefield, MA 01880
    +	(781) 665-0053
    +
    +
    diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index eff6d9117eb2..4e40a2f3d09b 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -115,14 +115,9 @@ AndroidBridge::Init(JNIEnv *jEnv, jNotifyScreenShot = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyScreenShot", "(Ljava/nio/ByteBuffer;III)V"); jAcknowledgeEventSync = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "acknowledgeEventSync", "()V"); - jEnableDeviceMotion = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableDeviceMotion", "(Z)V"); jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V"); - jEnableSensor = - (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, - "enableSensor", "(I)V"); - jDisableSensor = - (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, - "disableSensor", "(I)V"); + jEnableSensor = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableSensor", "(I)V"); + jDisableSensor = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableSensor", "(I)V"); jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V"); jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V"); jNotifyXreExit = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onXreExit", "()V"); @@ -322,13 +317,23 @@ AndroidBridge::EnableDeviceMotion(bool aEnable) { ALOG_BRIDGE("AndroidBridge::EnableDeviceMotion"); - JNIEnv *env = GetJNIEnv(); - if (!env) - return; - - env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableDeviceMotion, aEnable); + // bug 734855 - we probably can make this finer grain based on + // the DOM APIs that are being invoked. + if (aEnable) { + EnableSensor(hal::SENSOR_ORIENTATION); + EnableSensor(hal::SENSOR_ACCELERATION); + EnableSensor(hal::SENSOR_LINEAR_ACCELERATION); + EnableSensor(hal::SENSOR_GYROSCOPE); + } + else { + DisableSensor(hal::SENSOR_ORIENTATION); + DisableSensor(hal::SENSOR_ACCELERATION); + DisableSensor(hal::SENSOR_LINEAR_ACCELERATION); + DisableSensor(hal::SENSOR_GYROSCOPE); + } } + void AndroidBridge::EnableLocation(bool aEnable) { @@ -337,22 +342,30 @@ AndroidBridge::EnableLocation(bool aEnable) JNIEnv *env = GetJNIEnv(); if (!env) return; - + + AutoLocalJNIFrame jniFrame(env, 1); env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableLocation, aEnable); } void AndroidBridge::EnableSensor(int aSensorType) { ALOG_BRIDGE("AndroidBridge::EnableSensor"); - mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jEnableSensor, - aSensorType); + JNIEnv *env = GetJNIEnv(); + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env, 1); + env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableSensor, aSensorType); } void AndroidBridge::DisableSensor(int aSensorType) { ALOG_BRIDGE("AndroidBridge::DisableSensor"); - mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jDisableSensor, - aSensorType); + JNIEnv *env = GetJNIEnv(); + if (!env) + return; + AutoLocalJNIFrame jniFrame(env, 1); + env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableSensor, aSensorType); } void diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index e2f27ddb3f9d..40a90a4c138b 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -452,7 +452,6 @@ protected: jmethodID jNotifyIMEChange; jmethodID jNotifyScreenShot; jmethodID jAcknowledgeEventSync; - jmethodID jEnableDeviceMotion; jmethodID jEnableLocation; jmethodID jEnableSensor; jmethodID jDisableSensor; diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 84952f89a625..775a1b72b763 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -49,9 +49,6 @@ jfieldID AndroidGeckoEvent::jPointIndicies = 0; jfieldID AndroidGeckoEvent::jPressures = 0; jfieldID AndroidGeckoEvent::jPointRadii = 0; jfieldID AndroidGeckoEvent::jOrientations = 0; -jfieldID AndroidGeckoEvent::jAlphaField = 0; -jfieldID AndroidGeckoEvent::jBetaField = 0; -jfieldID AndroidGeckoEvent::jGammaField = 0; jfieldID AndroidGeckoEvent::jXField = 0; jfieldID AndroidGeckoEvent::jYField = 0; jfieldID AndroidGeckoEvent::jZField = 0; @@ -73,7 +70,6 @@ jfieldID AndroidGeckoEvent::jRangeStylesField = 0; jfieldID AndroidGeckoEvent::jRangeForeColorField = 0; jfieldID AndroidGeckoEvent::jRangeBackColorField = 0; jfieldID AndroidGeckoEvent::jLocationField = 0; -jfieldID AndroidGeckoEvent::jAddressField = 0; jfieldID AndroidGeckoEvent::jBandwidthField = 0; jfieldID AndroidGeckoEvent::jCanBeMeteredField = 0; @@ -96,19 +92,6 @@ jmethodID AndroidLocation::jGetBearingMethod = 0; jmethodID AndroidLocation::jGetSpeedMethod = 0; jmethodID AndroidLocation::jGetTimeMethod = 0; -jclass AndroidAddress::jAddressClass = 0; -jmethodID AndroidAddress::jGetAddressLineMethod; -jmethodID AndroidAddress::jGetAdminAreaMethod; -jmethodID AndroidAddress::jGetCountryNameMethod; -jmethodID AndroidAddress::jGetFeatureNameMethod; -jmethodID AndroidAddress::jGetLocalityMethod; -jmethodID AndroidAddress::jGetPostalCodeMethod; -jmethodID AndroidAddress::jGetPremisesMethod; -jmethodID AndroidAddress::jGetSubAdminAreaMethod; -jmethodID AndroidAddress::jGetSubLocalityMethod; -jmethodID AndroidAddress::jGetSubThoroughfareMethod; -jmethodID AndroidAddress::jGetThoroughfareMethod; - jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0; jmethodID AndroidGeckoLayerClient::jBeginDrawingMethod = 0; jmethodID AndroidGeckoLayerClient::jEndDrawingMethod = 0; @@ -158,7 +141,6 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv) AndroidGeckoEvent::InitGeckoEventClass(jEnv); AndroidPoint::InitPointClass(jEnv); AndroidLocation::InitLocationClass(jEnv); - AndroidAddress::InitAddressClass(jEnv); AndroidRect::InitRectClass(jEnv); AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv); AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv); @@ -181,9 +163,6 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv) jOrientations = getField("mOrientations", "[F"); jPressures = getField("mPressures", "[F"); jPointRadii = getField("mPointRadii", "[Landroid/graphics/Point;"); - jAlphaField = getField("mAlpha", "D"); - jBetaField = getField("mBeta", "D"); - jGammaField = getField("mGamma", "D"); jXField = getField("mX", "D"); jYField = getField("mY", "D"); jZField = getField("mZ", "D"); @@ -204,7 +183,6 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv) jRangeForeColorField = getField("mRangeForeColor", "I"); jRangeBackColorField = getField("mRangeBackColor", "I"); jLocationField = getField("mLocation", "Landroid/location/Location;"); - jAddressField = getField("mAddress", "Landroid/location/Address;"); jBandwidthField = getField("mBandwidth", "D"); jCanBeMeteredField = getField("mCanBeMetered", "Z"); } @@ -243,60 +221,6 @@ AndroidLocation::InitLocationClass(JNIEnv *jEnv) jGetTimeMethod = getMethod("getTime", "()J"); } -void -AndroidAddress::InitAddressClass(JNIEnv *jEnv) -{ - initInit(); - - jAddressClass = getClassGlobalRef("android/location/Address"); - - jGetAddressLineMethod = getMethod("getAddressLine", "(I)Ljava/lang/String;"); - jGetAdminAreaMethod = getMethod("getAdminArea", "()Ljava/lang/String;"); - jGetCountryNameMethod = getMethod("getCountryName", "()Ljava/lang/String;"); - jGetFeatureNameMethod = getMethod("getFeatureName", "()Ljava/lang/String;"); - jGetLocalityMethod = getMethod("getLocality", "()Ljava/lang/String;"); - jGetPostalCodeMethod = getMethod("getPostalCode", "()Ljava/lang/String;"); - jGetPremisesMethod = getMethod("getPremises", "()Ljava/lang/String;"); - jGetSubAdminAreaMethod = getMethod("getSubAdminArea", "()Ljava/lang/String;"); - jGetSubLocalityMethod = getMethod("getSubLocality", "()Ljava/lang/String;"); - jGetSubThoroughfareMethod = getMethod("getSubThoroughfare", "()Ljava/lang/String;"); - jGetThoroughfareMethod = getMethod("getThoroughfare", "()Ljava/lang/String;"); -} - -nsGeoPositionAddress* -AndroidAddress::CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj) -{ - nsJNIString streetNumber(static_cast(jenv->CallObjectMethod(jobj, jGetSubThoroughfareMethod)), jenv); - nsJNIString street(static_cast(jenv->CallObjectMethod(jobj, jGetThoroughfareMethod)), jenv); - nsJNIString city(static_cast(jenv->CallObjectMethod(jobj, jGetLocalityMethod)), jenv); - nsJNIString county(static_cast(jenv->CallObjectMethod(jobj, jGetSubAdminAreaMethod)), jenv); - nsJNIString country(static_cast(jenv->CallObjectMethod(jobj, jGetCountryNameMethod)), jenv); - nsJNIString premises(static_cast(jenv->CallObjectMethod(jobj, jGetPremisesMethod)), jenv); - nsJNIString postalCode(static_cast(jenv->CallObjectMethod(jobj, jGetPostalCodeMethod)), jenv); - nsJNIString region(static_cast(jenv->CallObjectMethod(jobj, jGetAdminAreaMethod, 0)), jenv); - -#ifdef DEBUG - printf_stderr("!!!!!!!!!!!!!! AndroidAddress::CreateGeoPositionAddress:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", - NS_LossyConvertUTF16toASCII(streetNumber).get(), - NS_LossyConvertUTF16toASCII(street).get(), - NS_LossyConvertUTF16toASCII(premises).get(), - NS_LossyConvertUTF16toASCII(city).get(), - NS_LossyConvertUTF16toASCII(county).get(), - NS_LossyConvertUTF16toASCII(region).get(), - NS_LossyConvertUTF16toASCII(country).get(), - NS_LossyConvertUTF16toASCII(postalCode).get()); -#endif - - return new nsGeoPositionAddress(streetNumber, - street, - premises, - city, - county, - region, - country, - postalCode); -} - nsGeoPosition* AndroidLocation::CreateGeoPosition(JNIEnv *jenv, jobject jobj) { @@ -548,25 +472,16 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) ReadRectField(jenv); break; - case ORIENTATION_EVENT: - mAlpha = jenv->GetDoubleField(jobj, jAlphaField); - mBeta = jenv->GetDoubleField(jobj, jBetaField); - mGamma = jenv->GetDoubleField(jobj, jGammaField); - break; - - case ACCELERATION_EVENT: - mX = jenv->GetDoubleField(jobj, jXField); - mY = jenv->GetDoubleField(jobj, jYField); - mZ = jenv->GetDoubleField(jobj, jZField); - break; + case SENSOR_EVENT: + mX = jenv->GetDoubleField(jobj, jXField); + mY = jenv->GetDoubleField(jobj, jYField); + mZ = jenv->GetDoubleField(jobj, jZField); + mFlags = jenv->GetIntField(jobj, jFlagsField); + break; case LOCATION_EVENT: { jobject location = jenv->GetObjectField(jobj, jLocationField); - jobject address = jenv->GetObjectField(jobj, jAddressField); - mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location); - if (address) - mGeoAddress = AndroidAddress::CreateGeoPositionAddress(jenv, address); break; } @@ -598,6 +513,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) break; } + case SENSOR_ACCURACY: case ACTIVITY_STOPPING: case ACTIVITY_START: case ACTIVITY_PAUSING: diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index d4f59ca5a446..127f49cf982b 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -430,25 +430,6 @@ public: static jmethodID jGetTimeMethod; }; -class AndroidAddress : public WrappedJavaObject -{ -public: - static void InitAddressClass(JNIEnv *jEnv); - static nsGeoPositionAddress* CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj); - static jclass jAddressClass; - static jmethodID jGetAddressLineMethod; - static jmethodID jGetAdminAreaMethod; - static jmethodID jGetCountryNameMethod; - static jmethodID jGetFeatureNameMethod; - static jmethodID jGetLocalityMethod; - static jmethodID jGetPostalCodeMethod; - static jmethodID jGetPremisesMethod; - static jmethodID jGetSubAdminAreaMethod; - static jmethodID jGetSubLocalityMethod; - static jmethodID jGetSubThoroughfareMethod; - static jmethodID jGetThoroughfareMethod; -}; - class AndroidGeckoEvent : public WrappedJavaObject { public: @@ -485,9 +466,6 @@ public: nsTArray Pressures() { return mPressures; } nsTArray Orientations() { return mOrientations; } nsTArray PointRadii() { return mPointRadii; } - double Alpha() { return mAlpha; } - double Beta() { return mBeta; } - double Gamma() { return mGamma; } double X() { return mX; } double Y() { return mY; } double Z() { return mZ; } @@ -507,7 +485,6 @@ public: int RangeForeColor() { return mRangeForeColor; } int RangeBackColor() { return mRangeBackColor; } nsGeoPosition* GeoPosition() { return mGeoPosition; } - nsGeoPositionAddress* GeoAddress() { return mGeoAddress; } double Bandwidth() { return mBandwidth; } bool CanBeMetered() { return mCanBeMetered; } @@ -526,13 +503,11 @@ protected: int mOffset, mCount; int mRangeType, mRangeStyles; int mRangeForeColor, mRangeBackColor; - double mAlpha, mBeta, mGamma; double mX, mY, mZ; double mDistance; int mPointerIndex; nsString mCharacters, mCharactersExtra; nsRefPtr mGeoPosition; - nsRefPtr mGeoAddress; double mBandwidth; bool mCanBeMetered; @@ -561,9 +536,6 @@ protected: static jfieldID jOrientations; static jfieldID jPressures; static jfieldID jPointRadii; - static jfieldID jAlphaField; - static jfieldID jBetaField; - static jfieldID jGammaField; static jfieldID jXField; static jfieldID jYField; static jfieldID jZField; @@ -585,7 +557,6 @@ protected: static jfieldID jRangeForeColorField; static jfieldID jRangeBackColorField; static jfieldID jLocationField; - static jfieldID jAddressField; static jfieldID jBandwidthField; static jfieldID jCanBeMeteredField; @@ -595,8 +566,8 @@ public: NATIVE_POKE = 0, KEY_EVENT = 1, MOTION_EVENT = 2, - ORIENTATION_EVENT = 3, - ACCELERATION_EVENT = 4, + SENSOR_EVENT = 3, + UNUSED1_EVENT = 4, LOCATION_EVENT = 5, IME_EVENT = 6, DRAW = 7, @@ -617,6 +588,7 @@ public: PROXIMITY_EVENT = 23, ACTIVITY_RESUMING = 24, SCREENSHOT = 25, + SENSOR_ACCURACY = 26, dummy_java_enum_list_end }; diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index 1038e8745139..6020cd91dc0e 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -96,7 +96,7 @@ nsAppShell::nsAppShell() mQueueCond(mCondLock, "nsAppShell.mQueueCond"), mNumDraws(0), mNumViewports(0), - mPendingOrientationEvents(false) + mPendingSensorEvents(false) { gAppShell = this; } @@ -331,32 +331,54 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait) NativeEventCallback(); break; - case AndroidGeckoEvent::ACCELERATION_EVENT: - gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, - -curEvent->X(), - curEvent->Y(), - curEvent->Z()); + case AndroidGeckoEvent::SENSOR_ACCURACY: + if (curEvent->Flags() == 0) + gDeviceMotionSystem->NeedsCalibration(); break; - case AndroidGeckoEvent::ORIENTATION_EVENT: - gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION, - -curEvent->Alpha(), - curEvent->Beta(), - curEvent->Gamma()); - mPendingOrientationEvents = false; - break; + case AndroidGeckoEvent::SENSOR_EVENT: + mPendingSensorEvents = false; + switch (curEvent->Flags()) { + case hal::SENSOR_ORIENTATION: + gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ORIENTATION, + curEvent->X(), + -curEvent->Y(), + -curEvent->Z()); + break; + + case hal::SENSOR_ACCELERATION: + gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_ACCELERATION, + -curEvent->X(), + curEvent->Y(), + curEvent->Z()); + break; + + case hal::SENSOR_LINEAR_ACCELERATION: + gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_LINEAR_ACCELERATION, + -curEvent->X(), + curEvent->Y(), + curEvent->Z()); + break; + + case hal::SENSOR_GYROSCOPE: + gDeviceMotionSystem->DeviceMotionChanged(nsIDeviceMotionData::TYPE_GYROSCOPE, + -curEvent->X(), + curEvent->Y(), + curEvent->Z()); + break; + + default: + __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### SENSOR_EVENT fired, but type wasn't known %d", curEvent->Flags()); + } + break; case AndroidGeckoEvent::LOCATION_EVENT: { if (!gLocationCallback) break; nsGeoPosition* p = curEvent->GeoPosition(); - nsGeoPositionAddress* a = curEvent->GeoAddress(); - - if (p) { - p->SetAddress(a); + if (p) gLocationCallback->Update(curEvent->GeoPosition()); - } else NS_WARNING("Received location event without geoposition!"); break; @@ -602,10 +624,10 @@ nsAppShell::PostEvent(AndroidGeckoEvent *ae) delete event; } } - } else if (ae->Type() == AndroidGeckoEvent::ORIENTATION_EVENT) { - if (!mPendingOrientationEvents) - mEventQueue.AppendElement(ae); - mPendingOrientationEvents = true; + } else if (ae->Type() == AndroidGeckoEvent::SENSOR_EVENT) { + if (!mPendingSensorEvents) + mEventQueue.AppendElement(ae); + mPendingSensorEvents = true; } else { mEventQueue.AppendElement(ae); } diff --git a/widget/android/nsAppShell.h b/widget/android/nsAppShell.h index ef43ae356e21..f86964dd8f59 100644 --- a/widget/android/nsAppShell.h +++ b/widget/android/nsAppShell.h @@ -110,7 +110,7 @@ protected: mozilla::AndroidGeckoEvent *PeekNextEvent(); nsCOMPtr mBrowserApp; - bool mPendingOrientationEvents; + bool mPendingSensorEvents; }; #endif // nsAppShell_h__ diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h index 4501daa756f4..091294f2039c 100644 --- a/xpcom/components/Module.h +++ b/xpcom/components/Module.h @@ -53,7 +53,7 @@ namespace mozilla { */ struct Module { - static const unsigned int kVersion = 13; + static const unsigned int kVersion = 14; struct CIDEntry; diff --git a/xpcom/idl-parser/header.py b/xpcom/idl-parser/header.py index 948c824d99be..b8d69408c70c 100644 --- a/xpcom/idl-parser/header.py +++ b/xpcom/idl-parser/header.py @@ -40,7 +40,7 @@ """Print a C++ header file for the IDL files specified on the command line""" -import sys, os.path, re, xpidl, itertools +import sys, os.path, re, xpidl, itertools, glob printdoccomments = False @@ -499,13 +499,21 @@ if __name__ == '__main__': os.mkdir(options.cachedir) sys.path.append(options.cachedir) - # Instantiate the parser. - p = xpidl.IDLParser(outputdir=options.cachedir) - # The only thing special about a regen is that there are no input files. if options.regen: if options.cachedir is None: print >>sys.stderr, "--regen useless without --cachedir" + # Delete the lex/yacc files. Ply is too stupid to regenerate them + # properly + deadfiles = os.path.join(options.cachedir, "*.py*") + for filename in glob.glob(deadfiles): + print filename + os.remove(filename) + + # Instantiate the parser. + p = xpidl.IDLParser(outputdir=options.cachedir) + + if options.regen: sys.exit(0) if options.depfile is not None and options.outfile is None: diff --git a/xpcom/system/nsIDeviceMotion.idl b/xpcom/system/nsIDeviceMotion.idl index f24144f6a3e6..79313d898388 100644 --- a/xpcom/system/nsIDeviceMotion.idl +++ b/xpcom/system/nsIDeviceMotion.idl @@ -43,6 +43,8 @@ interface nsIDeviceMotionData : nsISupports { const unsigned long TYPE_ACCELERATION = 0; const unsigned long TYPE_ORIENTATION = 1; + const unsigned long TYPE_LINEAR_ACCELERATION = 2; + const unsigned long TYPE_GYROSCOPE = 3; readonly attribute unsigned long type; @@ -51,10 +53,11 @@ interface nsIDeviceMotionData : nsISupports readonly attribute double z; }; -[scriptable, uuid(f01774a2-3b7e-4630-954b-196dc178221f)] +[scriptable, uuid(D29EA788-CCB6-4875-88E0-32A34BB71CBB)] interface nsIDeviceMotionListener : nsISupports { void onMotionChange(in nsIDeviceMotionData aMotionData); + void needsCalibration(); }; [scriptable, uuid(B6E5C463-AAA6-44E2-BD07-7A7DC6192E68)] @@ -73,9 +76,10 @@ interface nsIDeviceMotion : nsISupports /* for use by IPC system to notify non-chrome processes of * device motion events */ -[uuid(d3a56f08-b7b1-46bb-9dc1-fc3665a3631a)] +[uuid(C12C0157-DCFF-41B5-83F3-89179BF6CA4E)] interface nsIDeviceMotionUpdate : nsIDeviceMotion { /* must be called on the main thread or else */ void deviceMotionChanged(in unsigned long type, in double x, in double y, in double z); + void needsCalibration(); };