merge fx-team to m-c

This commit is contained in:
Tim Taubert
2012-01-26 08:36:07 +01:00
100 changed files with 1476 additions and 1113 deletions

View File

@@ -176,7 +176,8 @@
<menuseparator class="appmenu-menuseparator"/> <menuseparator class="appmenu-menuseparator"/>
<menu id="appmenu_webDeveloper" <menu id="appmenu_webDeveloper"
label="&appMenuWebDeveloper.label;"> label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup"> <menupopup id="appmenu_webDeveloper_popup"
onpopupshowing="onWebDeveloperMenuShowing();">
<menuitem id="appmenu_webConsole" <menuitem id="appmenu_webConsole"
label="&webConsoleCmd.label;" label="&webConsoleCmd.label;"
type="checkbox" type="checkbox"

View File

@@ -531,7 +531,8 @@
<menu id="webDeveloperMenu" <menu id="webDeveloperMenu"
label="&webDeveloperMenu.label;" label="&webDeveloperMenu.label;"
accesskey="&webDeveloperMenu.accesskey;"> accesskey="&webDeveloperMenu.accesskey;">
<menupopup id="menuWebDeveloperPopup"> <menupopup id="menuWebDeveloperPopup"
onpopupshowing="onWebDeveloperMenuShowing();">
<menuitem id="webConsole" <menuitem id="webConsole"
type="checkbox" type="checkbox"
label="&webConsoleCmd.label;" label="&webConsoleCmd.label;"

View File

@@ -9063,6 +9063,11 @@ var StyleEditor = {
} }
}; };
function onWebDeveloperMenuShowing() {
document.getElementById("Tools:WebConsole").setAttribute("checked", HUDConsoleUI.getOpenHUD() != null);
}
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () { XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
#ifdef XP_WIN #ifdef XP_WIN
// Only show resizers on Windows 2000 and XP // Only show resizers on Windows 2000 and XP
@@ -9137,6 +9142,7 @@ var MousePosTracker = {
} }
} }
}; };
function focusNextFrame(event) { function focusNextFrame(event) {
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC; let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC;

View File

@@ -741,6 +741,11 @@ iQClass.prototype = {
if (pair.original == func) { if (pair.original == func) {
handler = pair.modified; handler = pair.modified;
elem.iQEventData[type].splice(a, 1); elem.iQEventData[type].splice(a, 1);
if (!elem.iQEventData[type].length) {
delete elem.iQEventData[type];
if (!Object.keys(elem.iQEventData).length)
delete elem.iQEventData;
}
break; break;
} }
} }
@@ -765,10 +770,10 @@ iQClass.prototype = {
if (!elem.iQEventData) if (!elem.iQEventData)
continue; continue;
for (let type in elem.iQEventData) { Object.keys(elem.iQEventData).forEach(function (type) {
while (elem.iQEventData[type].length) while (elem.iQEventData && elem.iQEventData[type])
this.unbind(type, elem.iQEventData[type][0].original); this.unbind(type, elem.iQEventData[type][0].original);
} }, this);
} }
return this; return this;

View File

@@ -1552,8 +1552,6 @@ HUD_SERVICE.prototype =
this.disableAnimation(hudId); this.disableAnimation(hudId);
} }
chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "true");
// Create a processing instruction for GCLIs CSS stylesheet, but only if // Create a processing instruction for GCLIs CSS stylesheet, but only if
// we don't have one for this document. Also record the context we're // we don't have one for this document. Also record the context we're
// adding this for so we know when to remove it. // adding this for so we know when to remove it.
@@ -1603,8 +1601,6 @@ HUD_SERVICE.prototype =
window.focus(); window.focus();
} }
chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "false");
// Remove this context from the list of contexts that need the GCLI CSS // Remove this context from the list of contexts that need the GCLI CSS
// processing instruction and then remove the processing instruction if it // processing instruction and then remove the processing instruction if it
// isn't needed any more. // isn't needed any more.

View File

@@ -337,6 +337,7 @@ if test -n "$gonkdir" ; then
AC_DEFINE(ANDROID) AC_DEFINE(ANDROID)
AC_DEFINE(HAVE_SYS_UIO_H) AC_DEFINE(HAVE_SYS_UIO_H)
AC_DEFINE(HAVE_PTHREADS)
CROSS_COMPILE=1 CROSS_COMPILE=1
MOZ_CHROME_FILE_FORMAT=omni MOZ_CHROME_FILE_FORMAT=omni
ZLIB_DIR=yes ZLIB_DIR=yes

View File

@@ -73,6 +73,7 @@
#include "nsGUIEvent.h" #include "nsGUIEvent.h"
#include "nsAsyncDOMEvent.h" #include "nsAsyncDOMEvent.h"
#include "nsIDOMNodeFilter.h"
#include "nsIDOMStyleSheet.h" #include "nsIDOMStyleSheet.h"
#include "nsDOMAttribute.h" #include "nsDOMAttribute.h"
@@ -5024,11 +5025,15 @@ NS_IMETHODIMP
nsDocument::CreateNodeIterator(nsIDOMNode *aRoot, nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter,
bool aEntityReferenceExpansion, PRUint8 aOptionalArgc,
nsIDOMNodeIterator **_retval) nsIDOMNodeIterator **_retval)
{ {
*_retval = nsnull; *_retval = nsnull;
if (!aOptionalArgc) {
aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
}
if (!aRoot) if (!aRoot)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
@@ -5042,24 +5047,27 @@ nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
nsNodeIterator *iterator = new nsNodeIterator(root, nsNodeIterator *iterator = new nsNodeIterator(root,
aWhatToShow, aWhatToShow,
aFilter, aFilter);
aEntityReferenceExpansion);
NS_ENSURE_TRUE(iterator, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(iterator, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*_retval = iterator); NS_ADDREF(*_retval = iterator);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::CreateTreeWalker(nsIDOMNode *aRoot, nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter,
bool aEntityReferenceExpansion, PRUint8 aOptionalArgc,
nsIDOMTreeWalker **_retval) nsIDOMTreeWalker **_retval)
{ {
*_retval = nsnull; *_retval = nsnull;
if (!aOptionalArgc) {
aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
}
if (!aRoot) if (!aRoot)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
@@ -5073,8 +5081,7 @@ nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
nsTreeWalker* walker = new nsTreeWalker(root, nsTreeWalker* walker = new nsTreeWalker(root,
aWhatToShow, aWhatToShow,
aFilter, aFilter);
aEntityReferenceExpansion);
NS_ENSURE_TRUE(walker, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(walker, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*_retval = walker); NS_ADDREF(*_retval = walker);

View File

@@ -170,9 +170,8 @@ void nsNodeIterator::NodePointer::MoveBackward(nsINode *aParent, nsINode *aNode)
nsNodeIterator::nsNodeIterator(nsINode *aRoot, nsNodeIterator::nsNodeIterator(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter) :
bool aExpandEntityReferences) : nsTraversal(aRoot, aWhatToShow, aFilter),
nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
mDetached(false), mDetached(false),
mPointer(mRoot, true) mPointer(mRoot, true)
{ {
@@ -247,7 +246,7 @@ NS_IMETHODIMP nsNodeIterator::GetFilter(nsIDOMNodeFilter **aFilter)
/* readonly attribute boolean expandEntityReferences; */ /* readonly attribute boolean expandEntityReferences; */
NS_IMETHODIMP nsNodeIterator::GetExpandEntityReferences(bool *aExpandEntityReferences) NS_IMETHODIMP nsNodeIterator::GetExpandEntityReferences(bool *aExpandEntityReferences)
{ {
*aExpandEntityReferences = mExpandEntityReferences; *aExpandEntityReferences = false;
return NS_OK; return NS_OK;
} }

View File

@@ -63,8 +63,7 @@ public:
nsNodeIterator(nsINode *aRoot, nsNodeIterator(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter);
bool aExpandEntityReferences);
virtual ~nsNodeIterator(); virtual ~nsNodeIterator();
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED

View File

@@ -49,12 +49,10 @@
nsTraversal::nsTraversal(nsINode *aRoot, nsTraversal::nsTraversal(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter) :
bool aExpandEntityReferences) :
mRoot(aRoot), mRoot(aRoot),
mWhatToShow(aWhatToShow), mWhatToShow(aWhatToShow),
mFilter(aFilter), mFilter(aFilter),
mExpandEntityReferences(aExpandEntityReferences),
mInAcceptNode(false) mInAcceptNode(false)
{ {
NS_ASSERTION(aRoot, "invalid root in call to nsTraversal constructor"); NS_ASSERTION(aRoot, "invalid root in call to nsTraversal constructor");

View File

@@ -54,15 +54,13 @@ class nsTraversal
public: public:
nsTraversal(nsINode *aRoot, nsTraversal(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter);
bool aExpandEntityReferences);
virtual ~nsTraversal(); virtual ~nsTraversal();
protected: protected:
nsCOMPtr<nsINode> mRoot; nsCOMPtr<nsINode> mRoot;
PRUint32 mWhatToShow; PRUint32 mWhatToShow;
nsCOMPtr<nsIDOMNodeFilter> mFilter; nsCOMPtr<nsIDOMNodeFilter> mFilter;
bool mExpandEntityReferences;
bool mInAcceptNode; bool mInAcceptNode;
/* /*

View File

@@ -58,9 +58,8 @@
nsTreeWalker::nsTreeWalker(nsINode *aRoot, nsTreeWalker::nsTreeWalker(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter) :
bool aExpandEntityReferences) : nsTraversal(aRoot, aWhatToShow, aFilter),
nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
mCurrentNode(aRoot) mCurrentNode(aRoot)
{ {
} }
@@ -127,7 +126,7 @@ NS_IMETHODIMP nsTreeWalker::GetFilter(nsIDOMNodeFilter * *aFilter)
NS_IMETHODIMP NS_IMETHODIMP
nsTreeWalker::GetExpandEntityReferences(bool *aExpandEntityReferences) nsTreeWalker::GetExpandEntityReferences(bool *aExpandEntityReferences)
{ {
*aExpandEntityReferences = mExpandEntityReferences; *aExpandEntityReferences = false;
return NS_OK; return NS_OK;
} }

View File

@@ -63,8 +63,7 @@ public:
nsTreeWalker(nsINode *aRoot, nsTreeWalker(nsINode *aRoot,
PRUint32 aWhatToShow, PRUint32 aWhatToShow,
nsIDOMNodeFilter *aFilter, nsIDOMNodeFilter *aFilter);
bool aExpandEntityReferences);
virtual ~nsTreeWalker(); virtual ~nsTreeWalker();
NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeWalker) NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeWalker)

View File

@@ -542,6 +542,7 @@ _TEST_FILES2 = \
test_bug708620.html \ test_bug708620.html \
file_bug708620.html \ file_bug708620.html \
file_bug708620-2.html \ file_bug708620-2.html \
test_bug698384.html \
$(NULL) $(NULL)
_CHROME_FILES = \ _CHROME_FILES = \

View File

@@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=698384
-->
<head>
<title>Test for Bug 698384</title>
<script type="text/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"
type="text/javascript"></script>
<link rel="stylesheet" type="text/css"
href="/tests/SimpleTest/test.css" />
</head>
<body onload="runTests();">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=698384">
Mozilla Bug 698384</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="text/javascript">
/*
Checks to see if default parameter handling is correct when 0, 1
or 2 parameters are passed.
If one is only passed, aFilter should default to null
If none are passed, aFilter should be null and aWhatToShow should
be NodeFilter.SHOW_ALL
*/
SimpleTest.waitForExplicitFinish();
var content = $('content'),
ni;
content.innerHTML = ('<span id="A"><\/span><span id="B"><\/span>'
+ '<span id="C"><\/span>');
function runTests() {
// Test NodeIterator when no optional arguments are given
ni = document.createNodeIterator(content);
is(ni.whatToShow, NodeFilter.SHOW_ALL, "whatToShow should be " +
"NodeFilter.SHOW_ALL when both " +
" optionals are not given");
is(ni.filter, null, "filter should be defaulted to null when both " +
" optionals are not given");
// Test NodeIterator when first optional is passed
ni = document.createNodeIterator(content, NodeFilter.SHOW_ELEMENT);
is(ni.filter, null, "filter should be defaulted to null when only " +
" first argument is passed");
is(ni.whatToShow, NodeFilter.SHOW_ELEMENT, "whatToShow should " +
"properly be set to NodeFilter.SHOW_ELEMENT when whatToShow is " +
"provided and filter is not");
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@@ -816,7 +816,7 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener)
} }
#endif #endif
nsJSContext::GarbageCollectNow(); nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
nsJSContext::CycleCollectNow(aListener); nsJSContext::CycleCollectNow(aListener);
return NS_OK; return NS_OK;

View File

@@ -2272,7 +2272,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->mChromeEventHandler = mChromeEventHandler; newInnerWindow->mChromeEventHandler = mChromeEventHandler;
} }
mContext->GC(); mContext->GC(js::gcreason::SET_NEW_DOCUMENT);
mContext->DidInitializeContext(); mContext->DidInitializeContext();
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) { if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
@@ -2429,7 +2429,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
} }
if (mContext) { if (mContext) {
mContext->GC(); mContext->GC(js::gcreason::SET_DOC_SHELL);
mContext->FinalizeContext(); mContext->FinalizeContext();
mContext = nsnull; mContext = nsnull;
} }

View File

@@ -43,6 +43,7 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIProgrammingLanguage.h" #include "nsIProgrammingLanguage.h"
#include "jsfriendapi.h"
#include "jspubtd.h" #include "jspubtd.h"
class nsIScriptGlobalObject; class nsIScriptGlobalObject;
@@ -354,7 +355,7 @@ public:
* *
* @return NS_OK if the method is successful * @return NS_OK if the method is successful
*/ */
virtual void GC() = 0; virtual void GC(js::gcreason::Reason aReason) = 0;
/** /**
* Inform the context that a script was evaluated. * Inform the context that a script was evaluated.

View File

@@ -203,7 +203,7 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData) const PRUnichar* aData)
{ {
if (sGCOnMemoryPressure) { if (sGCOnMemoryPressure) {
nsJSContext::GarbageCollectNow(true); nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking);
nsJSContext::CycleCollectNow(); nsJSContext::CycleCollectNow();
} }
return NS_OK; return NS_OK;
@@ -1111,7 +1111,7 @@ nsJSContext::DestroyJSContext()
js_options_dot_str, this); js_options_dot_str, this);
if (mGCOnDestruction) { if (mGCOnDestruction) {
PokeGC(); PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
} }
// Let xpconnect destroy the JSContext when it thinks the time is right. // Let xpconnect destroy the JSContext when it thinks the time is right.
@@ -3220,7 +3220,7 @@ nsJSContext::ScriptExecuted()
//static //static
void void
nsJSContext::GarbageCollectNow(bool shrinkingGC) nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
{ {
NS_TIME_FUNCTION_MIN(1.0); NS_TIME_FUNCTION_MIN(1.0);
SAMPLE_LABEL("GC", "GarbageCollectNow"); SAMPLE_LABEL("GC", "GarbageCollectNow");
@@ -3238,7 +3238,7 @@ nsJSContext::GarbageCollectNow(bool shrinkingGC)
sLoadingInProgress = false; sLoadingInProgress = false;
if (nsContentUtils::XPConnect()) { if (nsContentUtils::XPConnect()) {
nsContentUtils::XPConnect()->GarbageCollect(shrinkingGC); nsContentUtils::XPConnect()->GarbageCollect(reason, gckind);
} }
} }
@@ -3276,7 +3276,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener)
// If we collected a substantial amount of cycles, poke the GC since more objects // If we collected a substantial amount of cycles, poke the GC since more objects
// might be unreachable now. // might be unreachable now.
if (sCCollectedWaitingForGC > 250) { if (sCCollectedWaitingForGC > 250) {
PokeGC(); PokeGC(js::gcreason::CC_WAITING);
} }
PRTime now = PR_Now(); PRTime now = PR_Now();
@@ -3315,7 +3315,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
{ {
NS_RELEASE(sGCTimer); NS_RELEASE(sGCTimer);
nsJSContext::GarbageCollectNow(); uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason), nsGCNormal);
} }
void void
@@ -3359,12 +3360,12 @@ nsJSContext::LoadEnd()
// Its probably a good idea to GC soon since we have finished loading. // Its probably a good idea to GC soon since we have finished loading.
sLoadingInProgress = false; sLoadingInProgress = false;
PokeGC(); PokeGC(js::gcreason::LOAD_END);
} }
// static // static
void void
nsJSContext::PokeGC() nsJSContext::PokeGC(js::gcreason::Reason aReason)
{ {
if (sGCTimer) { if (sGCTimer) {
// There's already a timer for GC'ing, just return // There's already a timer for GC'ing, just return
@@ -3380,7 +3381,7 @@ nsJSContext::PokeGC()
static bool first = true; static bool first = true;
sGCTimer->InitWithFuncCallback(GCTimerFired, nsnull, sGCTimer->InitWithFuncCallback(GCTimerFired, reinterpret_cast<void *>(aReason),
first first
? NS_FIRST_GC_DELAY ? NS_FIRST_GC_DELAY
: NS_GC_DELAY, : NS_GC_DELAY,
@@ -3473,9 +3474,9 @@ nsJSContext::KillCCTimer()
} }
void void
nsJSContext::GC() nsJSContext::GC(js::gcreason::Reason aReason)
{ {
PokeGC(); PokeGC(aReason);
} }
static void static void
@@ -3513,7 +3514,7 @@ DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
// probably a time of heavy activity and we want to delay // probably a time of heavy activity and we want to delay
// the full GC, but we do want it to happen eventually. // the full GC, but we do want it to happen eventually.
if (comp) { if (comp) {
nsJSContext::PokeGC(); nsJSContext::PokeGC(js::gcreason::POST_COMPARTMENT);
// We poked the GC, so we can kill any pending CC here. // We poked the GC, so we can kill any pending CC here.
nsJSContext::KillCCTimer(); nsJSContext::KillCCTimer();

View File

@@ -41,10 +41,12 @@
#include "nsIScriptRuntime.h" #include "nsIScriptRuntime.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "jsapi.h" #include "jsapi.h"
#include "jsfriendapi.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsIXPCScriptNotify.h" #include "nsIXPCScriptNotify.h"
#include "prtime.h" #include "prtime.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIXPConnect.h"
class nsIXPConnectJSObjectHolder; class nsIXPConnectJSObjectHolder;
class nsRootedJSValueArray; class nsRootedJSValueArray;
@@ -179,11 +181,11 @@ public:
static void LoadStart(); static void LoadStart();
static void LoadEnd(); static void LoadEnd();
static void GarbageCollectNow(bool shrinkingGC = false); static void GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind = nsGCNormal);
static void ShrinkGCBuffersNow(); static void ShrinkGCBuffersNow();
static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull); static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull);
static void PokeGC(); static void PokeGC(js::gcreason::Reason aReason);
static void KillGCTimer(); static void KillGCTimer();
static void PokeShrinkGCBuffers(); static void PokeShrinkGCBuffers();
@@ -193,7 +195,7 @@ public:
static void MaybePokeCC(); static void MaybePokeCC();
static void KillCCTimer(); static void KillCCTimer();
virtual void GC(); virtual void GC(js::gcreason::Reason aReason);
protected: protected:
nsresult InitializeExternalClasses(); nsresult InitializeExternalClasses();

View File

@@ -66,7 +66,7 @@ interface nsIDOMLocation;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/ */
[scriptable, uuid(5c3bff4d-ae7f-4c93-948c-519589672c30)] [scriptable, uuid(d7cdd08e-1bfd-4bc3-9742-d66586781ee2)]
interface nsIDOMDocument : nsIDOMNode interface nsIDOMDocument : nsIDOMNode
{ {
readonly attribute nsIDOMDocumentType doctype; readonly attribute nsIDOMDocumentType doctype;
@@ -118,16 +118,14 @@ interface nsIDOMDocument : nsIDOMNode
*/ */
nsIDOMRange createRange(); nsIDOMRange createRange();
nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root, [optional_argc] nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
in unsigned long whatToShow, [optional] in unsigned long whatToShow,
in nsIDOMNodeFilter filter, [optional] in nsIDOMNodeFilter filter)
in boolean entityReferenceExpansion) raises(DOMException);
raises(DOMException); [optional_argc] nsIDOMTreeWalker createTreeWalker(in nsIDOMNode root,
nsIDOMTreeWalker createTreeWalker(in nsIDOMNode root, [optional] in unsigned long whatToShow,
in unsigned long whatToShow, [optional] in nsIDOMNodeFilter filter)
in nsIDOMNodeFilter filter, raises(DOMException);
in boolean entityReferenceExpansion)
raises(DOMException);
nsIDOMEvent createEvent(in DOMString eventType) nsIDOMEvent createEvent(in DOMString eventType)
raises(DOMException); raises(DOMException);

View File

@@ -1,61 +0,0 @@
/* -*- Mode: IDL; 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 this file as it was released on May 1 2001.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
#include "domstubs.idl"
interface nsIDOMNodeIterator;
interface nsIDOMNodeFilter;
interface nsIDOMTreeWalker;
[scriptable, uuid(13f236c0-47f8-11d5-b6a3-009027446e84)]
// Introduced in DOM Level 2:
interface nsIDOMDocumentTraversal : nsISupports
{
nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
in unsigned long whatToShow,
in nsIDOMNodeFilter filter,
in boolean entityReferenceExpansion)
raises(DOMException);
nsIDOMTreeWalker createTreeWalker(in nsIDOMNode root,
in unsigned long whatToShow,
in nsIDOMNodeFilter filter,
in boolean entityReferenceExpansion)
raises(DOMException);
};

View File

@@ -44,7 +44,7 @@ interface nsIDOMNodeFilter;
[scriptable, uuid(5af83f50-c8d5-4824-be29-1aa9d640bacb)] [scriptable, uuid(5af83f50-c8d5-4824-be29-1aa9d640bacb)]
// Introduced in DOM Level 2: // Introduced in DOM Level 2, updated to DOM Level 4:
interface nsIDOMNodeIterator : nsISupports interface nsIDOMNodeIterator : nsISupports
{ {
readonly attribute nsIDOMNode root; readonly attribute nsIDOMNode root;

View File

@@ -800,14 +800,14 @@ ContentChild::GetIndexedDBPath()
bool bool
ContentChild::RecvGarbageCollect() ContentChild::RecvGarbageCollect()
{ {
nsJSContext::GarbageCollectNow(); nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
return true; return true;
} }
bool bool
ContentChild::RecvCycleCollect() ContentChild::RecvCycleCollect()
{ {
nsJSContext::GarbageCollectNow(); nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
nsJSContext::CycleCollectNow(); nsJSContext::CycleCollectNow();
return true; return true;
} }

View File

@@ -634,8 +634,6 @@ nsJSONListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
nsIInputStream *aStream, nsIInputStream *aStream,
PRUint32 aOffset, PRUint32 aLength) PRUint32 aOffset, PRUint32 aLength)
{ {
PRUint32 contentLength;
aStream->Available(&contentLength);
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (mNeedsConverter && mSniffBuffer.Length() < 4) { if (mNeedsConverter && mSniffBuffer.Length() < 4) {

View File

@@ -3794,10 +3794,10 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
AssertIsOnWorkerThread(); AssertIsOnWorkerThread();
if (aShrinking) { if (aShrinking) {
JS_ShrinkingGC(aCx); js::ShrinkingGC(aCx, js::gcreason::DOM_WORKER);
} }
else { else {
JS_GC(aCx); js::GCForReason(aCx, js::gcreason::DOM_WORKER);
} }
if (aCollectChildren) { if (aCollectChildren) {

View File

@@ -486,7 +486,7 @@ GetTextNode(nsISelection *selection, nsEditor *editor) {
// if node is null, return it to indicate there's no text // if node is null, return it to indicate there's no text
NS_ENSURE_TRUE(node, nsnull); NS_ENSURE_TRUE(node, nsnull);
// This should be the root node, walk the tree looking for text nodes // This should be the root node, walk the tree looking for text nodes
nsNodeIterator iter(node, nsIDOMNodeFilter::SHOW_TEXT, nsnull, true); nsNodeIterator iter(node, nsIDOMNodeFilter::SHOW_TEXT, nsnull);
while (!editor->IsTextNode(selNode)) { while (!editor->IsTextNode(selNode)) {
if (NS_FAILED(res = iter.NextNode(getter_AddRefs(selNode))) || !selNode) { if (NS_FAILED(res = iter.NextNode(getter_AddRefs(selNode))) || !selNode) {
return nsnull; return nsnull;

View File

@@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include <stdio.h> #include <stdio.h>
#include <ctype.h>
#include "jscntxt.h" #include "jscntxt.h"
#include "jscrashformat.h" #include "jscrashformat.h"
@@ -52,6 +53,22 @@
namespace js { namespace js {
namespace gcstats { namespace gcstats {
static const char *
ExplainReason(gcreason::Reason reason)
{
switch (reason) {
#define SWITCH_REASON(name) \
case gcreason::name: \
return #name;
GCREASONS(SWITCH_REASON)
default:
JS_NOT_REACHED("bad GC reason");
return "?";
#undef SWITCH_REASON
}
}
Statistics::ColumnInfo::ColumnInfo(const char *title, double t, double total) Statistics::ColumnInfo::ColumnInfo(const char *title, double t, double total)
: title(title) : title(title)
{ {
@@ -117,8 +134,8 @@ Statistics::makeTable(ColumnInfo *cols)
} }
Statistics::Statistics(JSRuntime *rt) Statistics::Statistics(JSRuntime *rt)
: runtime(rt) : runtime(rt),
, triggerReason(PUBLIC_API) //dummy reason to satisfy makeTable triggerReason(gcreason::NO_REASON)
{ {
PodArrayZero(counts); PodArrayZero(counts);
PodArrayZero(totals); PodArrayZero(totals);
@@ -178,7 +195,7 @@ struct GCCrashData
}; };
void void
Statistics::beginGC(JSCompartment *comp, Reason reason) Statistics::beginGC(JSCompartment *comp, gcreason::Reason reason)
{ {
compartment = comp; compartment = comp;
@@ -276,7 +293,6 @@ Statistics::endGC()
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) { if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
(*cb)(JS_TELEMETRY_GC_REASON, triggerReason); (*cb)(JS_TELEMETRY_GC_REASON, triggerReason);
(*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, compartment ? 1 : 0); (*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, compartment ? 1 : 0);
(*cb)(JS_TELEMETRY_GC_IS_SHAPE_REGEN, 0);
(*cb)(JS_TELEMETRY_GC_MS, t(PHASE_GC)); (*cb)(JS_TELEMETRY_GC_MS, t(PHASE_GC));
(*cb)(JS_TELEMETRY_GC_MARK_MS, t(PHASE_MARK)); (*cb)(JS_TELEMETRY_GC_MARK_MS, t(PHASE_MARK));
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(PHASE_SWEEP)); (*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(PHASE_SWEEP));

View File

@@ -42,6 +42,7 @@
#include <string.h> #include <string.h>
#include "jsfriendapi.h"
#include "jspubtd.h" #include "jspubtd.h"
#include "jsutil.h" #include "jsutil.h"
@@ -50,32 +51,6 @@ struct JSCompartment;
namespace js { namespace js {
namespace gcstats { namespace gcstats {
enum Reason {
PUBLIC_API,
MAYBEGC,
LASTCONTEXT,
DESTROYCONTEXT,
LASTDITCH,
TOOMUCHMALLOC,
ALLOCTRIGGER,
CHUNK,
SHAPE,
REFILL
};
static const int NUM_REASONS = REFILL + 1;
static inline const char *
ExplainReason(Reason r)
{
static const char *strs[] = {" API", "Maybe", "LastC", "DestC", "LastD",
"Mallc", "Alloc", "Chunk", "Shape", "Refil"};
JS_ASSERT(strcmp(strs[SHAPE], "Shape") == 0 &&
sizeof(strs) / sizeof(strs[0]) == NUM_REASONS);
return strs[r];
}
enum Phase { enum Phase {
PHASE_GC, PHASE_GC,
PHASE_MARK, PHASE_MARK,
@@ -103,7 +78,7 @@ struct Statistics {
Statistics(JSRuntime *rt); Statistics(JSRuntime *rt);
~Statistics(); ~Statistics();
void beginGC(JSCompartment *comp, Reason reason); void beginGC(JSCompartment *comp, gcreason::Reason reason);
void endGC(); void endGC();
void beginPhase(Phase phase); void beginPhase(Phase phase);
@@ -122,7 +97,7 @@ struct Statistics {
FILE *fp; FILE *fp;
bool fullFormat; bool fullFormat;
Reason triggerReason; gcreason::Reason triggerReason;
JSCompartment *compartment; JSCompartment *compartment;
uint64_t phaseStarts[PHASE_LIMIT]; uint64_t phaseStarts[PHASE_LIMIT];
@@ -140,8 +115,8 @@ struct Statistics {
struct ColumnInfo { struct ColumnInfo {
const char *title; const char *title;
char str[12]; char str[32];
char totalStr[12]; char totalStr[32];
int width; int width;
ColumnInfo() {} ColumnInfo() {}
@@ -155,7 +130,8 @@ struct Statistics {
}; };
struct AutoGC { struct AutoGC {
AutoGC(Statistics &stats, JSCompartment *comp, Reason reason JS_GUARD_OBJECT_NOTIFIER_PARAM) AutoGC(Statistics &stats, JSCompartment *comp, gcreason::Reason reason
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: stats(stats) { JS_GUARD_OBJECT_NOTIFIER_INIT; stats.beginGC(comp, reason); } : stats(stats) { JS_GUARD_OBJECT_NOTIFIER_INIT; stats.beginGC(comp, reason); }
~AutoGC() { stats.endGC(); } ~AutoGC() { stats.endGC(); }

View File

@@ -0,0 +1,21 @@
function f(arr, b) {
var res = "";
var a;
if (b)
a = arr;
for (var i=100; i>-200; i--) {
if (i in a) {
res += i;
}
}
return res;
}
assertEq(f([1, , 2, 3], true), "320");
try {
f([1, , 2, 3], false);
assertEq(0, 1);
} catch(e) {
assertEq(e instanceof TypeError, true);
}

View File

@@ -735,6 +735,7 @@ JSRuntime::JSRuntime()
gcIsNeeded(0), gcIsNeeded(0),
gcWeakMapList(NULL), gcWeakMapList(NULL),
gcStats(thisFromCtor()), gcStats(thisFromCtor()),
gcTriggerReason(gcreason::NO_REASON),
gcTriggerCompartment(NULL), gcTriggerCompartment(NULL),
gcCurrentCompartment(NULL), gcCurrentCompartment(NULL),
gcCheckCompartment(NULL), gcCheckCompartment(NULL),
@@ -2857,7 +2858,7 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp)
JS_ASSERT(comp != cx->runtime->atomsCompartment); JS_ASSERT(comp != cx->runtime->atomsCompartment);
js::gc::VerifyBarriers(cx, true); js::gc::VerifyBarriers(cx, true);
js_GC(cx, comp, GC_NORMAL, gcstats::PUBLIC_API); js_GC(cx, comp, GC_NORMAL, gcreason::API);
} }
JS_PUBLIC_API(void) JS_PUBLIC_API(void)

View File

@@ -323,13 +323,13 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
#endif #endif
if (last) { if (last) {
js_GC(cx, NULL, GC_NORMAL, gcstats::LASTCONTEXT); js_GC(cx, NULL, GC_NORMAL, gcreason::LAST_CONTEXT);
/* Take the runtime down, now that it has no contexts or atoms. */ /* Take the runtime down, now that it has no contexts or atoms. */
JS_LOCK_GC(rt); JS_LOCK_GC(rt);
} else { } else {
if (mode == JSDCM_FORCE_GC) if (mode == JSDCM_FORCE_GC)
js_GC(cx, NULL, GC_NORMAL, gcstats::DESTROYCONTEXT); js_GC(cx, NULL, GC_NORMAL, gcreason::DESTROY_CONTEXT);
else if (mode == JSDCM_MAYBE_GC) else if (mode == JSDCM_MAYBE_GC)
JS_MaybeGC(cx); JS_MaybeGC(cx);
@@ -1179,7 +1179,7 @@ JSContext::runningWithTrustedPrincipals() const
JS_FRIEND_API(void) JS_FRIEND_API(void)
JSRuntime::onTooMuchMalloc() JSRuntime::onTooMuchMalloc()
{ {
TriggerGC(this, gcstats::TOOMUCHMALLOC); TriggerGC(this, gcreason::TOO_MUCH_MALLOC);
} }
JS_FRIEND_API(void *) JS_FRIEND_API(void *)

View File

@@ -318,7 +318,7 @@ struct JSRuntime
js::gcstats::Statistics gcStats; js::gcstats::Statistics gcStats;
/* The reason that an interrupt-triggered GC should be called. */ /* The reason that an interrupt-triggered GC should be called. */
js::gcstats::Reason gcTriggerReason; js::gcreason::Reason gcTriggerReason;
/* Pre-allocated space for the GC mark stack. */ /* Pre-allocated space for the GC mark stack. */
uintptr_t gcMarkStackArray[js::MARK_STACK_LENGTH]; uintptr_t gcMarkStackArray[js::MARK_STACK_LENGTH];

View File

@@ -128,9 +128,15 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj
} }
JS_FRIEND_API(void) JS_FRIEND_API(void)
JS_ShrinkingGC(JSContext *cx) js::GCForReason(JSContext *cx, gcreason::Reason reason)
{ {
js_GC(cx, NULL, GC_SHRINK, gcstats::PUBLIC_API); js_GC(cx, NULL, GC_NORMAL, reason);
}
JS_FRIEND_API(void)
js::ShrinkingGC(JSContext *cx, gcreason::Reason reason)
{
js_GC(cx, NULL, GC_SHRINK, reason);
} }
JS_FRIEND_API(void) JS_FRIEND_API(void)

View File

@@ -72,9 +72,6 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj
extern JS_FRIEND_API(uint32_t) extern JS_FRIEND_API(uint32_t)
JS_ObjectCountDynamicSlots(JSObject *obj); JS_ObjectCountDynamicSlots(JSObject *obj);
extern JS_FRIEND_API(void)
JS_ShrinkingGC(JSContext *cx);
extern JS_FRIEND_API(void) extern JS_FRIEND_API(void)
JS_ShrinkGCBuffers(JSRuntime *rt); JS_ShrinkGCBuffers(JSRuntime *rt);
@@ -101,7 +98,6 @@ JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape);
enum { enum {
JS_TELEMETRY_GC_REASON, JS_TELEMETRY_GC_REASON,
JS_TELEMETRY_GC_IS_COMPARTMENTAL, JS_TELEMETRY_GC_IS_COMPARTMENTAL,
JS_TELEMETRY_GC_IS_SHAPE_REGEN,
JS_TELEMETRY_GC_MS, JS_TELEMETRY_GC_MS,
JS_TELEMETRY_GC_MARK_MS, JS_TELEMETRY_GC_MARK_MS,
JS_TELEMETRY_GC_SWEEP_MS JS_TELEMETRY_GC_SWEEP_MS
@@ -572,6 +568,56 @@ GetRuntimeCompartments(JSRuntime *rt);
extern JS_FRIEND_API(size_t) extern JS_FRIEND_API(size_t)
SizeOfJSContext(); SizeOfJSContext();
#define GCREASONS(D) \
/* Reasons internal to the JS engine */ \
D(API) \
D(MAYBEGC) \
D(LAST_CONTEXT) \
D(DESTROY_CONTEXT) \
D(LAST_DITCH) \
D(TOO_MUCH_MALLOC) \
D(ALLOC_TRIGGER) \
D(UNUSED1) /* was CHUNK */ \
D(UNUSED2) /* was SHAPE */ \
D(UNUSED3) /* was REFILL */ \
\
/* Reasons from Firefox */ \
D(DOM_WINDOW_UTILS) \
D(COMPONENT_UTILS) \
D(MEM_PRESSURE) \
D(CC_WAITING) \
D(CC_FORCED) \
D(LOAD_END) \
D(POST_COMPARTMENT) \
D(PAGE_HIDE) \
D(NSJSCONTEXT_DESTROY) \
D(SET_NEW_DOCUMENT) \
D(SET_DOC_SHELL) \
D(DOM_UTILS) \
D(DOM_IPC) \
D(DOM_WORKER) \
D(INTER_SLICE_GC) \
D(REFRESH_FRAME)
namespace gcreason {
/* GCReasons will end up looking like JSGC_MAYBEGC */
enum Reason {
#define MAKE_REASON(name) name,
GCREASONS(MAKE_REASON)
#undef MAKE_REASON
NO_REASON,
NUM_REASONS
};
} /* namespace gcreason */
extern JS_FRIEND_API(void)
GCForReason(JSContext *cx, gcreason::Reason reason);
extern JS_FRIEND_API(void)
ShrinkingGC(JSContext *cx, gcreason::Reason reason);
extern JS_FRIEND_API(bool) extern JS_FRIEND_API(bool)
IsIncrementalBarrierNeeded(JSRuntime *rt); IsIncrementalBarrierNeeded(JSRuntime *rt);

View File

@@ -742,7 +742,7 @@ Chunk::allocateArena(JSCompartment *comp, AllocKind thingKind)
rt->gcBytes += ArenaSize; rt->gcBytes += ArenaSize;
comp->gcBytes += ArenaSize; comp->gcBytes += ArenaSize;
if (comp->gcBytes >= comp->gcTriggerBytes) if (comp->gcBytes >= comp->gcTriggerBytes)
TriggerCompartmentGC(comp, gcstats::ALLOCTRIGGER); TriggerCompartmentGC(comp, gcreason::ALLOC_TRIGGER);
return aheader; return aheader;
} }
@@ -1647,7 +1647,7 @@ RunLastDitchGC(JSContext *cx)
/* The last ditch GC preserves all atoms. */ /* The last ditch GC preserves all atoms. */
AutoKeepAtoms keep(rt); AutoKeepAtoms keep(rt);
js_GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcstats::LASTDITCH); js_GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcreason::LAST_DITCH);
} }
/* static */ void * /* static */ void *
@@ -2137,7 +2137,7 @@ MarkRuntime(JSTracer *trc)
} }
void void
TriggerGC(JSRuntime *rt, gcstats::Reason reason) TriggerGC(JSRuntime *rt, gcreason::Reason reason)
{ {
JS_ASSERT(rt->onOwnerThread()); JS_ASSERT(rt->onOwnerThread());
@@ -2152,7 +2152,7 @@ TriggerGC(JSRuntime *rt, gcstats::Reason reason)
} }
void void
TriggerCompartmentGC(JSCompartment *comp, gcstats::Reason reason) TriggerCompartmentGC(JSCompartment *comp, gcreason::Reason reason)
{ {
JSRuntime *rt = comp->rt; JSRuntime *rt = comp->rt;
JS_ASSERT(!rt->gcRunning); JS_ASSERT(!rt->gcRunning);
@@ -2198,18 +2198,18 @@ MaybeGC(JSContext *cx)
JS_ASSERT(rt->onOwnerThread()); JS_ASSERT(rt->onOwnerThread());
if (rt->gcZeal()) { if (rt->gcZeal()) {
js_GC(cx, NULL, GC_NORMAL, gcstats::MAYBEGC); js_GC(cx, NULL, GC_NORMAL, gcreason::MAYBEGC);
return; return;
} }
JSCompartment *comp = cx->compartment; JSCompartment *comp = cx->compartment;
if (rt->gcIsNeeded) { if (rt->gcIsNeeded) {
js_GC(cx, (comp == rt->gcTriggerCompartment) ? comp : NULL, GC_NORMAL, gcstats::MAYBEGC); js_GC(cx, (comp == rt->gcTriggerCompartment) ? comp : NULL, GC_NORMAL, gcreason::MAYBEGC);
return; return;
} }
if (comp->gcBytes > 8192 && comp->gcBytes >= 3 * (comp->gcTriggerBytes / 4)) { if (comp->gcBytes > 8192 && comp->gcBytes >= 3 * (comp->gcTriggerBytes / 4)) {
js_GC(cx, (rt->gcMode == JSGC_MODE_COMPARTMENT) ? comp : NULL, GC_NORMAL, gcstats::MAYBEGC); js_GC(cx, (rt->gcMode == JSGC_MODE_COMPARTMENT) ? comp : NULL, GC_NORMAL, gcreason::MAYBEGC);
return; return;
} }
@@ -2223,7 +2223,7 @@ MaybeGC(JSContext *cx)
if (rt->gcChunkAllocationSinceLastGC || if (rt->gcChunkAllocationSinceLastGC ||
rt->gcNumArenasFreeCommitted > FreeCommittedArenasThreshold) rt->gcNumArenasFreeCommitted > FreeCommittedArenasThreshold)
{ {
js_GC(cx, NULL, GC_SHRINK, gcstats::MAYBEGC); js_GC(cx, NULL, GC_SHRINK, gcreason::MAYBEGC);
} else { } else {
rt->gcNextFullGCTime = now + GC_IDLE_FULL_SPAN; rt->gcNextFullGCTime = now + GC_IDLE_FULL_SPAN;
} }
@@ -2966,7 +2966,7 @@ GCCycle(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind)
} }
void void
js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind, gcstats::Reason reason) js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind, gcreason::Reason reason)
{ {
JSRuntime *rt = cx->runtime; JSRuntime *rt = cx->runtime;
JS_AbortIfWrongThread(rt); JS_AbortIfWrongThread(rt);

View File

@@ -1382,11 +1382,11 @@ MarkContext(JSTracer *trc, JSContext *acx);
/* Must be called with GC lock taken. */ /* Must be called with GC lock taken. */
extern void extern void
TriggerGC(JSRuntime *rt, js::gcstats::Reason reason); TriggerGC(JSRuntime *rt, js::gcreason::Reason reason);
/* Must be called with GC lock taken. */ /* Must be called with GC lock taken. */
extern void extern void
TriggerCompartmentGC(JSCompartment *comp, js::gcstats::Reason reason); TriggerCompartmentGC(JSCompartment *comp, js::gcreason::Reason reason);
extern void extern void
MaybeGC(JSContext *cx); MaybeGC(JSContext *cx);
@@ -1409,7 +1409,7 @@ typedef enum JSGCInvocationKind {
/* Pass NULL for |comp| to get a full GC. */ /* Pass NULL for |comp| to get a full GC. */
extern void extern void
js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind, js::gcstats::Reason r); js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind, js::gcreason::Reason r);
namespace js { namespace js {

View File

@@ -791,6 +791,20 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
return branch32(cond, extent, key.reg()); return branch32(cond, extent, key.reg());
} }
Jump guardElementNotHole(RegisterID elements, const Int32Key &key) {
Jump jmp;
if (key.isConstant()) {
Address slot(elements, key.index() * sizeof(Value));
jmp = guardNotHole(slot);
} else {
BaseIndex slot(elements, key.reg(), JSVAL_SCALE);
jmp = guardNotHole(slot);
}
return jmp;
}
// Load a jsval from an array slot, given a key. |objReg| is clobbered. // Load a jsval from an array slot, given a key. |objReg| is clobbered.
FastArrayLoadFails fastArrayLoad(RegisterID objReg, const Int32Key &key, FastArrayLoadFails fastArrayLoad(RegisterID objReg, const Int32Key &key,
RegisterID typeReg, RegisterID dataReg) { RegisterID typeReg, RegisterID dataReg) {

View File

@@ -2966,11 +2966,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_IN) BEGIN_CASE(JSOP_IN)
{ {
prepareStubCall(Uses(2)); jsop_in();
INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
frame.popn(2);
frame.takeReg(Registers::ReturnReg);
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
} }
END_CASE(JSOP_IN) END_CASE(JSOP_IN)
@@ -7448,6 +7444,76 @@ mjit::Compiler::jsop_toid()
stubcc.rejoin(Changes(1)); stubcc.rejoin(Changes(1));
} }
void
mjit::Compiler::jsop_in()
{
FrameEntry *obj = frame.peek(-1);
FrameEntry *id = frame.peek(-2);
if (cx->typeInferenceEnabled() && id->isType(JSVAL_TYPE_INT32)) {
types::TypeSet *types = analysis->poppedTypes(PC, 0);
if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY) &&
!types::ArrayPrototypeHasIndexedProperty(cx, outerScript))
{
bool isPacked = !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY);
if (!obj->isTypeKnown()) {
Jump guard = frame.testObject(Assembler::NotEqual, obj);
stubcc.linkExit(guard, Uses(2));
}
RegisterID dataReg = frame.copyDataIntoReg(obj);
Int32Key key = id->isConstant()
? Int32Key::FromConstant(id->getValue().toInt32())
: Int32Key::FromRegister(frame.tempRegForData(id));
masm.loadPtr(Address(dataReg, JSObject::offsetOfElements()), dataReg);
// Guard on the array's initialized length.
Jump initlenGuard = masm.guardArrayExtent(ObjectElements::offsetOfInitializedLength(),
dataReg, key, Assembler::BelowOrEqual);
// Guard to make sure we don't have a hole. Skip it if the array is packed.
MaybeJump holeCheck;
if (!isPacked)
holeCheck = masm.guardElementNotHole(dataReg, key);
masm.move(Imm32(1), dataReg);
Jump done = masm.jump();
Label falseBranch = masm.label();
initlenGuard.linkTo(falseBranch, &masm);
if (!isPacked)
holeCheck.getJump().linkTo(falseBranch, &masm);
masm.move(Imm32(0), dataReg);
done.linkTo(masm.label(), &masm);
stubcc.leave();
OOL_STUBCALL_USES(stubs::In, REJOIN_PUSH_BOOLEAN, Uses(2));
frame.popn(2);
if (dataReg != Registers::ReturnReg)
stubcc.masm.move(Registers::ReturnReg, dataReg);
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, dataReg);
stubcc.rejoin(Changes(2));
return;
}
}
prepareStubCall(Uses(2));
INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
frame.popn(2);
frame.takeReg(Registers::ReturnReg);
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
}
/* /*
* For any locals or args which we know to be integers but are treated as * For any locals or args which we know to be integers but are treated as
* doubles by the type inference, convert to double. These will be assumed to be * doubles by the type inference, convert to double. These will be assumed to be

View File

@@ -753,6 +753,7 @@ private:
CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused); CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused);
bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused); bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
void jsop_pos(); void jsop_pos();
void jsop_in();
static inline Assembler::Condition static inline Assembler::Condition
GetCompareCondition(JSOp op, JSOp fused) GetCompareCondition(JSOp op, JSOp fused)

View File

@@ -390,9 +390,15 @@ interface nsIXPCFunctionThisTranslator : nsISupports
#define NS_XPCONNECT_CID \ #define NS_XPCONNECT_CID \
{ 0xcb6593e0, 0xf9b2, 0x11d2, \ { 0xcb6593e0, 0xf9b2, 0x11d2, \
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
enum nsGCType {
nsGCNormal,
nsGCShrinking,
nsGCIncremental
};
%} %}
[uuid(241e6db3-e018-4d99-b976-c782a05f9c77)] [uuid(686bb1d0-4711-11e1-b86c-0800200c9a66)]
interface nsIXPConnect : nsISupports interface nsIXPConnect : nsISupports
{ {
%{ C++ %{ C++
@@ -723,8 +729,10 @@ interface nsIXPConnect : nsISupports
/** /**
* Trigger a JS garbage collection. * Trigger a JS garbage collection.
* Use a js::gcreason::Reason from jsfriendapi.h for the kind.
* Use the nsGCType enum for the kind.
*/ */
void GarbageCollect(in boolean shrinkingGC); void GarbageCollect(in PRUint32 reason, in PRUint32 kind);
/** /**
* Define quick stubs on the given object, @a proto. * Define quick stubs on the given object, @a proto.

View File

@@ -3600,7 +3600,7 @@ nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx,
NS_IMETHODIMP NS_IMETHODIMP
nsXPCComponents_Utils::ForceGC(JSContext *cx) nsXPCComponents_Utils::ForceGC(JSContext *cx)
{ {
JS_GC(cx); js::GCForReason(cx, js::gcreason::COMPONENT_UTILS);
return NS_OK; return NS_OK;
} }
@@ -3608,7 +3608,7 @@ nsXPCComponents_Utils::ForceGC(JSContext *cx)
NS_IMETHODIMP NS_IMETHODIMP
nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx) nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx)
{ {
JS_ShrinkingGC(cx); js::ShrinkingGC(cx, js::gcreason::COMPONENT_UTILS);
return NS_OK; return NS_OK;
} }
@@ -3636,9 +3636,9 @@ class PreciseGCRunnable : public nsRunnable
} }
if (mShrinking) if (mShrinking)
JS_ShrinkingGC(mCx); js::ShrinkingGC(mCx, js::gcreason::COMPONENT_UTILS);
else else
JS_GC(mCx); js::GCForReason(mCx, js::gcreason::COMPONENT_UTILS);
mCallback->Callback(); mCallback->Callback();
return NS_OK; return NS_OK;

View File

@@ -1870,9 +1870,6 @@ AccumulateTelemetryCallback(int id, uint32_t sample)
case JS_TELEMETRY_GC_IS_COMPARTMENTAL: case JS_TELEMETRY_GC_IS_COMPARTMENTAL:
Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample); Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample);
break; break;
case JS_TELEMETRY_GC_IS_SHAPE_REGEN:
Telemetry::Accumulate(Telemetry::GC_IS_SHAPE_REGEN, sample);
break;
case JS_TELEMETRY_GC_MS: case JS_TELEMETRY_GC_MS:
Telemetry::Accumulate(Telemetry::GC_MS, sample); Telemetry::Accumulate(Telemetry::GC_MS, sample);
break; break;

View File

@@ -365,7 +365,7 @@ nsXPConnect::NeedCollect()
} }
void void
nsXPConnect::Collect(bool shrinkingGC) nsXPConnect::Collect(PRUint32 reason, PRUint32 kind)
{ {
// We're dividing JS objects into 2 categories: // We're dividing JS objects into 2 categories:
// //
@@ -424,16 +424,20 @@ nsXPConnect::Collect(bool shrinkingGC)
// XPCCallContext::Init we disable the conservative scanner if that call // XPCCallContext::Init we disable the conservative scanner if that call
// has started the request on this thread. // has started the request on this thread.
js::AutoSkipConservativeScan ascs(cx); js::AutoSkipConservativeScan ascs(cx);
if (shrinkingGC) MOZ_ASSERT(reason < js::gcreason::NUM_REASONS);
JS_ShrinkingGC(cx); js::gcreason::Reason gcreason = (js::gcreason::Reason)reason;
else if (kind == nsGCShrinking) {
JS_GC(cx); js::ShrinkingGC(cx, gcreason);
} else {
MOZ_ASSERT(kind == nsGCNormal);
js::GCForReason(cx, gcreason);
}
} }
NS_IMETHODIMP NS_IMETHODIMP
nsXPConnect::GarbageCollect(bool shrinkingGC) nsXPConnect::GarbageCollect(PRUint32 reason, PRUint32 kind)
{ {
Collect(shrinkingGC); Collect(reason, kind);
return NS_OK; return NS_OK;
} }

View File

@@ -549,7 +549,7 @@ public:
virtual nsresult FinishCycleCollection(); virtual nsresult FinishCycleCollection();
virtual nsCycleCollectionParticipant *ToParticipant(void *p); virtual nsCycleCollectionParticipant *ToParticipant(void *p);
virtual bool NeedCollect(); virtual bool NeedCollect();
virtual void Collect(bool shrinkingGC=false); virtual void Collect(PRUint32 reason, PRUint32 kind);
#ifdef DEBUG_CC #ifdef DEBUG_CC
virtual void PrintAllReferencesTo(void *p); virtual void PrintAllReferencesTo(void *p);
#endif #endif

View File

@@ -198,6 +198,8 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "jsfriendapi.h"
using namespace mozilla; using namespace mozilla;
#ifdef NS_DEBUG #ifdef NS_DEBUG
@@ -1287,7 +1289,7 @@ DocumentViewerImpl::PageHide(bool aIsUnload)
if (aIsUnload) { if (aIsUnload) {
// Poke the GC. The window might be collectable garbage now. // Poke the GC. The window might be collectable garbage now.
nsJSContext::PokeGC(); nsJSContext::PokeGC(js::gcreason::PAGE_HIDE);
// if Destroy() was called during OnPageHide(), mDocument is nsnull. // if Destroy() was called during OnPageHide(), mDocument is nsnull.
NS_ENSURE_STATE(mDocument); NS_ENSURE_STATE(mDocument);

View File

@@ -310,7 +310,7 @@ nsContentDLF::CreateInstance(const char* aCommand,
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID)); nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get()); nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
if(pluginHost && if(pluginHost &&
NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType))) { NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType, true))) {
return CreateDocument(aCommand, return CreateDocument(aCommand,
aChannel, aLoadGroup, aChannel, aLoadGroup,
aContainer, kPluginDocumentCID, aContainer, kPluginDocumentCID,

View File

@@ -405,6 +405,11 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
ExpandableListView exList = (ExpandableListView)list; ExpandableListView exList = (ExpandableListView)list;
int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition); int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition);
int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);
// Check if long tap is on a header row
if (groupPosition < 0 || childPosition < 0)
return;
selectedItem = exList.getExpandableListAdapter().getChild(groupPosition, childPosition); selectedItem = exList.getExpandableListAdapter().getChild(groupPosition, childPosition);
Map map = (Map)selectedItem; Map map = (Map)selectedItem;

View File

@@ -52,6 +52,9 @@ SYNC_JAVA_FILES=$(shell cat $(topsrcdir)/mobile/android/sync/java-sources.mn | t
SYNC_PP_JAVA_FILES=$(shell cat $(topsrcdir)/mobile/android/sync/preprocess-sources.mn | tr '\n' ' ';) SYNC_PP_JAVA_FILES=$(shell cat $(topsrcdir)/mobile/android/sync/preprocess-sources.mn | tr '\n' ' ';)
SYNC_THIRDPARTY_JAVA_FILES=$(shell cat $(topsrcdir)/mobile/android/sync/java-third-party-sources.mn | tr '\n' ' ';) SYNC_THIRDPARTY_JAVA_FILES=$(shell cat $(topsrcdir)/mobile/android/sync/java-third-party-sources.mn | tr '\n' ' ';)
SYNC_RES_DRAWABLE=$(shell cat $(topsrcdir)/mobile/android/sync/android-drawable-resources.mn | tr '\n' ' ';) SYNC_RES_DRAWABLE=$(shell cat $(topsrcdir)/mobile/android/sync/android-drawable-resources.mn | tr '\n' ' ';)
SYNC_RES_DRAWABLE_LDPI=$(shell cat $(topsrcdir)/mobile/android/sync/android-drawable-ldpi-resources.mn | tr '\n' ' ';)
SYNC_RES_DRAWABLE_MDPI=$(shell cat $(topsrcdir)/mobile/android/sync/android-drawable-mdpi-resources.mn | tr '\n' ' ';)
SYNC_RES_DRAWABLE_HDPI=$(shell cat $(topsrcdir)/mobile/android/sync/android-drawable-hdpi-resources.mn | tr '\n' ' ';)
SYNC_RES_LAYOUT=$(shell cat $(topsrcdir)/mobile/android/sync/android-layout-resources.mn | tr '\n' ' ';) SYNC_RES_LAYOUT=$(shell cat $(topsrcdir)/mobile/android/sync/android-layout-resources.mn | tr '\n' ' ';)
SYNC_RES_VALUES=$(shell cat $(topsrcdir)/mobile/android/sync/android-values-resources.mn | tr '\n' ' ';) SYNC_RES_VALUES=$(shell cat $(topsrcdir)/mobile/android/sync/android-values-resources.mn | tr '\n' ' ';)
SYNC_RES_XML=res/xml/sync_authenticator.xml res/xml/sync_options.xml SYNC_RES_XML=res/xml/sync_authenticator.xml res/xml/sync_options.xml
@@ -143,7 +146,6 @@ FENNEC_PP_JAVA_FILES = \
db/BrowserContract.java \ db/BrowserContract.java \
db/BrowserProvider.java \ db/BrowserProvider.java \
SmsManager.java \ SmsManager.java \
SyncPreference.java \
$(NULL) $(NULL)
@@ -539,6 +541,9 @@ RES_DIRS= \
res/xml \ res/xml \
res/anim \ res/anim \
res/drawable-nodpi \ res/drawable-nodpi \
res/drawable-ldpi \
res/drawable-mdpi \
res/drawable-hdpi \
res/drawable-mdpi-v8 \ res/drawable-mdpi-v8 \
res/drawable-hdpi-v8 \ res/drawable-hdpi-v8 \
res/drawable-mdpi-v9 \ res/drawable-mdpi-v9 \
@@ -576,7 +581,10 @@ $(PP_RES_XML): $(subst res/,$(srcdir)/resources/, $(PP_RES_XML).in)
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \ $(PYTHON) $(topsrcdir)/config/Preprocessor.py \
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
AndroidManifest.xml $(FENNEC_PP_JAVA_FILES) $(SYNC_PP_JAVA_FILES) package-name.txt: % : %.in Makefile.in # AndroidManifest.xml includes these files, so they need to be marked as dependencies.
SYNC_MANIFEST_FRAGMENTS = $(wildcard $(topsrcdir)/mobile/android/sync/manifests/*.in)
AndroidManifest.xml $(FENNEC_PP_JAVA_FILES) $(SYNC_PP_JAVA_FILES) package-name.txt: % : %.in Makefile.in $(SYNC_MANIFEST_FRAGMENTS)
mkdir -p db sync/repositories/android mkdir -p db sync/repositories/android
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \ $(PYTHON) $(topsrcdir)/config/Preprocessor.py \
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
@@ -594,6 +602,21 @@ $(RES_DRAWABLE): $(addprefix $(topsrcdir)/,$(MOZ_ANDROID_DRAWABLES))
$(NSINSTALL) -D res/drawable $(NSINSTALL) -D res/drawable
$(NSINSTALL) $^ res/drawable/ $(NSINSTALL) $^ res/drawable/
RES_DRAWABLE_LDPI = $(addprefix res/drawable-ldpi/,$(notdir $(SYNC_RES_DRAWABLE_LDPI)))
$(RES_DRAWABLE_LDPI): $(addprefix $(topsrcdir)/,$(SYNC_RES_DRAWABLE_LDPI))
$(NSINSTALL) -D res/drawable-ldpi
$(NSINSTALL) $^ res/drawable-ldpi/
RES_DRAWABLE_MDPI = $(addprefix res/drawable-mdpi/,$(notdir $(SYNC_RES_DRAWABLE_MDPI)))
$(RES_DRAWABLE_MDPI): $(addprefix $(topsrcdir)/,$(SYNC_RES_DRAWABLE_MDPI))
$(NSINSTALL) -D res/drawable-mdpi
$(NSINSTALL) $^ res/drawable-mdpi/
RES_DRAWABLE_HDPI = $(addprefix res/drawable-hdpi/,$(notdir $(SYNC_RES_DRAWABLE_HDPI)))
$(RES_DRAWABLE_HDPI): $(addprefix $(topsrcdir)/,$(SYNC_RES_DRAWABLE_HDPI))
$(NSINSTALL) -D res/drawable-hdpi
$(NSINSTALL) $^ res/drawable-hdpi/
res/values/defaults.xml: $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/res/values/defaults.xml res/values/defaults.xml: $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/res/values/defaults.xml
$(NSINSTALL) -D res/values $(NSINSTALL) -D res/values
$(NSINSTALL) $^ res/values $(NSINSTALL) $^ res/values
@@ -607,10 +630,10 @@ $(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
$(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@) $(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@)
R.java: $(MOZ_APP_ICON) $(RESOURCES) $(RES_DRAWABLE) $(PP_RES_XML) res/values/defaults.xml res/drawable/sync_icon.png res/drawable/icon.png res/drawable-hdpi/icon.png res/values/strings.xml AndroidManifest.xml FORCE R.java: $(MOZ_APP_ICON) $(RESOURCES) $(RES_DRAWABLE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_MDPI) $(RES_DRAWABLE_HDPI) $(PP_RES_XML) res/values/defaults.xml res/drawable/sync_icon.png res/drawable/icon.png res/drawable-hdpi/icon.png res/values/strings.xml AndroidManifest.xml FORCE
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -J . --custom-package org.mozilla.gecko $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -J . --custom-package org.mozilla.gecko
gecko.ap_: AndroidManifest.xml res/drawable/sync_icon.png res/drawable/icon.png res/drawable-hdpi/icon.png $(RESOURCES) $(RES_DRAWABLE) $(PP_RES_XML) res/values/defaults.xml res/values/strings.xml FORCE gecko.ap_: AndroidManifest.xml res/drawable/sync_icon.png res/drawable/icon.png res/drawable-hdpi/icon.png $(RESOURCES) $(RES_DRAWABLE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_MDPI) $(RES_DRAWABLE_HDPI) $(PP_RES_XML) res/values/defaults.xml res/values/strings.xml FORCE
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@ $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
libs:: classes.dex package-name.txt libs:: classes.dex package-name.txt

View File

@@ -1,81 +0,0 @@
/* -*- 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
* 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) 2009-2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Nicholson <bnicholson@mozilla.com>
*
* 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 ***** */
#filter substitution
package org.mozilla.gecko;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
class SyncPreference extends Preference {
private static final String FEEDS_PACKAGE_NAME = "com.android.providers.subscribedfeeds";
private static final String ACCOUNT_SYNC_CLASS_NAME = "com.android.settings.AccountSyncSettings";
private static final String ACCOUNT_KEY = "account";
private static final String FENNEC_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
private static final String FENNEC_SYNC_CLASS_NAME = "org.mozilla.gecko.sync.setup.activities.SetupSyncActivity";
private static final String FENNEC_ACCOUNT_TYPE = "org.mozilla.firefox_sync";
private Context mContext;
public SyncPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@Override
protected void onClick() {
Intent intent = new Intent(Intent.ACTION_MAIN);
Account[] accounts = AccountManager.get(mContext).getAccountsByType(FENNEC_ACCOUNT_TYPE);
if (accounts.length > 0) {
// show sync account
// we assume there's exactly one sync account. see bugs 716906 and 710407.
intent.setComponent(new ComponentName(FEEDS_PACKAGE_NAME, ACCOUNT_SYNC_CLASS_NAME));
Account account = accounts[0];
intent.putExtra(ACCOUNT_KEY, account);
} else {
// show sync setup
intent.setComponent(new ComponentName(FENNEC_PACKAGE_NAME, FENNEC_SYNC_CLASS_NAME));
}
mContext.startActivity(intent);
}
}

View File

@@ -182,6 +182,7 @@ public class BrowserProvider extends ContentProvider {
// Images // Images
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "images", IMAGES); URI_MATCHER.addURI(BrowserContract.AUTHORITY, "images", IMAGES);
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "images/#", IMAGES_ID);
map = IMAGES_PROJECTION_MAP; map = IMAGES_PROJECTION_MAP;
map.put(Images._ID, Images._ID); map.put(Images._ID, Images._ID);

View File

@@ -69,7 +69,6 @@
<!ENTITY pref_font_size_large "Large"> <!ENTITY pref_font_size_large "Large">
<!ENTITY pref_font_size_xlarge "Extra Large"> <!ENTITY pref_font_size_xlarge "Extra Large">
<!ENTITY pref_use_master_password "Use master password"> <!ENTITY pref_use_master_password "Use master password">
<!ENTITY pref_sync "Sync">
<!ENTITY quit "Quit"> <!ENTITY quit "Quit">

View File

@@ -6,13 +6,18 @@
<!-- Main titles. --> <!-- Main titles. -->
<!ENTITY sync.app.name.label '&syncBrand.fullName.label;'> <!ENTITY sync.app.name.label '&syncBrand.fullName.label;'>
<!ENTITY sync.title.connect.label 'Connect to &syncBrand.shortName.label;'> <!ENTITY sync.title.connect.label 'Connect to &syncBrand.shortName.label;'>
<!ENTITY sync.title.adddevice.label 'Add a &syncBrand.fullName.label; Account'>
<!ENTITY sync.title.pair.label 'Pair a Device'> <!ENTITY sync.title.pair.label 'Pair a Device'>
<!-- J-PAKE Key Screen --> <!-- J-PAKE Key Screen -->
<!ENTITY sync.subtitle.connect.label 'To activate your new device, select “Set up &syncBrand.shortName.label;” on the device.'> <!ENTITY sync.subtitle.connect.label 'To activate your new device, select “Set up &syncBrand.shortName.label;” on the device.'>
<!ENTITY sync.subtitle.header.label 'Enter this code on your computer'>
<!ENTITY sync.subtitle.connectlocation.label 'Select “&sync.title.pair.label;” in the &syncBrand.shortName.label; section of your desktop Firefox options.'>
<!ENTITY sync.subtitle.pair.label 'To activate, select “Pair a device” on your other device.'> <!ENTITY sync.subtitle.pair.label 'To activate, select “Pair a device” on your other device.'>
<!ENTITY sync.pin.default.label '...\n...\n...\n'> <!ENTITY sync.pin.default.label '...\n...\n...\n'>
<!ENTITY sync.pin.oneline.label '...'>
<!ENTITY sync.link.show.label 'Show me how.'> <!ENTITY sync.link.show.label 'Show me how.'>
<!ENTITY sync.link.advancedsetup.label 'Advanced setup...'>
<!ENTITY sync.link.nodevice.label 'I don\&apos;t have the device with me…'> <!ENTITY sync.link.nodevice.label 'I don\&apos;t have the device with me…'>
<!-- J-PAKE Waiting Screen --> <!-- J-PAKE Waiting Screen -->

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#000000" />
<stroke android:width="1dp" android:color="#FFFFFF" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
</shape>

View File

@@ -1,23 +1,31 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<LinearLayout
android:id="@+id/account_top"
style="@style/SyncTop">
<ImageView
style="@style/SyncTopIcon" />
<TextView
style="@style/SyncTextTitle"
android:text="@string/sync_title_connect" />
</LinearLayout>
<ScrollView <ScrollView
style="@style/SyncLayout" > android:id="@+id/account_content"
style="@style/SyncLayout"
android:layout_below="@id/account_top"
android:layout_above="@+id/account_bottom">
<LinearLayout <LinearLayout
style="@style/SyncLayout" > style="@style/SyncLayout.Vertical"
android:padding="20dp" >
<TextView
style="@style/SyncTextTitle"
android:text="@string/sync_title_connect" />
<View
style="@style/SyncViewLine" />
<TextView <TextView
style="@style/SyncTextItem" style="@style/SyncTextItem"
android:text="@string/sync_subtitle_account" /> android:text="@string/sync_subtitle_account"
android:layout_marginBottom="10dp" />
<EditText android:id="@+id/usernameInput" <EditText android:id="@+id/usernameInput"
style="@style/SyncEditItem" style="@style/SyncEditItem"
@@ -43,26 +51,26 @@
style="@style/SyncEditItem" style="@style/SyncEditItem"
android:visibility="gone" android:visibility="gone"
android:hint="@string/sync_input_server" /> android:hint="@string/sync_input_server" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button
style="@style/SyncButtonCommon"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
<Button
android:id="@+id/accountConnectButton"
style="@style/SyncButtonCommon"
android:onClick="connectClickHandler"
android:clickable="false"
android:enabled="false"
android:text="@string/sync_button_connect" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</TableLayout>
<LinearLayout
android:id="@id/account_bottom"
style="@style/SyncBottom"
android:orientation="horizontal" >
<Button
style="@style/SyncButton"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
<Button
style="@style/SyncButton"
android:id="@+id/accountConnectButton"
android:onClick="connectClickHandler"
android:clickable="false"
android:enabled="false"
android:text="@string/sync_button_connect" />
</LinearLayout>
</RelativeLayout>

View File

@@ -1,65 +1,87 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<LinearLayout
android:id="@+id/setup_top"
style="@style/SyncTop" >
<ImageView
style="@style/SyncTopIcon" />
<TextView
android:id="@+id/setup_title"
style="@style/SyncTextTitle"
android:text="@string/sync_title_connect" />
</LinearLayout>
<ScrollView <ScrollView
style="@style/SyncLayout" > style="@style/SyncLayout"
android:fillViewport="true"
android:layout_below="@id/setup_top"
android:layout_above="@+id/setup_bottom" >
<LinearLayout <RelativeLayout
style="@style/SyncLayout" > style="@style/SyncLayout.Vertical"
android:layout_height="fill_parent"
android:padding="15dp" >
<TextView <TextView
android:id="@+id/setup_title" android:id="@+id/setup_header"
style="@style/SyncTextTitle" style="@style/SyncTextItem"
android:text="@string/sync_title_connect" /> android:gravity="left"
android:layout_marginTop="15dp"
<View android:text="@string/sync_subtitle_header"
android:layout_width="wrap_content" android:textStyle="bold" />
android:layout_height="2dp" <TextView
android:background="#FFFFFF" /> android:id="@+id/setup_subtitle"
style="@style/SyncTextItem"
android:layout_below="@id/setup_header"
android:gravity="left"
android:layout_marginTop="2dp"
android:text="@string/sync_subtitle_connect" />
<TextView <TextView
android:id="@+id/setup_subtitle" android:id="@+id/setup_showme"
style="@style/SyncTextItem" style="@style/SyncLinkItem"
android:layout_marginTop="10dp" android:layout_below="@id/setup_subtitle"
android:layout_marginBottom="10dp" android:layout_marginTop="2dp"
android:text="@string/sync_subtitle_pair" /> android:onClick="showClickHandler"
android:text="@string/sync_link_show" />
<TextView
style="@style/SyncLinkItem"
android:onClick="showClickHandler"
android:text="@string/sync_link_show" />
<LinearLayout <LinearLayout
style="@style/SyncTextItem" style="@style/SyncLayout"
android:orientation="vertical" > android:layout_below="@id/setup_showme"
android:paddingTop="30dp"
<TextView android:paddingLeft="-15dp"
android:id="@+id/text_pin" android:orientation="vertical" >
style="@style/SyncTextItem" <TextView
android:text="@string/sync_pin_default" android:id="@+id/text_pin1"
android:textSize="40dp" /> style="@style/SyncPinText" />
<TextView
android:id="@+id/text_pin2"
style="@style/SyncPinText" />
<TextView
android:id="@+id/text_pin3"
style="@style/SyncPinText" />
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/link_nodevice" android:id="@+id/link_nodevice"
style="@style/SyncLinkItem" style="@style/SyncLinkItem"
android:onClick="manualClickHandler" android:layout_alignParentBottom="true"
android:text="@string/sync_link_nodevice" /> android:gravity="center"
android:paddingBottom="5dp"
<LinearLayout android:onClick="manualClickHandler"
android:layout_width="wrap_content" android:text="@string/sync_link_advancedsetup" />
android:layout_height="wrap_content" </RelativeLayout>
android:gravity="center"
android:orientation="horizontal" >
<Button
style="@style/SyncButtonCommon"
android:layout_marginTop="10dp"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
</LinearLayout>
</LinearLayout>
</ScrollView> </ScrollView>
</TableLayout> <LinearLayout
android:id="@id/setup_bottom"
style="@style/SyncBottom"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
</LinearLayout>
</RelativeLayout>

View File

@@ -1,41 +1,45 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<TextView <LinearLayout
style="@style/SyncTextTitle" android:id="@+id/failure_top"
android:text="@string/sync_title_fail" /> style="@style/SyncTop" >
<View <ImageView
style="@style/SyncViewLine" /> style="@style/SyncTopIcon" />
<TextView
style="@style/SyncTextTitle"
android:text="@string/sync_title_fail" />
</LinearLayout>
<TextView <TextView
style="@style/SyncTextItem" style="@style/SyncTextItem"
android:text="@string/sync_subtitle_fail" /> android:layout_below="@id/failure_top"
android:layout_above="@+id/failure_bottom"
android:padding="20dp"
android:text="@string/sync_subtitle_fail" />
<LinearLayout
android:id="@id/failure_bottom"
style="@style/SyncBottom"
android:orientation="horizontal" >
<LinearLayout <Button
android:layout_width="wrap_content" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:layout_weight="1"
android:onClick="tryAgainClickHandler"
android:text="@string/sync_button_tryagain" />
<LinearLayout <Button
android:layout_width="wrap_content" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:layout_weight="1"
android:onClick="manualClickHandler"
<Button android:text="@string/sync_button_manual" />
style="@style/SyncButtonCommon" <Button
android:onClick="tryAgainClickHandler" android:layout_width="fill_parent"
android:text="@string/sync_button_tryagain" /> android:layout_height="wrap_content"
android:layout_weight="1"
<Button android:onClick="cancelClickHandler"
style="@style/SyncButtonCommon" android:text="@string/sync_button_cancel" />
android:onClick="manualClickHandler" </LinearLayout>
android:text="@string/sync_button_manual" /> </RelativeLayout>
</LinearLayout>
<Button
style="@style/SyncButtonCommon"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
</LinearLayout>
</TableLayout>

View File

@@ -1,23 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<TextView <LinearLayout
style="@style/SyncTextTitle" android:id="@+id/waiting_top"
android:text="@string/sync_title_connect" /> style="@style/SyncTop" >
<View <ImageView
style="@style/SyncViewLine" /> style="@style/SyncTopIcon" />
<ProgressBar <TextView
style="@android:style/Widget.ProgressBar.Horizontal" style="@style/SyncTextTitle"
android:layout_width="wrap_content" android:text="@string/sync_title_connect" />
android:layout_height="wrap_content" </LinearLayout>
android:indeterminateOnly="true"
android:layout_marginTop="10dp" <ProgressBar
android:layout_marginBottom="10dp" /> android:id="@+id/waiting_content1"
<TextView style="@android:style/Widget.ProgressBar.Horizontal"
style="@style/SyncTextItem" android:layout_width="fill_parent"
android:text="@string/sync_jpake_subtitle_waiting" /> android:layout_height="wrap_content"
android:layout_below="@id/waiting_top"
android:indeterminateOnly="true"
android:layout_marginTop="40dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"/>
<TextView
style="@style/SyncTextItem"
android:gravity="center"
android:layout_below="@id/waiting_content1"
android:text="@string/sync_jpake_subtitle_waiting" />
<LinearLayout
style="@style/SyncBottom">
<Button <Button
style="@style/SyncButtonCommon" style="@style/SyncButton"
android:onClick="cancelClickHandler" android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" /> android:text="@string/sync_button_cancel" />
</TableLayout> </LinearLayout>
</RelativeLayout>

View File

@@ -1,18 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<LinearLayout
android:id="@+id/internet_top"
style="@style/SyncTop">
<ImageView
style="@style/SyncTopIcon" />
<TextView <TextView
style="@style/SyncTextTitle" style="@style/SyncTextTitle"
android:text="@string/sync_title_fail" /> android:text="@string/sync_title_fail" />
<View </LinearLayout>
style="@style/SyncViewLine"/> <TextView
<TextView style="@style/SyncTextItem"
style="@style/SyncTextItem" android:layout_below="@id/internet_top"
android:text="@string/sync_subtitle_nointernet" /> android:layout_marginTop="20dp"
android:gravity="center"
android:text="@string/sync_subtitle_nointernet" />
<LinearLayout
style="@style/SyncBottom" >
<Button <Button
style="@style/SyncButtonCommon" style="@style/SyncButton"
android:layout_marginTop="10dp" android:onClick="cancelClickHandler"
android:layout_marginBottom="10dp" android:text="@string/sync_button_ok" />
android:onClick="cancelClickHandler" </LinearLayout>
android:text="@string/sync_button_ok" /> </RelativeLayout>
</TableLayout>

View File

@@ -1,28 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<LinearLayout
android:id="@+id/pair_top"
style="@style/SyncTop" >
<ImageView
style="@style/SyncTopIcon" />
<TextView
android:id="@+id/setup_title"
style="@style/SyncTextTitle"
android:text="@string/sync_title_pair" />
</LinearLayout>
<ScrollView <ScrollView
style="@style/SyncLayout" > style="@style/SyncLayout"
android:layout_below="@id/pair_top"
android:layout_above="@+id/pair_bottom" >
<LinearLayout <LinearLayout
style="@style/SyncLayout" > style="@style/SyncLayout.Vertical"
android:gravity="center"
<TextView android:padding="10dp" >
android:id="@+id/setup_title"
style="@style/SyncTextTitle"
android:text="@string/sync_title_pair" />
<View
style="@style/SyncViewLine" />
<TextView <TextView
android:id="@+id/setup_subtitle" android:id="@+id/setup_subtitle"
style="@style/SyncTextItem" style="@style/SyncTextItem"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:text="@string/sync_subtitle_connect" /> android:text="@string/sync_subtitle_connect" />
<TextView <TextView
style="@style/SyncLinkItem" style="@style/SyncLinkItem"
android:layout_marginBottom="10dp"
android:onClick="showClickHandler" android:onClick="showClickHandler"
android:text="@string/sync_link_show" /> android:text="@string/sync_link_show" />
@@ -32,16 +40,16 @@
android:gravity="center" android:gravity="center"
android:orientation="vertical" > android:orientation="vertical" >
<EditText <EditText
android:id="@+id/pair_row1" android:id="@+id/pair_row1"
style="@style/SyncEditPin" /> style="@style/SyncEditPin" />
<EditText <EditText
android:id="@+id/pair_row2" android:id="@+id/pair_row2"
style="@style/SyncEditPin" /> style="@style/SyncEditPin" />
<EditText <EditText
android:id="@+id/pair_row3" android:id="@+id/pair_row3"
style="@style/SyncEditPin" style="@style/SyncEditPin"
android:imeOptions="actionDone" /> android:imeOptions="actionDone" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@@ -54,31 +62,28 @@
<TextView <TextView
style="@style/SyncTextItem" style="@style/SyncTextItem"
android:layout_marginTop="10dp" android:layout_margin="10dp"
android:layout_marginBottom="10dp"
android:text="@string/sync_pair_tryagain" android:text="@string/sync_pair_tryagain"
android:textSize="10dp" /> android:textSize="10dp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<Button
style="@style/SyncButtonCommon"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
<Button
android:id="@+id/pair_button_connect"
style="@style/SyncButtonCommon"
android:onClick="connectClickHandler"
android:clickable="false"
android:enabled="false"
android:text="@string/sync_button_connect" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</TableLayout> <LinearLayout
android:id="@id/pair_bottom"
style="@style/SyncBottom"
android:orientation="horizontal" >
<Button
style="@style/SyncButton"
android:onClick="cancelClickHandler"
android:text="@string/sync_button_cancel" />
<Button
android:id="@+id/pair_button_connect"
style="@style/SyncButton"
android:onClick="connectClickHandler"
android:clickable="false"
android:enabled="false"
android:text="@string/sync_button_connect" />
</LinearLayout>
</RelativeLayout>

View File

@@ -1,38 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SyncTextFrame" > style="@style/SyncLayout" >
<LinearLayout
android:id="@+id/success_top"
style="@style/SyncTop" >
<ImageView
style="@style/SyncTopIcon"/>
<TextView <TextView
style="@style/SyncTextTitle" style="@style/SyncTextTitle"
android:text="@string/sync_title_success" /> android:text="@string/sync_title_success" />
</LinearLayout>
<View style="@style/SyncViewLine" /> <TextView
android:id="@+id/setup_success_subtitle"
<TextView style="@style/SyncTextItem"
android:id="@+id/setup_success_subtitle" android:gravity="left"
android:layout_width="fill_parent" android:padding="20dp"
android:layout_height="wrap_content" android:layout_below="@id/success_top"
android:gravity="center" android:text="@string/sync_subtitle_success" />
android:padding="20dp"
android:text="@string/sync_subtitle_success" />
<LinearLayout
style="@style/SyncBottom" >
<Button <Button
android:layout_width="wrap_content" style="@style/SyncButton"
android:layout_height="wrap_content" android:onClick="settingsClickHandler"
android:layout_gravity="center" android:text="@string/sync_settings" />
android:onClick="settingsClickHandler" </LinearLayout>
android:text="@string/sync_settings" /> </RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
<TextView
android:id="@+id/link_pair"
style="@style/SyncLinkItem"
android:layout_gravity="center|bottom"
android:onClick="pairClickHandler"
android:text="@string/sync_title_pair" />
</TableLayout>

View File

@@ -1,34 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="SyncLayout" parent="@android:style/Widget"> <style name="SyncLayout">
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item> <item name="android:layout_height">fill_parent</item>
<item name="android:gravity">center</item> </style>
<style name="SyncLayout.Vertical" parent="@style/SyncLayout">
<item name="android:orientation">vertical</item> <item name="android:orientation">vertical</item>
</style> </style>
<style name="SyncLayout.Horizontal" parent="@style/SyncLayout">
<item name="android:orientation">horizontal</item>
</style>
<!-- TextView Styles --> <!-- TextView Styles -->
<style name="SyncTextFrame" parent="@android:style/TextAppearance"> <style name="SyncTextFrame" parent="@android:style/TextAppearance">
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item> <item name="android:layout_height">fill_parent</item>
<item name="android:layout_gravity">center</item> <item name="android:layout_gravity">center</item>
<item name="android:padding">20dp</item> <item name="android:padding">20dp</item>
<item name="android:orientation">vertical</item> <item name="android:orientation">vertical</item>
<item name="android:background">#82818A</item>
</style> </style>
<style name="SyncTextItem" parent="@android:style/TextAppearance.Medium"> <style name="SyncTextItem" parent="@android:style/TextAppearance.Medium">
<item name="android:gravity">center</item>
<item name="android:layout_width">fill_parent</item> <item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center_vertical</item>
<item name="android:textSize">15dp</item> <item name="android:textSize">15dp</item>
</style> </style>
<style name="SyncLinkItem" parent="SyncTextItem"> <style name="SyncLinkItem" parent="SyncTextItem">
<item name="android:clickable">true</item> <item name="android:clickable">true</item>
<item name="android:textColor">#99CCFF</item> <item name="android:textColor">#ACC4D5</item>
</style> </style>
<style name="SyncTextTitle" parent="@style/SyncTextItem"> <style name="SyncTextTitle" parent="@style/SyncTextItem">
<item name="android:gravity">center</item> <item name="android:layout_gravity">center_vertical</item>
<item name="android:paddingBottom">10dp</item> <item name="android:paddingLeft">4dp</item>
<item name="android:gravity">left</item>
<item name="android:textSize">20dp</item> <item name="android:textSize">20dp</item>
</style> </style>
<!-- EditView Styles --> <!-- EditView Styles -->
@@ -44,16 +47,48 @@
<item name="android:maxLength">4</item> <item name="android:maxLength">4</item>
<item name="android:imeOptions">actionNext</item> <item name="android:imeOptions">actionNext</item>
</style> </style>
<!-- Misc Styles -->
<style name="SyncButtonCommon"> <!-- Theme Styles -->
<style name="SyncTheme" parent="@android:style/Theme.NoTitleBar"/>
<style name="SyncTop">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">left</item>
<item name="android:orientation">horizontal</item>
<item name="android:layout_alignParentTop">true</item>
<item name="android:background">@android:drawable/bottom_bar</item>
</style>
<style name="SyncBottom">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
<item name="android:layout_alignParentBottom">true</item>
<item name="android:background">@android:drawable/bottom_bar</item>
</style>
<style name="SyncButton" parent="@android:style/Widget.Button">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
</style>
<!-- Text Display Styles -->
<style name="SyncPinText" parent="@android:style/Widget.TextView">
<item name="android:layout_width">130sp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_marginBottom">5dp</item>
<item name="android:gravity">center</item>
<item name="android:background">@drawable/pin_background</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">35sp</item>
<item name="android:text">@string/sync_pin_default</item>
</style>
<style name="SyncTopIcon">
<item name="android:src">@drawable/sync_ic_launcher</item>
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
</style> <item name="android:paddingTop">2dp</item>
<style name="SyncViewLine"> <item name="android:paddingLeft">4dp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">2dp</item>
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">10dp</item>
<item name="android:background">#FFFFFF</item>
</style> </style>
</resources> </resources>

View File

@@ -7,8 +7,9 @@
<org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox" <org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox"
url="about:" /> url="about:" />
<org.mozilla.gecko.SyncPreference android:title="@string/pref_sync" <!-- TODO: Default Search Engine -->
android:persistent="false" />
<!-- TODO: Sync -->
</PreferenceCategory> </PreferenceCategory>

View File

@@ -74,7 +74,6 @@
<string name="pref_font_size_medium">&pref_font_size_medium;</string> <string name="pref_font_size_medium">&pref_font_size_medium;</string>
<string name="pref_font_size_large">&pref_font_size_large;</string> <string name="pref_font_size_large">&pref_font_size_large;</string>
<string name="pref_font_size_xlarge">&pref_font_size_xlarge;</string> <string name="pref_font_size_xlarge">&pref_font_size_xlarge;</string>
<string name="pref_sync">&pref_sync;</string>
<string name="reload">&reload;</string> <string name="reload">&reload;</string>
<string name="forward">&forward;</string> <string name="forward">&forward;</string>

View File

@@ -63,9 +63,9 @@ public class SyncConfiguration implements CredentialsSource {
this.editor = config.getEditor(); this.editor = config.getEditor();
} }
@Override
public void apply() { public void apply() {
this.editor.apply(); // Android <=r8 SharedPreferences.Editor does not contain apply() for overriding.
this.editor.commit();
} }
@Override @Override

View File

@@ -41,7 +41,6 @@ package org.mozilla.gecko.sync;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Random; import java.util.Random;
@@ -128,8 +127,10 @@ public class Utils {
totalLength += array.length; totalLength += array.length;
} }
byte[] result = Arrays.copyOf(first, totalLength); byte[] result = new byte[totalLength];
int offset = first.length; int offset = first.length;
System.arraycopy(first, 0, result, 0, offset);
for (byte[] array : rest) { for (byte[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length); System.arraycopy(array, 0, result, offset, array.length);

View File

@@ -40,7 +40,6 @@ package org.mozilla.gecko.sync.crypto;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@@ -98,7 +97,9 @@ public class HKDF {
T = Utils.concatAll(T, Tn); T = Utils.concatAll(T, Tn);
} }
return Arrays.copyOfRange(T, 0, len); byte[] result = new byte[len];
System.arraycopy(T, 0, result, 0, len);
return result;
} }
/* /*

View File

@@ -19,7 +19,8 @@
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* Chenxia Liu <liuche@mozilla.com> * Chenxia Liu <liuche@mozilla.com>
* Richard Newman <rnewman@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * 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 * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -52,49 +53,49 @@ import org.mozilla.gecko.sync.crypto.KeyBundle;
import android.util.Log; import android.util.Log;
public class JPakeCrypto { public class JPakeCrypto {
private static final String LOG_TAG = "JpakeCrypto"; private static final String LOG_TAG = "JPakeCrypto";
/* /*
* Primes P and Q, and generator G - from original Mozilla jpake * Primes P and Q, and generator G - from original Mozilla J-PAKE
* implementation. * implementation.
*/ */
public static final BigInteger P = new BigInteger( public static final BigInteger P = new BigInteger(
"90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" +
+ "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" +
+ "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" +
+ "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" +
+ "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" +
+ "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" +
+ "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" +
+ "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" +
+ "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" +
+ "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" +
+ "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" +
+ "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73", "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73",
16); 16);
public static final BigInteger Q = new BigInteger( public static final BigInteger Q = new BigInteger(
"CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D", "CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D",
16); 16);
public static final BigInteger G = new BigInteger( public static final BigInteger G = new BigInteger(
"5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" +
+ "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" +
+ "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" +
+ "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" +
+ "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" +
+ "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" +
+ "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" +
+ "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" +
+ "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" +
+ "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" +
+ "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" +
+ "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B", "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B",
16); 16);
/** /**
* *
* Round 1 of JPAKE protocol. * Round 1 of J-PAKE protocol.
* Generate x1, x2, and ZKP for other party. * Generate x1, x2, and ZKP for other party.
* *
* @param mySignerId * @param mySignerId
@@ -118,7 +119,7 @@ public class JPakeCrypto {
} }
/** /**
* Round 2 of JPAKE protocol. * Round 2 of J-PAKE protocol.
* Generate A and ZKP for A. * Generate A and ZKP for A.
* Verify ZKP from other party. Does not check for replay ZKP. * Verify ZKP from other party. Does not check for replay ZKP.
* *
@@ -135,9 +136,9 @@ public class JPakeCrypto {
public static void round2(String secret, JPakeParty jp, public static void round2(String secret, JPakeParty jp,
JPakeNumGenerator gen) throws Gx4IsOneException, IncorrectZkpException { JPakeNumGenerator gen) throws Gx4IsOneException, IncorrectZkpException {
Log.d(LOG_TAG, "round2 started"); Log.d(LOG_TAG, "round2 started.");
if (jp.gx4 == BigInteger.ONE) { if (BigInteger.ONE.compareTo(jp.gx4) == 0) {
throw new Gx4IsOneException(); throw new Gx4IsOneException();
} }
@@ -159,11 +160,11 @@ public class JPakeCrypto {
jp.thisZkpA = createZkp(y1, y2, a, jp.signerId, gen); jp.thisZkpA = createZkp(y1, y2, a, jp.signerId, gen);
jp.thisA = a; jp.thisA = a;
Log.d(LOG_TAG, "round2 finished"); Log.d(LOG_TAG, "round2 finished.");
} }
/** /**
* Final round of JPAKE protocol. * Final round of J-PAKE protocol.
* *
* @param b * @param b
* @param zkp * @param zkp
@@ -174,7 +175,7 @@ public class JPakeCrypto {
*/ */
public static KeyBundle finalRound(String secret, JPakeParty jp) public static KeyBundle finalRound(String secret, JPakeParty jp)
throws IncorrectZkpException { throws IncorrectZkpException {
Log.d(LOG_TAG, "final round started"); Log.d(LOG_TAG, "Final round started.");
BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3) BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3)
.mod(P); .mod(P);
checkZkp(gb, jp.otherA, jp.otherZkpA); checkZkp(gb, jp.otherA, jp.otherZkpA);
@@ -188,7 +189,7 @@ public class JPakeCrypto {
byte[] hmac = new byte[32]; byte[] hmac = new byte[32];
generateKeyAndHmac(k, enc, hmac); generateKeyAndHmac(k, enc, hmac);
Log.d(LOG_TAG, "final round finished; returning key"); Log.d(LOG_TAG, "Final round finished; returning key.");
return new KeyBundle(enc, hmac); return new KeyBundle(enc, hmac);
} }
@@ -198,8 +199,7 @@ public class JPakeCrypto {
try { try {
Mac hmacSha256; Mac hmacSha256;
hmacSha256 = Mac.getInstance("HmacSHA256"); hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key, SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
"HmacSHA256");
hmacSha256.init(secret_key); hmacSha256.init(secret_key);
result = hmacSha256.doFinal(data); result = hmacSha256.doFinal(data);
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
@@ -243,14 +243,18 @@ public class JPakeCrypto {
// Check parameters of zkp, and compare to computed hash. These shouldn't // Check parameters of zkp, and compare to computed hash. These shouldn't
// fail. // fail.
if (gx.compareTo(BigInteger.ZERO) < 1) {// g^x > 1 if (gx.compareTo(BigInteger.ZERO) < 1) {// g^x > 1
Log.e(LOG_TAG, "g^x > 1 fails"); Log.e(LOG_TAG, "g^x > 1 fails.");
throw new IncorrectZkpException(); throw new IncorrectZkpException();
} else if (gx.compareTo(P.subtract(BigInteger.ONE)) > -1) { // g^x < p-1 }
Log.e(LOG_TAG, "g^x < p-1 fails"); if (gx.compareTo(P.subtract(BigInteger.ONE)) > -1) { // g^x < p-1
Log.e(LOG_TAG, "g^x < p-1 fails.");
throw new IncorrectZkpException(); throw new IncorrectZkpException();
} else if (gx.modPow(Q, P).compareTo(BigInteger.ONE) != 0) { }
Log.e(LOG_TAG, "g^x^q % p = 1 fails"); if (gx.modPow(Q, P).compareTo(BigInteger.ONE) != 0) {
} else if (zkp.gr.compareTo(g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P)) != 0) { Log.e(LOG_TAG, "g^x^q % p = 1 fails.");
throw new IncorrectZkpException();
}
if (zkp.gr.compareTo(g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P)) != 0) {
// b = r-h*x ==> g^r = g^b*g^x^(h) // b = r-h*x ==> g^r = g^b*g^x^(h)
Log.i(LOG_TAG, "gb*g(xh) = " Log.i(LOG_TAG, "gb*g(xh) = "
+ g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P).toString(16)); + g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P).toString(16));
@@ -260,11 +264,10 @@ public class JPakeCrypto {
Log.d(LOG_TAG, "g^(xh) = " + gx.modPow(h, P).toString(16)); Log.d(LOG_TAG, "g^(xh) = " + gx.modPow(h, P).toString(16));
Log.d(LOG_TAG, "gx = " + gx.toString(16)); Log.d(LOG_TAG, "gx = " + gx.toString(16));
Log.d(LOG_TAG, "h = " + h.toString(16)); Log.d(LOG_TAG, "h = " + h.toString(16));
Log.e(LOG_TAG, "zkp calculation incorrect"); Log.e(LOG_TAG, "zkp calculation incorrect.");
throw new IncorrectZkpException(); throw new IncorrectZkpException();
} else {
Log.d(LOG_TAG, "*** ZKP SUCCESS ***");
} }
Log.d(LOG_TAG, "*** ZKP SUCCESS ***");
} }
/* /*

View File

@@ -50,6 +50,7 @@ import android.util.Log;
import ch.boye.httpclientandroidlib.Header; import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity; import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.HttpResponse; import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.HttpVersion;
import ch.boye.httpclientandroidlib.auth.Credentials; import ch.boye.httpclientandroidlib.auth.Credentials;
import ch.boye.httpclientandroidlib.auth.UsernamePasswordCredentials; import ch.boye.httpclientandroidlib.auth.UsernamePasswordCredentials;
import ch.boye.httpclientandroidlib.client.ClientProtocolException; import ch.boye.httpclientandroidlib.client.ClientProtocolException;
@@ -157,6 +158,7 @@ public class BaseResource implements Resource {
HttpConnectionParams.setConnectionTimeout(params, delegate.connectionTimeout()); HttpConnectionParams.setConnectionTimeout(params, delegate.connectionTimeout());
HttpConnectionParams.setSoTimeout(params, delegate.socketTimeout()); HttpConnectionParams.setSoTimeout(params, delegate.socketTimeout());
HttpProtocolParams.setContentCharset(params, charset); HttpProtocolParams.setContentCharset(params, charset);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
delegate.addHeaders(request, client); delegate.addHeaders(request, client);
} }
@@ -182,8 +184,7 @@ public class BaseResource implements Resource {
SchemeRegistry schemeRegistry = new SchemeRegistry(); SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", 443, sf)); schemeRegistry.register(new Scheme("https", 443, sf));
schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory())); schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory()));
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager( ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
schemeRegistry);
connManager = cm; connManager = cm;
return cm; return cm;
} }

View File

@@ -173,7 +173,7 @@ public class SyncStorageRequest implements Resource {
} }
} }
public static String USER_AGENT = "Firefox AndroidSync 0.2"; public static String USER_AGENT = "Firefox AndroidSync 0.3";
protected SyncResourceDelegate resourceDelegate; protected SyncResourceDelegate resourceDelegate;
public SyncStorageRequestDelegate delegate; public SyncStorageRequestDelegate delegate;
protected BaseResource resource; protected BaseResource resource;

View File

@@ -43,19 +43,59 @@ import java.net.Socket;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import android.util.Log;
import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory; import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory;
import ch.boye.httpclientandroidlib.params.HttpParams; import ch.boye.httpclientandroidlib.params.HttpParams;
public class TLSSocketFactory extends SSLSocketFactory { public class TLSSocketFactory extends SSLSocketFactory {
private static final String LOG_TAG = "TLSSocketFactory";
private static final String[] DEFAULT_CIPHER_SUITES = new String[] {
"SSL_RSA_WITH_RC4_128_SHA", // "RC4_SHA"
};
private static final String[] DEFAULT_PROTOCOLS = new String[] {
"SSLv3",
"TLSv1"
};
// Guarded by `this`.
private static String[] cipherSuites = DEFAULT_CIPHER_SUITES;
public TLSSocketFactory(SSLContext sslContext) { public TLSSocketFactory(SSLContext sslContext) {
super(sslContext); super(sslContext);
} }
/**
* Attempt to specify the cipher suites to use for a connection. If
* setting fails (as it will on Android 2.2, because the wrong names
* are in use to specify ciphers), attempt to set the defaults.
*
* We store the list of cipher suites in `cipherSuites`, which
* avoids this fallback handling having to be executed more than once.
*
* This method is synchronized to ensure correct use of that member.
*
* See Bug 717691 for more details.
*
* @param socket
* The SSLSocket on which to operate.
*/
public static synchronized void setEnabledCipherSuites(SSLSocket socket) {
try {
socket.setEnabledCipherSuites(cipherSuites);
} catch (IllegalArgumentException e) {
cipherSuites = socket.getSupportedCipherSuites();
Log.d(LOG_TAG, "Setting enabled cipher suites failed: " + e.getMessage());
Log.d(LOG_TAG, "Using " + cipherSuites.length + " supported suites.");
socket.setEnabledCipherSuites(cipherSuites);
}
}
@Override @Override
public Socket createSocket(HttpParams params) throws IOException { public Socket createSocket(HttpParams params) throws IOException {
SSLSocket socket = (SSLSocket) super.createSocket(params); SSLSocket socket = (SSLSocket) super.createSocket(params);
socket.setEnabledProtocols(new String[] { "SSLv3", "TLSv1" }); socket.setEnabledProtocols(DEFAULT_PROTOCOLS);
socket.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_SHA" }); setEnabledCipherSuites(socket);
return socket; return socket;
} }

View File

@@ -82,6 +82,7 @@ public class AccountActivity extends AccountAuthenticatorActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.SyncTheme);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.sync_account); setContentView(R.layout.sync_account);
mContext = getApplicationContext(); mContext = getApplicationContext();
@@ -132,7 +133,7 @@ public class AccountActivity extends AccountAuthenticatorActivity {
} }
public void cancelClickHandler(View target) { public void cancelClickHandler(View target) {
moveTaskToBack(true); finish();
} }
/* /*

View File

@@ -50,6 +50,7 @@ public class SetupFailureActivity extends Activity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.SyncTheme);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.sync_setup_failure); setContentView(R.layout.sync_setup_failure);
mContext = this.getApplicationContext(); mContext = this.getApplicationContext();

View File

@@ -44,15 +44,18 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
public class SetupSuccessActivity extends Activity { public class SetupSuccessActivity extends Activity {
private final static String LOG_TAG = "SetupSuccessActivity";
private TextView setupSubtitle; private TextView setupSubtitle;
private Context mContext; private Context mContext;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.SyncTheme);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContext = getApplicationContext(); mContext = getApplicationContext();
Bundle extras = this.getIntent().getExtras(); Bundle extras = this.getIntent().getExtras();
@@ -68,7 +71,7 @@ public class SetupSuccessActivity extends Activity {
/* Click Handlers */ /* Click Handlers */
public void settingsClickHandler(View target) { public void settingsClickHandler(View target) {
Intent intent = new Intent("android.settings.SYNC_SETTINGS"); Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION); intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
startActivity(intent); startActivity(intent);
finish(); finish();

View File

@@ -53,6 +53,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
@@ -79,7 +80,9 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
private TextView setupTitleView; private TextView setupTitleView;
private TextView setupNoDeviceLinkTitleView; private TextView setupNoDeviceLinkTitleView;
private TextView setupSubtitleView; private TextView setupSubtitleView;
private TextView pinTextView; private TextView pinTextView1;
private TextView pinTextView2;
private TextView pinTextView3;
private JPakeClient jClient; private JPakeClient jClient;
// Android context. // Android context.
@@ -94,6 +97,7 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.SyncTheme);
Log.i(LOG_TAG, "Called SetupSyncActivity.onCreate."); Log.i(LOG_TAG, "Called SetupSyncActivity.onCreate.");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -134,9 +138,14 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
return; return;
} }
} }
// Display toast for "Only one account supported." // Display toast for "Only one account supported." and redirect to account management.
Toast toast = Toast.makeText(mContext, R.string.sync_notification_oneaccount, Toast.LENGTH_LONG); Toast toast = Toast.makeText(mContext, R.string.sync_notification_oneaccount, Toast.LENGTH_LONG);
toast.show(); toast.show();
Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
startActivity(intent);
finish(); finish();
} }
@@ -202,20 +211,23 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
} }
// Format PIN for display. // Format PIN for display.
int charPerLine = pin.length() / 3; int charPerLine = pin.length() / 3;
String prettyPin = pin.substring(0, charPerLine) + "\n"; final String pin1 = pin.substring(0, charPerLine);
prettyPin += pin.substring(charPerLine, 2 * charPerLine) + "\n"; final String pin2 = pin.substring(charPerLine, 2 * charPerLine);
prettyPin += pin.substring(2 * charPerLine, pin.length()); final String pin3 = pin.substring(2 * charPerLine, pin.length());
final String toDisplay = prettyPin;
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
TextView view = pinTextView; TextView view1 = pinTextView1;
if (view == null) { TextView view2 = pinTextView2;
TextView view3 = pinTextView3;
if (view1 == null || view2 == null || view3 == null) {
Log.w(LOG_TAG, "Couldn't find view to display PIN."); Log.w(LOG_TAG, "Couldn't find view to display PIN.");
return; return;
} }
view.setText(toDisplay); view1.setText(pin1);
view2.setText(pin2);
view3.setText(pin3);
} }
}); });
} }
@@ -475,7 +487,9 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
setupTitleView = ((TextView) findViewById(R.id.setup_title)); setupTitleView = ((TextView) findViewById(R.id.setup_title));
setupSubtitleView = (TextView) findViewById(R.id.setup_subtitle); setupSubtitleView = (TextView) findViewById(R.id.setup_subtitle);
setupNoDeviceLinkTitleView = (TextView) findViewById(R.id.link_nodevice); setupNoDeviceLinkTitleView = (TextView) findViewById(R.id.link_nodevice);
pinTextView = ((TextView) findViewById(R.id.text_pin)); pinTextView1 = ((TextView) findViewById(R.id.text_pin1));
pinTextView2 = ((TextView) findViewById(R.id.text_pin2));
pinTextView3 = ((TextView) findViewById(R.id.text_pin3));
// UI checks. // UI checks.
if (setupTitleView == null) { if (setupTitleView == null) {

View File

@@ -6,7 +6,7 @@ mk_add_options AUTOCONF=autoconf213
ac_cv_visibility_pragma=no ac_cv_visibility_pragma=no
ac_add_options --disable-install-strip ac_add_options --disable-install-strip
ac_add_options --disable-installer
ac_add_options --enable-application=mobile/android ac_add_options --enable-application=mobile/android
# Nightlies only since this has a cost in performance # Nightlies only since this has a cost in performance

View File

@@ -0,0 +1 @@
mobile/android/base/resources/drawable-hdpi/sync_ic_launcher.png

View File

@@ -0,0 +1 @@
mobile/android/base/resources/drawable-ldpi/sync_ic_launcher.png

View File

@@ -0,0 +1 @@
mobile/android/base/resources/drawable-mdpi/sync_ic_launcher.png

View File

@@ -1,4 +1,2 @@
mobile/android/base/resources/drawable/pin_background.xml
mobile/android/base/resources/drawable/sync_icon.png mobile/android/base/resources/drawable/sync_icon.png
mobile/android/base/resources/drawable-hdpi/sync_ic_launcher.png
mobile/android/base/resources/drawable-ldpi/sync_ic_launcher.png
mobile/android/base/resources/drawable-mdpi/sync_ic_launcher.png

View File

@@ -1,13 +1,14 @@
<string name="sync_app_name">&sync.app.name.label;</string> <string name="sync_app_name">&sync.app.name.label;</string>
<string name="sync_title_connect">&sync.title.connect.label;</string> <string name="sync_title_connect">&sync.title.adddevice.label;</string>
<string name="sync_title_pair">&sync.title.pair.label;</string> <string name="sync_title_pair">&sync.title.pair.label;</string>
<!-- J-PAKE PIN Screen --> <!-- J-PAKE PIN Screen -->
<string name="sync_subtitle_connect">&sync.subtitle.connect.label;</string> <string name="sync_subtitle_header">&sync.subtitle.header.label;</string>
<string name="sync_subtitle_connect">&sync.subtitle.connectlocation.label;</string>
<string name="sync_subtitle_pair">&sync.subtitle.pair.label;</string> <string name="sync_subtitle_pair">&sync.subtitle.pair.label;</string>
<string name="sync_pin_default">&sync.pin.default.label;</string> <string name="sync_pin_default">&sync.pin.oneline.label;</string>
<string name="sync_link_show">&sync.link.show.label;</string> <string name="sync_link_show"><u>&sync.link.show.label;</u></string>
<string name="sync_link_nodevice">&sync.link.nodevice.label;</string> <string name="sync_link_advancedsetup"><u>&sync.link.advancedsetup.label;</u></string>
<!-- J-PAKE Waiting Screen --> <!-- J-PAKE Waiting Screen -->

View File

@@ -6,7 +6,7 @@ mk_add_options AUTOCONF=autoconf213
ac_cv_visibility_pragma=no ac_cv_visibility_pragma=no
ac_add_options --disable-install-strip ac_add_options --disable-install-strip
ac_add_options --disable-installer
ac_add_options --enable-application=mobile ac_add_options --enable-application=mobile
# Nightlies only since this has a cost in performance # Nightlies only since this has a cost in performance

View File

@@ -586,7 +586,6 @@ nsSocketOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *countWrit
PRInt32 n = PR_Write(fd, buf, count); PRInt32 n = PR_Write(fd, buf, count);
SOCKET_LOG((" PR_Write returned [n=%d]\n", n)); SOCKET_LOG((" PR_Write returned [n=%d]\n", n));
NS_ASSERTION(n != 0, "unexpected return value");
nsresult rv; nsresult rv;
{ {

View File

@@ -915,6 +915,8 @@ nsCompressOutputStreamWrapper::Write(const char * buf,
while (mZstream.avail_in > 0) { while (mZstream.avail_in > 0) {
zerr = deflate(&mZstream, Z_NO_FLUSH); zerr = deflate(&mZstream, Z_NO_FLUSH);
if (zerr == Z_STREAM_ERROR) { if (zerr == Z_STREAM_ERROR) {
deflateEnd(&mZstream);
mStreamInitialized = PR_FALSE;
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Note: Z_BUF_ERROR is non-fatal and sometimes expected here. // Note: Z_BUF_ERROR is non-fatal and sometimes expected here.
@@ -924,6 +926,8 @@ nsCompressOutputStreamWrapper::Write(const char * buf,
if (mZstream.avail_out == 0) { if (mZstream.avail_out == 0) {
rv = WriteBuffer(); rv = WriteBuffer();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
deflateEnd(&mZstream);
mStreamInitialized = PR_FALSE;
return rv; return rv;
} }
} }

View File

@@ -851,6 +851,8 @@ SpdySession::HandleSynReply(SpdySession *self)
return NS_OK; return NS_OK;
} }
self->mFrameDataStream->UpdateTransportReadEvents(self->mFrameDataSize);
if (!self->mFrameDataStream->SetFullyOpen()) { if (!self->mFrameDataStream->SetFullyOpen()) {
// "If an endpoint receives multiple SYN_REPLY frames for the same active // "If an endpoint receives multiple SYN_REPLY frames for the same active
// stream ID, it must drop the stream, and send a RST_STREAM for the // stream ID, it must drop the stream, and send a RST_STREAM for the
@@ -1128,6 +1130,9 @@ SpdySession::HandleHeaders(SpdySession *self)
// this is actually not legal in the HTTP mapping of SPDY. All // this is actually not legal in the HTTP mapping of SPDY. All
// headers are in the syn or syn reply. Log and ignore it. // headers are in the syn or syn reply. Log and ignore it.
// in v3 this will be legal and we must remember to note
// NS_NET_STATUS_RECEIVING_FROM from it
LOG3(("SpdySession::HandleHeaders %p HEADERS for Stream 0x%X. " LOG3(("SpdySession::HandleHeaders %p HEADERS for Stream 0x%X. "
"They are ignored in the HTTP/SPDY mapping.", "They are ignored in the HTTP/SPDY mapping.",
self, streamID)); self, streamID));
@@ -1148,29 +1153,6 @@ SpdySession::HandleWindowUpdate(SpdySession *self)
return NS_OK; return NS_OK;
} }
// Used for the hashtable enumeration to propogate OnTransportStatus events
struct transportStatus
{
nsITransport *transport;
nsresult status;
PRUint64 progress;
};
static PLDHashOperator
StreamTransportStatus(nsAHttpTransaction *key,
nsAutoPtr<SpdyStream> &stream,
void *closure)
{
struct transportStatus *status =
static_cast<struct transportStatus *>(closure);
stream->Transaction()->OnTransportStatus(status->transport,
status->status,
status->progress);
return PL_DHASH_NEXT;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsAHttpTransaction. It is expected that nsHttpConnection is the caller // nsAHttpTransaction. It is expected that nsHttpConnection is the caller
// of these methods // of these methods
@@ -1183,21 +1165,47 @@ SpdySession::OnTransportStatus(nsITransport* aTransport,
{ {
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
// nsHttpChannel synthesizes progress events in OnDataAvailable switch (aStatus) {
if (aStatus == nsISocketTransport::STATUS_RECEIVING_FROM) // These should appear only once, deliver to the first
return; // transaction on the session.
case NS_NET_STATUS_RESOLVING_HOST:
case NS_NET_STATUS_RESOLVED_HOST:
case NS_NET_STATUS_CONNECTING_TO:
case NS_NET_STATUS_CONNECTED_TO:
{
SpdyStream *target = mStreamIDHash.Get(1);
if (target)
target->Transaction()->OnTransportStatus(aTransport, aStatus, aProgress);
break;
}
// STATUS_SENDING_TO is handled by SpdyStream default:
if (aStatus == nsISocketTransport::STATUS_SENDING_TO) // The other transport events are ignored here because there is no good
return; // way to map them to the right transaction in spdy. Instead, the events
// are generated again from the spdy code and passed directly to the
// correct transaction.
struct transportStatus status; // NS_NET_STATUS_SENDING_TO:
// This is generated by the socket transport when (part) of
status.transport = aTransport; // a transaction is written out
status.status = aStatus; //
status.progress = aProgress; // There is no good way to map it to the right transaction in spdy,
// so it is ignored here and generated separately when the SYN_STREAM
// is sent from SpdyStream::TransmitFrame
mStreamTransactionHash.Enumerate(StreamTransportStatus, &status); // NS_NET_STATUS_WAITING_FOR:
// Created by nsHttpConnection when the request has been totally sent.
// There is no good way to map it to the right transaction in spdy,
// so it is ignored here and generated separately when the same
// condition is complete in SpdyStream when there is no more
// request body left to be transmitted.
// NS_NET_STATUS_RECEIVING_FROM
// Generated in spdysession whenever we read a data frame or a syn_reply
// that can be attributed to a particular stream/transaction
break;
}
} }
// ReadSegments() is used to write data to the network. Generally, HTTP // ReadSegments() is used to write data to the network. Generally, HTTP
@@ -1675,6 +1683,7 @@ SpdySession::OnWriteSegment(char *buf,
mFrameDataRead += *countWritten; mFrameDataRead += *countWritten;
mFrameDataStream->UpdateTransportReadEvents(*countWritten);
if ((mFrameDataRead == mFrameDataSize) && !mFrameDataLast) if ((mFrameDataRead == mFrameDataSize) && !mFrameDataLast)
ChangeDownstreamState(BUFFERING_FRAME_HEADER); ChangeDownstreamState(BUFFERING_FRAME_HEADER);

View File

@@ -75,6 +75,7 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
mSentFinOnData(0), mSentFinOnData(0),
mRecvdFin(0), mRecvdFin(0),
mFullyOpen(0), mFullyOpen(0),
mSentWaitingFor(0),
mTxInlineFrameAllocation(SpdySession::kDefaultBufferSize), mTxInlineFrameAllocation(SpdySession::kDefaultBufferSize),
mTxInlineFrameSize(0), mTxInlineFrameSize(0),
mTxInlineFrameSent(0), mTxInlineFrameSent(0),
@@ -82,7 +83,9 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
mTxStreamFrameSent(0), mTxStreamFrameSent(0),
mZlib(compressionContext), mZlib(compressionContext),
mRequestBodyLen(0), mRequestBodyLen(0),
mPriority(priority) mPriority(priority),
mTotalSent(0),
mTotalRead(0)
{ {
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@@ -458,6 +461,36 @@ SpdyStream::ParseHttpRequestHeaders(const char *buf,
return NS_OK; return NS_OK;
} }
void
SpdyStream::UpdateTransportReadEvents(PRUint32 count)
{
mTotalRead += count;
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_RECEIVING_FROM,
mTotalRead);
}
void
SpdyStream::UpdateTransportSendEvents(PRUint32 count)
{
mTotalSent += count;
if (mUpstreamState != SENDING_FIN_STREAM)
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_SENDING_TO,
mTotalSent);
if (!mSentWaitingFor && !mRequestBodyLen &&
mTxInlineFrameSent == mTxInlineFrameSize &&
mTxStreamFrameSent == mTxStreamFrameSize) {
mSentWaitingFor = 1;
mTransaction->OnTransportStatus(mSocketTransport,
NS_NET_STATUS_WAITING_FOR,
LL_ZERO);
}
}
nsresult nsresult
SpdyStream::TransmitFrame(const char *buf, SpdyStream::TransmitFrame(const char *buf,
PRUint32 *countUsed) PRUint32 *countUsed)
@@ -538,16 +571,11 @@ SpdyStream::TransmitFrame(const char *buf,
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer", SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
buf + offset, transmittedCount); buf + offset, transmittedCount);
if (mUpstreamState == SENDING_REQUEST_BODY) {
mTransaction->OnTransportStatus(mSocketTransport,
nsISocketTransport::STATUS_SENDING_TO,
transmittedCount);
}
*countUsed += transmittedCount; *countUsed += transmittedCount;
avail -= transmittedCount; avail -= transmittedCount;
offset += transmittedCount; offset += transmittedCount;
mTxStreamFrameSent += transmittedCount; mTxStreamFrameSent += transmittedCount;
UpdateTransportSendEvents(transmittedCount);
} }
if (!avail) { if (!avail) {

View File

@@ -89,6 +89,9 @@ public:
void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; } void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
bool RecvdFin() { return mRecvdFin; } bool RecvdFin() { return mRecvdFin; }
void UpdateTransportSendEvents(PRUint32 count);
void UpdateTransportReadEvents(PRUint32 count);
// The zlib header compression dictionary defined by SPDY, // The zlib header compression dictionary defined by SPDY,
// and hooks to the mozilla allocator for zlib to use. // and hooks to the mozilla allocator for zlib to use.
static const char *kDictionary; static const char *kDictionary;
@@ -171,6 +174,9 @@ private:
// Flag is set after syn reply received // Flag is set after syn reply received
PRUint32 mFullyOpen : 1; PRUint32 mFullyOpen : 1;
// Flag is set after the WAITING_FOR Transport event has been generated
PRUint32 mSentWaitingFor : 1;
// The InlineFrame and associated data is used for composing control // The InlineFrame and associated data is used for composing control
// frames and data frame headers. // frames and data frame headers.
nsAutoArrayPtr<char> mTxInlineFrame; nsAutoArrayPtr<char> mTxInlineFrame;
@@ -200,6 +206,9 @@ private:
// based on nsISupportsPriority definitions // based on nsISupportsPriority definitions
PRInt32 mPriority; PRInt32 mPriority;
// For Progress Events
PRUint64 mTotalSent;
PRUint64 mTotalRead;
}; };
}} // namespace mozilla::net }} // namespace mozilla::net

View File

@@ -75,7 +75,6 @@ HISTOGRAM(CYCLE_COLLECTOR_TIME_BETWEEN, 1, 120, 50, EXPONENTIAL, "Time spent in
*/ */
HISTOGRAM(GC_REASON, 1, 20, 20, LINEAR, "Reason (enum value) for initiating a GC") HISTOGRAM(GC_REASON, 1, 20, 20, LINEAR, "Reason (enum value) for initiating a GC")
HISTOGRAM_BOOLEAN(GC_IS_COMPARTMENTAL, "Is it a compartmental GC?") HISTOGRAM_BOOLEAN(GC_IS_COMPARTMENTAL, "Is it a compartmental GC?")
HISTOGRAM_BOOLEAN(GC_IS_SHAPE_REGEN, "Is it a shape regenerating GC?")
HISTOGRAM(GC_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC (ms)") HISTOGRAM(GC_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC (ms)")
HISTOGRAM(GC_MARK_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC mark phase (ms)") HISTOGRAM(GC_MARK_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC mark phase (ms)")
HISTOGRAM(GC_SWEEP_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC sweep phase (ms)") HISTOGRAM(GC_SWEEP_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC sweep phase (ms)")

View File

@@ -137,6 +137,42 @@ function getSimpleMeasurements() {
return ret; return ret;
} }
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other installations of the application that may use the same profile.
*/
function getUpdateChannel() {
var channel = "default";
var prefName;
var prefValue;
var defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
// use default when pref not found
}
try {
var partners = Services.prefs.getChildList("app.partner.");
if (partners.length) {
channel += "-cck";
partners.sort();
for each (prefName in partners) {
prefValue = Services.prefs.getCharPref(prefName);
channel += "-" + prefValue;
}
}
}
catch (e) {
Cu.reportError(e);
}
return channel;
}
function TelemetryPing() {} function TelemetryPing() {}
TelemetryPing.prototype = { TelemetryPing.prototype = {
@@ -231,7 +267,8 @@ TelemetryPing.prototype = {
appVersion: ai.version, appVersion: ai.version,
appName: ai.name, appName: ai.name,
appBuildID: ai.appBuildID, appBuildID: ai.appBuildID,
platformBuildID: ai.platformBuildID, appUpdateChannel: getUpdateChannel(),
platformBuildID: ai.platformBuildID
}; };
// sysinfo fields are not always available, get what we can. // sysinfo fields are not always available, get what we can.

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
* *
@@ -214,8 +214,17 @@ static const char kOOMAllocationSizeParameter[] = "OOMAllocationSize=";
static const int kOOMAllocationSizeParameterLen = static const int kOOMAllocationSizeParameterLen =
sizeof(kOOMAllocationSizeParameter)-1; sizeof(kOOMAllocationSizeParameter)-1;
static const char kAvailablePageFileParameter[] = "AvailablePageFile=";
static const int kAvailablePageFileParameterLen =
sizeof(kAvailablePageFileParameter)-1;
static const char kAvailablePhysicalMemoryParameter[] = "AvailablePhysicalMemory=";
static const int kAvailablePhysicalMemoryParameterLen =
sizeof(kAvailablePhysicalMemoryParameter)-1;
// this holds additional data sent via the API // this holds additional data sent via the API
static Mutex* crashReporterAPILock; static Mutex* crashReporterAPILock;
static Mutex* notesFieldLock;
static AnnotationTable* crashReporterAPIData_Hash; static AnnotationTable* crashReporterAPIData_Hash;
static nsCString* crashReporterAPIData = nsnull; static nsCString* crashReporterAPIData = nsnull;
static nsCString* notesField = nsnull; static nsCString* notesField = nsnull;
@@ -454,34 +463,31 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
&nBytes, NULL); &nBytes, NULL);
WriteFile(hFile, "\n", 1, &nBytes, NULL); WriteFile(hFile, "\n", 1, &nBytes, NULL);
} }
// Try to get some information about memory. // Try to get some information about memory.
MEMORYSTATUSEX statex; MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex); statex.dwLength = sizeof(statex);
if (GlobalMemoryStatusEx(&statex)) { if (GlobalMemoryStatusEx(&statex)) {
char buffer[128]; char buffer[128];
int bufferLen; int bufferLen;
WriteFile(hFile, kSysMemoryParameter,
kSysMemoryParameterLen, &nBytes, NULL); #define WRITE_STATEX_FIELD(field, paramName, conversionFunc) \
ltoa(statex.dwMemoryLoad, buffer, 10); WriteFile(hFile, k##paramName##Parameter, \
bufferLen = strlen(buffer); k##paramName##ParameterLen, &nBytes, NULL); \
WriteFile(hFile, buffer, bufferLen, conversionFunc(statex.field, buffer, 10); \
&nBytes, NULL); bufferLen = strlen(buffer); \
WriteFile(hFile, "\n", 1, &nBytes, NULL); WriteFile(hFile, buffer, bufferLen, &nBytes, NULL); \
WriteFile(hFile, kTotalVirtualMemoryParameter,
kTotalVirtualMemoryParameterLen, &nBytes, NULL);
_ui64toa(statex.ullTotalVirtual, buffer, 10);
bufferLen = strlen(buffer);
WriteFile(hFile, buffer, bufferLen,
&nBytes, NULL);
WriteFile(hFile, "\n", 1, &nBytes, NULL);
WriteFile(hFile, kAvailableVirtualMemoryParameter,
kAvailableVirtualMemoryParameterLen, &nBytes, NULL);
_ui64toa(statex.ullAvailVirtual, buffer, 10);
bufferLen = strlen(buffer);
WriteFile(hFile, buffer, bufferLen,
&nBytes, NULL);
WriteFile(hFile, "\n", 1, &nBytes, NULL); WriteFile(hFile, "\n", 1, &nBytes, NULL);
WRITE_STATEX_FIELD(dwMemoryLoad, SysMemory, ltoa);
WRITE_STATEX_FIELD(ullTotalVirtual, TotalVirtualMemory, _ui64toa);
WRITE_STATEX_FIELD(ullAvailVirtual, AvailableVirtualMemory, _ui64toa);
WRITE_STATEX_FIELD(ullAvailPageFile, AvailablePageFile, _ui64toa);
WRITE_STATEX_FIELD(ullAvailPhys, AvailablePhysicalMemory, _ui64toa);
#undef WRITE_STATEX_FIELD
} }
if (oomAllocationSizeBufferLen) { if (oomAllocationSizeBufferLen) {
WriteFile(hFile, kOOMAllocationSizeParameter, WriteFile(hFile, kOOMAllocationSizeParameter,
kOOMAllocationSizeParameterLen, &nBytes, NULL); kOOMAllocationSizeParameterLen, &nBytes, NULL);
@@ -657,6 +663,8 @@ nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
NS_ASSERTION(!crashReporterAPILock, "Shouldn't have a lock yet"); NS_ASSERTION(!crashReporterAPILock, "Shouldn't have a lock yet");
crashReporterAPILock = new Mutex("crashReporterAPILock"); crashReporterAPILock = new Mutex("crashReporterAPILock");
NS_ASSERTION(!notesFieldLock, "Shouldn't have a lock yet");
notesFieldLock = new Mutex("notesFieldLock");
crashReporterAPIData_Hash = crashReporterAPIData_Hash =
new nsDataHashtable<nsCStringHashKey,nsCString>(); new nsDataHashtable<nsCStringHashKey,nsCString>();
@@ -1086,6 +1094,9 @@ nsresult UnsetExceptionHandler()
delete crashReporterAPILock; delete crashReporterAPILock;
crashReporterAPILock = nsnull; crashReporterAPILock = nsnull;
delete notesFieldLock;
notesFieldLock = nsnull;
delete crashReporterAPIData; delete crashReporterAPIData;
crashReporterAPIData = nsnull; crashReporterAPIData = nsnull;
@@ -1255,6 +1266,10 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
if (XRE_GetProcessType() != GeckoProcessType_Default) { if (XRE_GetProcessType() != GeckoProcessType_Default) {
if (!NS_IsMainThread()) {
NS_ERROR("Cannot call AnnotateCrashReport in child processes from non-main thread.");
return NS_ERROR_FAILURE;
}
PCrashReporterChild* reporter = CrashReporterChild::GetCrashReporter(); PCrashReporterChild* reporter = CrashReporterChild::GetCrashReporter();
if (!reporter) { if (!reporter) {
EnqueueDelayedNote(new DelayedNote(data)); EnqueueDelayedNote(new DelayedNote(data));
@@ -1274,6 +1289,8 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
return NS_OK; return NS_OK;
} }
MutexAutoLock lock(*notesFieldLock);
notesField->Append(data); notesField->Append(data);
return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField); return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField);
} }

View File

@@ -66,11 +66,12 @@ bool GetMinidumpPath(nsAString& aPath);
nsresult SetMinidumpPath(const nsAString& aPath); nsresult SetMinidumpPath(const nsAString& aPath);
// AnnotateCrashReport may be called from any thread in a chrome process, // AnnotateCrashReport and AppendAppNotesToCrashReport may be called from any
// but may only be called from the main thread in a content process. // thread in a chrome process, but may only be called from the main thread in
// a content process.
nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data); nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data);
nsresult AppendAppNotesToCrashReport(const nsACString& data); nsresult AppendAppNotesToCrashReport(const nsACString& data);
nsresult SetRestartArgs(int argc, char** argv); nsresult SetRestartArgs(int argc, char** argv);
nsresult SetupExtraData(nsILocalFile* aAppDataDirectory, nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
const nsACString& aBuildID); const nsACString& aBuildID);

View File

@@ -6,9 +6,13 @@ function run_test()
} }
var is_win7_or_newer = false; var is_win7_or_newer = false;
var is_windows = false;
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"] var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"]
.getService(Components.interfaces.nsIHttpProtocolHandler); .getService(Components.interfaces.nsIHttpProtocolHandler);
var match = ph.userAgent.match(/Windows NT (\d+).(\d+)/); var match = ph.userAgent.match(/Windows NT (\d+).(\d+)/);
if (match) {
is_windows = true;
}
if (match && (parseInt(match[1]) > 6 || if (match && (parseInt(match[1]) > 6 ||
parseInt(match[1]) == 6 && parseInt(match[2]) >= 1)) { parseInt(match[1]) == 6 && parseInt(match[2]) >= 1)) {
is_win7_or_newer = true; is_win7_or_newer = true;
@@ -22,6 +26,12 @@ function run_test()
do_check_true('CrashTime' in extra); do_check_true('CrashTime' in extra);
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_THREAD_LIST_STREAM)); do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_THREAD_LIST_STREAM));
do_check_true(CrashTestUtils.dumpHasInstructionPointerMemory(mdump.path)); do_check_true(CrashTestUtils.dumpHasInstructionPointerMemory(mdump.path));
if (is_windows) {
['SystemMemoryUsePercentage', 'TotalVirtualMemory', 'AvailableVirtualMemory',
'AvailablePageFile', 'AvailablePhysicalMemory'].forEach(function(prop) {
do_check_true(extra[prop].toString().match(/^\d+$/));
});
}
if (is_win7_or_newer) if (is_win7_or_newer)
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM)); do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM));
}); });

View File

@@ -425,6 +425,7 @@ OS_LIBS += \
-lmedia \ -lmedia \
-lhardware_legacy \ -lhardware_legacy \
-lhardware \ -lhardware \
-lutils \
$(NULL) $(NULL)
endif endif

View File

@@ -42,7 +42,6 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/input.h>
#include <signal.h> #include <signal.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -53,6 +52,7 @@
#include "nscore.h" #include "nscore.h"
#include "mozilla/FileUtils.h" #include "mozilla/FileUtils.h"
#include "mozilla/Mutex.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "nsAppShell.h" #include "nsAppShell.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
@@ -61,26 +61,9 @@
#include "nsWindow.h" #include "nsWindow.h"
#include "android/log.h" #include "android/log.h"
#include "ui/EventHub.h"
#ifndef ABS_MT_TOUCH_MAJOR #include "ui/InputReader.h"
// Taken from include/linux/input.h #include "ui/InputDispatcher.h"
// XXX update the bionic input.h so we don't have to do this!
#define ABS_X 0x00
#define ABS_Y 0x01
// ...
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
#define SYN_MT_REPORT 2
#endif
#define LOG(args...) \ #define LOG(args...) \
__android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
@@ -93,6 +76,7 @@
#endif #endif
using namespace mozilla; using namespace mozilla;
using namespace android;
bool gDrawRequest = false; bool gDrawRequest = false;
static nsAppShell *gAppShell = NULL; static nsAppShell *gAppShell = NULL;
@@ -123,21 +107,15 @@ pipeHandler(int fd, FdHandler *data)
} while (len > 0); } while (len > 0);
} }
static
PRUint64 timevalToMS(const struct timeval &time)
{
return time.tv_sec * 1000 + time.tv_usec / 1000;
}
static void static void
sendMouseEvent(PRUint32 msg, struct timeval& time, int x, int y) sendMouseEvent(PRUint32 msg, uint64_t timeMs, int x, int y)
{ {
nsMouseEvent event(true, msg, NULL, nsMouseEvent event(true, msg, NULL,
nsMouseEvent::eReal, nsMouseEvent::eNormal); nsMouseEvent::eReal, nsMouseEvent::eNormal);
event.refPoint.x = x; event.refPoint.x = x;
event.refPoint.y = y; event.refPoint.y = y;
event.time = timevalToMS(time); event.time = timeMs;
event.isShift = false; event.isShift = false;
event.isControl = false; event.isControl = false;
event.isMeta = false; event.isMeta = false;
@@ -152,64 +130,64 @@ sendMouseEvent(PRUint32 msg, struct timeval& time, int x, int y)
static nsEventStatus static nsEventStatus
sendKeyEventWithMsg(PRUint32 keyCode, sendKeyEventWithMsg(PRUint32 keyCode,
PRUint32 msg, PRUint32 msg,
const timeval &time, uint64_t timeMs,
PRUint32 flags) PRUint32 flags)
{ {
nsKeyEvent event(true, msg, NULL); nsKeyEvent event(true, msg, NULL);
event.keyCode = keyCode; event.keyCode = keyCode;
event.time = timevalToMS(time); event.time = timeMs;
event.flags |= flags; event.flags |= flags;
return nsWindow::DispatchInputEvent(event); return nsWindow::DispatchInputEvent(event);
} }
static void static void
sendKeyEvent(PRUint32 keyCode, bool down, const timeval &time) sendKeyEvent(PRUint32 keyCode, bool down, uint64_t timeMs)
{ {
nsEventStatus status = nsEventStatus status =
sendKeyEventWithMsg(keyCode, down ? NS_KEY_DOWN : NS_KEY_UP, time, 0); sendKeyEventWithMsg(keyCode, down ? NS_KEY_DOWN : NS_KEY_UP, timeMs, 0);
if (down) { if (down) {
sendKeyEventWithMsg(keyCode, NS_KEY_PRESS, time, sendKeyEventWithMsg(keyCode, NS_KEY_PRESS, timeMs,
status == nsEventStatus_eConsumeNoDefault ? status == nsEventStatus_eConsumeNoDefault ?
NS_EVENT_FLAG_NO_DEFAULT : 0); NS_EVENT_FLAG_NO_DEFAULT : 0);
} }
} }
static void static void
sendSpecialKeyEvent(nsIAtom *command, const timeval &time) sendSpecialKeyEvent(nsIAtom *command, uint64_t timeMs)
{ {
nsCommandEvent event(true, nsGkAtoms::onAppCommand, command, NULL); nsCommandEvent event(true, nsGkAtoms::onAppCommand, command, NULL);
event.time = timevalToMS(time); event.time = timeMs;
nsWindow::DispatchInputEvent(event); nsWindow::DispatchInputEvent(event);
} }
static void static void
maybeSendKeyEvent(int keyCode, bool pressed, const timeval& time) maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs)
{ {
switch (keyCode) { switch (keyCode) {
case KEY_BACK: case KEY_BACK:
sendKeyEvent(NS_VK_ESCAPE, pressed, time); sendKeyEvent(NS_VK_ESCAPE, pressed, timeMs);
break; break;
case KEY_MENU: case KEY_MENU:
if (!pressed) if (!pressed)
sendSpecialKeyEvent(nsGkAtoms::Menu, time); sendSpecialKeyEvent(nsGkAtoms::Menu, timeMs);
break; break;
case KEY_SEARCH: case KEY_SEARCH:
if (pressed) if (pressed)
sendSpecialKeyEvent(nsGkAtoms::Search, time); sendSpecialKeyEvent(nsGkAtoms::Search, timeMs);
break; break;
case KEY_HOME: case KEY_HOME:
sendKeyEvent(NS_VK_HOME, pressed, time); sendKeyEvent(NS_VK_HOME, pressed, timeMs);
break; break;
case KEY_POWER: case KEY_POWER:
sendKeyEvent(NS_VK_SLEEP, pressed, time); sendKeyEvent(NS_VK_SLEEP, pressed, timeMs);
break; break;
case KEY_VOLUMEUP: case KEY_VOLUMEUP:
if (pressed) if (pressed)
sendSpecialKeyEvent(nsGkAtoms::VolumeUp, time); sendSpecialKeyEvent(nsGkAtoms::VolumeUp, timeMs);
break; break;
case KEY_VOLUMEDOWN: case KEY_VOLUMEDOWN:
if (pressed) if (pressed)
sendSpecialKeyEvent(nsGkAtoms::VolumeDown, time); sendSpecialKeyEvent(nsGkAtoms::VolumeDown, timeMs);
break; break;
default: default:
VERBOSE_LOG("Got unknown key event code. type 0x%04x code 0x%04x value %d", VERBOSE_LOG("Got unknown key event code. type 0x%04x code 0x%04x value %d",
@@ -217,35 +195,139 @@ maybeSendKeyEvent(int keyCode, bool pressed, const timeval& time)
} }
} }
static void struct UserInputData {
maybeSendKeyEvent(const input_event& e) uint64_t timeMs;
enum {
MOTION_DATA,
KEY_DATA
} type;
int32_t action;
int32_t flags;
int32_t metaState;
union {
struct {
int32_t keyCode;
int32_t scanCode;
} key;
struct {
PointerCoords coords;
} motion;
};
};
class GeckoInputReaderPolicy : public InputReaderPolicyInterface {
public:
GeckoInputReaderPolicy() {}
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation);
virtual bool filterTouchEvents();
virtual bool filterJumpyTouchEvents();
virtual nsecs_t getVirtualKeyQuietTime();
virtual void getVirtualKeyDefinitions(const String8& deviceName,
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
virtual void getInputDeviceCalibration(const String8& deviceName,
InputDeviceCalibration& outCalibration);
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
protected:
virtual ~GeckoInputReaderPolicy() {}
};
class GeckoInputDispatcher : public InputDispatcherInterface {
public:
GeckoInputDispatcher()
: mQueueLock("GeckoInputDispatcher::mQueueMutex")
{}
virtual void dump(String8& dump);
// Called on the main thread
virtual void dispatchOnce();
// notify* methods are called on the InputReaderThread
virtual void notifyConfigurationChanged(nsecs_t eventTime);
virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
int32_t scanCode, int32_t metaState, nsecs_t downTime);
virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
uint32_t policyFlags, int32_t action, int32_t flags,
int32_t metaState, int32_t edgeFlags,
uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime);
virtual void notifySwitch(nsecs_t when,
int32_t switchCode, int32_t switchValue, uint32_t policyFlags);
virtual int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
virtual void setFocusedApplication(const InputApplication* inputApplication);
virtual void setInputDispatchMode(bool enabled, bool frozen);
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor);
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
protected:
virtual ~GeckoInputDispatcher() {}
private:
// mQueueLock should generally be locked while using mEventQueue.
// UserInputData is pushed on on the InputReaderThread and
// popped and dispatched on the main thread.
mozilla::Mutex mQueueLock;
std::queue<UserInputData> mEventQueue;
};
// GeckoInputReaderPolicy
bool
GeckoInputReaderPolicy::getDisplayInfo(int32_t displayId,
int32_t* width,
int32_t* height,
int32_t* orientation)
{ {
if (e.type != EV_KEY) { // 0 is the default displayId. We only support one display
VERBOSE_LOG("Got unknown key event type. type 0x%04x code 0x%04x value %d", if (displayId)
e.type, e.code, e.value); return false;
return;
}
if (e.value != 0 && e.value != 1) { if (width)
VERBOSE_LOG("Got unknown key event value. type 0x%04x code 0x%04x value %d", *width = gScreenBounds.width;
e.type, e.code, e.value); if (height)
return; *height = gScreenBounds.height;
} if (orientation)
*orientation = ROTATION_0;
bool pressed = e.value == 1; return true;
maybeSendKeyEvent(e.code, pressed, e.time);
} }
static void bool
configureVButtons(FdHandler& data) GeckoInputReaderPolicy::filterTouchEvents()
{ {
return false;
}
bool
GeckoInputReaderPolicy::filterJumpyTouchEvents()
{
return false;
}
nsecs_t
GeckoInputReaderPolicy::getVirtualKeyQuietTime()
{
return 0;
}
void
GeckoInputReaderPolicy::getVirtualKeyDefinitions(const String8& deviceName,
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions)
{
outVirtualKeyDefinitions.clear();
char vbuttonsPath[PATH_MAX]; char vbuttonsPath[PATH_MAX];
snprintf(vbuttonsPath, sizeof(vbuttonsPath), snprintf(vbuttonsPath, sizeof(vbuttonsPath),
"/sys/board_properties/virtualkeys.%s", "/sys/board_properties/virtualkeys.%s",
data.name); deviceName.string());
ScopedClose fd(open(vbuttonsPath, O_RDONLY)); ScopedClose fd(open(vbuttonsPath, O_RDONLY));
if (0 > fd.mFd) { if (0 > fd.mFd) {
LOG("No vbuttons for mt device %s", data.name); LOG("No vbuttons for mt device %s", deviceName.string());
return; return;
} }
@@ -263,31 +345,23 @@ configureVButtons(FdHandler& data)
config[nread] = '\0'; config[nread] = '\0';
LOG("Device %s has vbutton config '%s'", data.name, config); LOG("Device %s has vbutton config '%s'", deviceName.string(), config);
char* startStr = config; char* first = config;
for (size_t i = 0; i < FdHandler::kMaxVButtons; ++i) { char* magic;
FdHandler::VButton& vbutton = data.vbuttons[i]; char* state;
char* token; while ((magic = strtok_r(first, ":", &state))) {
char* state;
// XXX not clear what "0x01" is ... maybe a version // XXX not clear what "0x01" is ... maybe a version
// number? See InputManager.java. // number? See InputManager.java.
if (!(token = strtok_r(startStr, ":", &state)) || if (strcmp(magic, "0x01")) {
strcmp(token, "0x01")) {
LOG(" magic 0x01 tag missing"); LOG(" magic 0x01 tag missing");
break; break;
} }
startStr = NULL; first = NULL;
if (!(token = strtok_r(NULL, ":", &state))) { const char *scanCode, *centerX, *centerY, *width, *height;
LOG(" failed to read keycode"); if (!((scanCode = strtok_r(NULL, ":", &state)) &&
break; (centerX = strtok_r(NULL, ":", &state)) &&
}
vbutton.keyCode = atoi(token);
const char *centerX, *centerY, *width, *height;
if (!((centerX = strtok_r(NULL, ":", &state)) &&
(centerY = strtok_r(NULL, ":", &state)) && (centerY = strtok_r(NULL, ":", &state)) &&
(width = strtok_r(NULL, ":", &state)) && (width = strtok_r(NULL, ":", &state)) &&
(height = strtok_r(NULL, ":", &state)))) { (height = strtok_r(NULL, ":", &state)))) {
@@ -299,247 +373,194 @@ configureVButtons(FdHandler& data)
// space. That means the values in /sys/board_config make // space. That means the values in /sys/board_config make
// assumptions about how the raw input events are mapped // assumptions about how the raw input events are mapped
// ... le sigh. // ... le sigh.
nsIntRect rect; VirtualKeyDefinition def;
rect.width = atoi(width); def.scanCode = atoi(scanCode);
rect.height = atoi(height); def.centerX = atoi(centerX);
rect.x = atoi(centerX) - rect.width / 2; def.centerY = atoi(centerY);
rect.y = atoi(centerY) - rect.height / 2; def.width = atoi(width);
vbutton.buttonRect = rect; def.height = atoi(height);
outVirtualKeyDefinitions.push(def);
LOG(" configured vbutton code=%d at <x=%d,y=%d,w=%d,h=%d>", LOG(" configured vbutton code=%d at <x=%d,y=%d,w=%d,h=%d>",
vbutton.keyCode, rect.x, rect.y, rect.width, rect.height); def.scanCode, def.centerX, def.centerY, def.width, def.height);
} }
} }
static bool void
calibrateMultitouchDevice(FdHandler& data) GeckoInputReaderPolicy::getInputDeviceCalibration(const String8& deviceName, InputDeviceCalibration& outCalibration)
{ {
if (data.calibrated) outCalibration.clear();
return true;
if (gScreenBounds.IsEmpty()) {
// The framebuffer hasn't been initialized yet. We *could*
// force it to be initialized here, but that's another patch.
LOG("Deferring multitouch calibrate, fb not ready");
return false;
}
struct input_absinfo xInfo, yInfo;
if (0 > ioctl(data.fd, EVIOCGABS(ABS_MT_POSITION_X), &xInfo) ||
0 > ioctl(data.fd, EVIOCGABS(ABS_MT_POSITION_Y), &yInfo)) {
LOG("Couldn't get absinfo for multitouch axes");
return false;
}
LOG("Input coordinate bounds: xmin=%d, xmax=%d, ymin=%d, ymax=%d",
xInfo.minimum, xInfo.maximum, yInfo.minimum, yInfo.maximum);
data.inputMinX = xInfo.minimum;
data.inputMinY = yInfo.minimum;
data.inputToScreenScaleX =
float(gScreenBounds.width) / float(xInfo.maximum - xInfo.minimum);
data.inputToScreenScaleY =
float(gScreenBounds.height) / float(yInfo.maximum - yInfo.minimum);
configureVButtons(data);
data.calibrated = true;
return true;
} }
static void void
multitouchHandler(int fd, FdHandler *data) GeckoInputReaderPolicy::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames)
{ {
if (!calibrateMultitouchDevice(*data)) outExcludedDeviceNames.clear();
return;
// The Linux's input documentation (Documentation/input/input.txt)
// says that we'll always read a multiple of sizeof(input_event) bytes here.
input_event events[16];
int event_count = read(fd, events, sizeof(events));
if (event_count < 0) {
LOG("Error reading in multitouchHandler");
return;
}
MOZ_ASSERT(event_count % sizeof(input_event) == 0);
event_count /= sizeof(struct input_event);
for (int i = 0; i < event_count; i++) {
input_event *event = &events[i];
if (event->type == EV_ABS) {
if (data->mtState == FdHandler::MT_IGNORE)
continue;
if (data->mtState == FdHandler::MT_START)
data->mtState = FdHandler::MT_COLLECT;
switch (event->code) {
case ABS_MT_TOUCH_MAJOR:
data->mtMajor = event->value;
break;
case ABS_MT_TOUCH_MINOR:
case ABS_MT_WIDTH_MAJOR:
case ABS_MT_WIDTH_MINOR:
case ABS_MT_ORIENTATION:
case ABS_MT_TOOL_TYPE:
case ABS_MT_BLOB_ID:
case ABS_MT_TRACKING_ID:
case ABS_MT_PRESSURE:
break;
case ABS_MT_POSITION_X:
data->mtX = data->inputXToScreenX(event->value);
break;
case ABS_MT_POSITION_Y:
data->mtY = data->inputYToScreenY(event->value);
break;
default:
VERBOSE_LOG("Got unknown mt event type 0x%04x with code 0x%04x and value %d",
event->type, event->code, event->value);
break;
}
} else if (event->type == EV_SYN) {
switch (event->code) {
case SYN_MT_REPORT:
if (data->mtState == FdHandler::MT_COLLECT)
data->mtState = FdHandler::MT_IGNORE;
break;
case SYN_REPORT:
if (!data->mtMajor || data->mtState == FdHandler::MT_START) {
data->mtDown = false;
if (data->keyCode) {
maybeSendKeyEvent(data->keyCode, data->mtDown,
event->time);
data->keyCode = 0;
} else {
sendMouseEvent(NS_MOUSE_BUTTON_UP, event->time,
data->mtX, data->mtY);
}
} else if (!data->mtDown) {
int x = data->mtX, y = data->mtY;
bool isKeyEvent = false;
if (!gScreenBounds.Contains(x, y)) {
// Off-screen mt down. Should be a vbutton.
for (size_t i = 0; i < FdHandler::kMaxVButtons; ++i) {
const FdHandler::VButton& vbutton = data->vbuttons[i];
if (vbutton.buttonRect.IsEmpty())
break;
if (vbutton.buttonRect.Contains(x, y)) {
isKeyEvent = true;
data->keyCode = vbutton.keyCode;
break;
}
}
}
data->mtDown = true;
if (isKeyEvent) {
maybeSendKeyEvent(data->keyCode, data->mtDown,
event->time);
} else {
sendMouseEvent(NS_MOUSE_BUTTON_DOWN, event->time,
data->mtX, data->mtY);
}
} else if (!data->keyCode) {
sendMouseEvent(NS_MOUSE_MOVE, event->time,
data->mtX, data->mtY);
data->mtDown = true;
}
data->mtState = FdHandler::MT_START;
break;
default:
VERBOSE_LOG("Got unknown mt event type 0x%04x with code 0x%04x and value %d",
event->type, event->code, event->value);
}
} else
VERBOSE_LOG("Got unknown mt event type 0x%04x with code 0x%04x and value %d",
event->type, event->code, event->value);
}
} }
static void // GeckoInputDispatcher
singleTouchHandler(int fd, FdHandler *data) void
GeckoInputDispatcher::dump(String8& dump)
{ {
// The Linux's input documentation (Documentation/input/input.txt) }
// says that we'll always read a multiple of sizeof(input_event) bytes here.
input_event events[16]; void
int event_count = read(fd, events, sizeof(events)); GeckoInputDispatcher::dispatchOnce()
if (event_count < 0) { {
LOG("Error reading in singleTouchHandler"); UserInputData data;
return; {
MutexAutoLock lock(mQueueLock);
if (mEventQueue.empty())
return;
data = mEventQueue.front();
mEventQueue.pop();
if (!mEventQueue.empty())
gAppShell->NotifyNativeEvent();
} }
MOZ_ASSERT(event_count % sizeof(input_event) == 0);
event_count /= sizeof(struct input_event); switch (data.type) {
case UserInputData::MOTION_DATA: {
for (int i = 0; i < event_count; i++) { PRUint32 msg;
input_event *event = &events[i]; switch (data.action) {
case AMOTION_EVENT_ACTION_DOWN:
if (event->type == EV_KEY) { msg = NS_MOUSE_BUTTON_DOWN;
switch (event->code) { break;
case BTN_TOUCH: case AMOTION_EVENT_ACTION_MOVE:
data->mtDown = event->value; msg = NS_MOUSE_MOVE;
break; break;
default: case AMOTION_EVENT_ACTION_UP:
maybeSendKeyEvent(*event); msg = NS_MOUSE_BUTTON_UP;
} break;
} else if (event->type == EV_ABS) {
switch (event->code) {
case ABS_X:
data->mtX = event->value;
break;
case ABS_Y:
data->mtY = event->value;
break;
default:
LOG("Got unknown st abs event type 0x%04x with code 0x%04x and value %d",
event->type, event->code, event->value);
}
} else if (event->type == EV_SYN) {
if (data->mtState == FdHandler::MT_START) {
MOZ_ASSERT(data->mtDown);
sendMouseEvent(NS_MOUSE_BUTTON_DOWN, event->time,
data->mtX, data->mtY);
data->mtState = FdHandler::MT_COLLECT;
} else if (data->mtDown) {
MOZ_ASSERT(data->mtDown);
sendMouseEvent(NS_MOUSE_MOVE, event->time,
data->mtX, data->mtY);
} else {
MOZ_ASSERT(!data->mtDown);
sendMouseEvent(NS_MOUSE_BUTTON_UP, event->time,
data->mtX, data->mtY);
data->mtDown = false;
data->mtState = FdHandler::MT_START;
}
} }
sendMouseEvent(msg,
data.timeMs,
data.motion.coords.x,
data.motion.coords.y);
break;
}
case UserInputData::KEY_DATA:
maybeSendKeyEvent(data.key.scanCode,
data.action == AKEY_EVENT_ACTION_DOWN,
data.timeMs);
break;
} }
} }
static void
keyHandler(int fd, FdHandler *data) void
GeckoInputDispatcher::notifyConfigurationChanged(nsecs_t eventTime)
{ {
input_event events[16]; }
ssize_t bytesRead = read(fd, events, sizeof(events));
if (bytesRead < 0) { static uint64_t
LOG("Error reading in keyHandler"); nanosecsToMillisecs(nsecs_t nsecs)
return; {
return nsecs / 1000000;
}
void
GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
int32_t deviceId,
int32_t source,
uint32_t policyFlags,
int32_t action,
int32_t flags,
int32_t keyCode,
int32_t scanCode,
int32_t metaState,
nsecs_t downTime)
{
UserInputData data;
data.timeMs = nanosecsToMillisecs(eventTime);
data.type = UserInputData::KEY_DATA;
data.action = action;
data.flags = flags;
data.metaState = metaState;
data.key.keyCode = keyCode;
data.key.scanCode = scanCode;
{
MutexAutoLock lock(mQueueLock);
mEventQueue.push(data);
} }
MOZ_ASSERT(bytesRead % sizeof(input_event) == 0); gAppShell->NotifyNativeEvent();
}
for (unsigned int i = 0; i < bytesRead / sizeof(struct input_event); i++) { void
const input_event &e = events[i]; GeckoInputDispatcher::notifyMotion(nsecs_t eventTime,
int32_t deviceId,
if (e.type == EV_SYN) { int32_t source,
// Ignore this event; it just signifies that a key was pressed. uint32_t policyFlags,
continue; int32_t action,
} int32_t flags,
int32_t metaState,
maybeSendKeyEvent(e); int32_t edgeFlags,
uint32_t pointerCount,
const int32_t* pointerIds,
const PointerCoords* pointerCoords,
float xPrecision,
float yPrecision,
nsecs_t downTime)
{
UserInputData data;
data.timeMs = nanosecsToMillisecs(eventTime);
data.type = UserInputData::MOTION_DATA;
data.action = action;
data.flags = flags;
data.metaState = metaState;
data.motion.coords = *pointerCoords;
{
MutexAutoLock lock(mQueueLock);
mEventQueue.push(data);
} }
gAppShell->NotifyNativeEvent();
}
void
GeckoInputDispatcher::notifySwitch(nsecs_t when,
int32_t switchCode,
int32_t switchValue,
uint32_t policyFlags)
{
}
int32_t
GeckoInputDispatcher::injectInputEvent(const InputEvent* event,
int32_t injectorPid,
int32_t injectorUid,
int32_t syncMode,
int32_t timeoutMillis)
{
return INPUT_EVENT_INJECTION_SUCCEEDED;
}
void
GeckoInputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows)
{
}
void
GeckoInputDispatcher::setFocusedApplication(const InputApplication* inputApplication)
{
}
void
GeckoInputDispatcher::setInputDispatchMode(bool enabled, bool frozen)
{
}
status_t
GeckoInputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
bool monitor)
{
return OK;
}
status_t
GeckoInputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel)
{
return OK;
} }
nsAppShell::nsAppShell() nsAppShell::nsAppShell()
@@ -551,6 +572,9 @@ nsAppShell::nsAppShell()
nsAppShell::~nsAppShell() nsAppShell::~nsAppShell()
{ {
status_t result = mReaderThread->requestExitAndWait();
if (result)
LOG("Could not stop reader thread - %d", result);
gAppShell = NULL; gAppShell = NULL;
} }
@@ -569,52 +593,15 @@ nsAppShell::Init()
rv = AddFdHandler(signalfds[0], pipeHandler, ""); rv = AddFdHandler(signalfds[0], pipeHandler, "");
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
DIR *dir = opendir("/dev/input"); mEventHub = new EventHub();
NS_ENSURE_TRUE(dir, NS_ERROR_UNEXPECTED); mReaderPolicy = new GeckoInputReaderPolicy();
mDispatcher = new GeckoInputDispatcher();
#define IS_BIT_SET(bit, flags) (flags[bit >> 3] & (1 << (bit & 0x7))) mReader = new InputReader(mEventHub, mReaderPolicy, mDispatcher);
mReaderThread = new InputReaderThread(mReader);
struct dirent *entry;
while ((entry = readdir(dir))) {
char entryName[64];
char entryPath[MAXPATHLEN];
if (snprintf(entryPath, sizeof(entryPath),
"/dev/input/%s", entry->d_name) < 0) {
LOG("Couldn't generate path while enumerating input devices!");
continue;
}
int fd = open(entryPath, O_RDONLY);
if (ioctl(fd, EVIOCGNAME(sizeof(entryName)), entryName) >= 0)
LOG("Found device %s - %s", entry->d_name, entryName);
else
continue;
FdHandlerCallback handlerFunc = NULL;
char flags[(NS_MAX(ABS_MAX, KEY_MAX) + 1) / 8];
if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(flags)), flags) >= 0 &&
IS_BIT_SET(ABS_MT_POSITION_X, flags)) {
LOG("Found multitouch input device");
handlerFunc = multitouchHandler;
} else if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(flags)), flags) >= 0 &&
IS_BIT_SET(ABS_X, flags)) {
LOG("Found single touch input device");
handlerFunc = singleTouchHandler;
} else if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(flags)), flags) >= 0) {
LOG("Found key input device");
handlerFunc = keyHandler;
}
// Register the handler, if we have one.
if (!handlerFunc)
continue;
rv = AddFdHandler(fd, handlerFunc, entryName);
if (NS_FAILED(rv))
LOG("Failed to add fd to epoll fd");
}
status_t result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
NS_ENSURE_FALSE(result, NS_ERROR_UNEXPECTED);
return rv; return rv;
} }
@@ -655,6 +642,8 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
for (int i = 0; i < event_count; i++) for (int i = 0; i < event_count; i++)
mHandlers[events[i].data.u32].run(); mHandlers[events[i].data.u32].run();
mDispatcher->dispatchOnce();
// NativeEventCallback always schedules more if it needs it // NativeEventCallback always schedules more if it needs it
// so we can coalesce these. // so we can coalesce these.
// See the implementation in nsBaseAppShell.cpp for more info // See the implementation in nsBaseAppShell.cpp for more info

View File

@@ -38,10 +38,15 @@
#ifndef nsAppShell_h #ifndef nsAppShell_h
#define nsAppShell_h #define nsAppShell_h
#include <queue>
#include "mozilla/Mutex.h"
#include "nsBaseAppShell.h" #include "nsBaseAppShell.h"
#include "nsRect.h" #include "nsRect.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "utils/RefBase.h"
namespace mozilla { namespace mozilla {
bool ProcessNextEvent(); bool ProcessNextEvent();
void NotifyEvent(); void NotifyEvent();
@@ -55,10 +60,6 @@ typedef void(*FdHandlerCallback)(int, FdHandler *);
class FdHandler { class FdHandler {
public: public:
FdHandler() FdHandler()
: mtState(MT_START)
, keyCode(0)
, mtDown(false)
, calibrated(false)
{ {
memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name));
} }
@@ -66,57 +67,21 @@ public:
int fd; int fd;
char name[64]; char name[64];
FdHandlerCallback func; FdHandlerCallback func;
enum mtStates {
MT_START,
MT_COLLECT,
MT_IGNORE
} mtState;
int mtX, mtY;
int mtMajor;
int keyCode;
bool mtDown;
// FIXME/bug 712973: we should be using libui here instead of
// recreating all that logic ourselves. Please don't extend the
// hacks here further than what's below.
bool calibrated;
// Multitouch events are delivered to us in "input space", which
// is a coordinate space defined by the multitouch device driver.
// The coordinate space has top-left at P_min = <inputMinX,
// inputMinY> when in normal-portrait orientation. The input
// device and the screen might have different resolutions. The
// resolution difference is Scale = <inputToScreenScaleX,
// inputToScreenScaleY>. So going from input to screen space
// (when in normal portrait orientation) is an affine transform
// defined by
//
// P_screen = Scale * (P_input - P_min)
//
int inputMinX, inputMinY;
float inputToScreenScaleX, inputToScreenScaleY;
// Some touch devices use virtual buttons instead of hardware
// buttons. When the device uses vbuttons, we convert touch
// events into key events of type |keyCode| when the start of the
// touch is within |buttonRect|. |buttonRect| must be disjoint
// from the screen rect.
static const size_t kMaxVButtons = 4;
struct VButton {
nsIntRect buttonRect; // in screen space
int keyCode;
} vbuttons[kMaxVButtons];
void run() void run()
{ {
func(fd, this); func(fd, this);
} }
int inputXToScreenX(int inputX) {
return inputToScreenScaleX * (inputX - inputMinX);
}
int inputYToScreenY(int inputY) {
return inputToScreenScaleY * (inputY - inputMinY);
}
}; };
namespace android {
class EventHub;
class InputReader;
class InputReaderThread;
}
class GeckoInputReaderPolicy;
class GeckoInputDispatcher;
class nsAppShell : public nsBaseAppShell { class nsAppShell : public nsBaseAppShell {
public: public:
nsAppShell(); nsAppShell();
@@ -138,6 +103,12 @@ private:
// This is somewhat racy but is perfectly safe given how the callback works // This is somewhat racy but is perfectly safe given how the callback works
bool mNativeCallbackRequest; bool mNativeCallbackRequest;
nsTArray<FdHandler> mHandlers; nsTArray<FdHandler> mHandlers;
android::sp<android::EventHub> mEventHub;
android::sp<GeckoInputReaderPolicy> mReaderPolicy;
android::sp<GeckoInputDispatcher> mDispatcher;
android::sp<android::InputReader> mReader;
android::sp<android::InputReaderThread> mReaderThread;
}; };
#endif /* nsAppShell_h */ #endif /* nsAppShell_h */

View File

@@ -47,6 +47,7 @@
#include "nsAppShellSingleton.h" #include "nsAppShellSingleton.h"
#include "nsScreenManagerGonk.h" #include "nsScreenManagerGonk.h"
#include "nsIdleServiceGonk.h" #include "nsIdleServiceGonk.h"
#include "nsTransferable.h"
#include "nsHTMLFormatConverter.h" #include "nsHTMLFormatConverter.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@@ -55,6 +56,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerGonk) NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerGonk)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceGonk) NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceGonk)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
NS_DEFINE_NAMED_CID(NS_WINDOW_CID); NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
@@ -62,6 +64,7 @@ NS_DEFINE_NAMED_CID(NS_CHILD_CID);
NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID); NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
static const mozilla::Module::CIDEntry kWidgetCIDs[] = { static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_WINDOW_CID, false, NULL, nsWindowConstructor }, { &kNS_WINDOW_CID, false, NULL, nsWindowConstructor },
@@ -70,6 +73,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerGonkConstructor }, { &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerGonkConstructor },
{ &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor }, { &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor },
{ &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceGonkConstructor }, { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceGonkConstructor },
{ &kNS_TRANSFERABLE_CID, false, NULL, nsTransferableConstructor },
{ NULL } { NULL }
}; };
@@ -80,6 +84,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID }, { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
{ "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID }, { "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID }, { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
{ "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID },
{ NULL } { NULL }
}; };

View File

@@ -2823,7 +2823,7 @@ nsCycleCollector::GCIfNeeded(bool aForceGC)
// rt->Collect() must be called from the main thread, // rt->Collect() must be called from the main thread,
// because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN) // because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN)
// which returns false if not in the main thread. // which returns false if not in the main thread.
rt->Collect(); rt->Collect(js::gcreason::CC_FORCED, nsGCNormal);
#ifdef COLLECT_TIME_DEBUG #ifdef COLLECT_TIME_DEBUG
printf("cc: GC() took %lldms\n", (PR_Now() - start) / PR_USEC_PER_MSEC); printf("cc: GC() took %lldms\n", (PR_Now() - start) / PR_USEC_PER_MSEC);
#endif #endif

View File

@@ -106,9 +106,10 @@ struct nsCycleCollectionJSRuntime : public nsCycleCollectionLanguageRuntime
virtual bool NeedCollect() = 0; virtual bool NeedCollect() = 0;
/** /**
* Runs the JavaScript GC. * Runs the JavaScript GC. |reason| is a gcreason::Reason from jsfriendapi.h.
* |kind| is a nsGCType from nsIXPConnect.idl.
*/ */
virtual void Collect(bool shrinkingGC = false) = 0; virtual void Collect(PRUint32 reason, PRUint32 kind) = 0;
}; };
#ifdef DEBUG #ifdef DEBUG

View File

@@ -3,7 +3,6 @@ export JAVA_HOME=/d/jdk1.6.0_14
ac_add_options --enable-application=xulrunner ac_add_options --enable-application=xulrunner
ac_add_options --enable-jemalloc ac_add_options --enable-jemalloc
ac_add_options --disable-installer
ac_add_options --disable-tests ac_add_options --disable-tests
mk_add_options MOZ_MAKE_FLAGS=-j1 mk_add_options MOZ_MAKE_FLAGS=-j1

View File

@@ -6,7 +6,6 @@ export JAVA_HOME=/d/jdk1.6.0_14
ac_add_options --enable-application=xulrunner ac_add_options --enable-application=xulrunner
ac_add_options --enable-jemalloc ac_add_options --enable-jemalloc
ac_add_options --disable-installer
ac_add_options --disable-tests ac_add_options --disable-tests
mk_add_options MOZ_MAKE_FLAGS=-j1 mk_add_options MOZ_MAKE_FLAGS=-j1