merge fx-team to m-c
This commit is contained in:
@@ -176,7 +176,8 @@
|
||||
<menuseparator class="appmenu-menuseparator"/>
|
||||
<menu id="appmenu_webDeveloper"
|
||||
label="&appMenuWebDeveloper.label;">
|
||||
<menupopup id="appmenu_webDeveloper_popup">
|
||||
<menupopup id="appmenu_webDeveloper_popup"
|
||||
onpopupshowing="onWebDeveloperMenuShowing();">
|
||||
<menuitem id="appmenu_webConsole"
|
||||
label="&webConsoleCmd.label;"
|
||||
type="checkbox"
|
||||
|
||||
@@ -531,7 +531,8 @@
|
||||
<menu id="webDeveloperMenu"
|
||||
label="&webDeveloperMenu.label;"
|
||||
accesskey="&webDeveloperMenu.accesskey;">
|
||||
<menupopup id="menuWebDeveloperPopup">
|
||||
<menupopup id="menuWebDeveloperPopup"
|
||||
onpopupshowing="onWebDeveloperMenuShowing();">
|
||||
<menuitem id="webConsole"
|
||||
type="checkbox"
|
||||
label="&webConsoleCmd.label;"
|
||||
|
||||
@@ -9063,6 +9063,11 @@ var StyleEditor = {
|
||||
}
|
||||
};
|
||||
|
||||
function onWebDeveloperMenuShowing() {
|
||||
document.getElementById("Tools:WebConsole").setAttribute("checked", HUDConsoleUI.getOpenHUD() != null);
|
||||
}
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
||||
#ifdef XP_WIN
|
||||
// Only show resizers on Windows 2000 and XP
|
||||
@@ -9137,6 +9142,7 @@ var MousePosTracker = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function focusNextFrame(event) {
|
||||
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
|
||||
let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC;
|
||||
|
||||
@@ -741,6 +741,11 @@ iQClass.prototype = {
|
||||
if (pair.original == func) {
|
||||
handler = pair.modified;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -765,10 +770,10 @@ iQClass.prototype = {
|
||||
if (!elem.iQEventData)
|
||||
continue;
|
||||
|
||||
for (let type in elem.iQEventData) {
|
||||
while (elem.iQEventData[type].length)
|
||||
Object.keys(elem.iQEventData).forEach(function (type) {
|
||||
while (elem.iQEventData && elem.iQEventData[type])
|
||||
this.unbind(type, elem.iQEventData[type][0].original);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
@@ -1552,8 +1552,6 @@ HUD_SERVICE.prototype =
|
||||
this.disableAnimation(hudId);
|
||||
}
|
||||
|
||||
chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "true");
|
||||
|
||||
// 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
|
||||
// adding this for so we know when to remove it.
|
||||
@@ -1603,8 +1601,6 @@ HUD_SERVICE.prototype =
|
||||
window.focus();
|
||||
}
|
||||
|
||||
chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "false");
|
||||
|
||||
// Remove this context from the list of contexts that need the GCLI CSS
|
||||
// processing instruction and then remove the processing instruction if it
|
||||
// isn't needed any more.
|
||||
|
||||
@@ -337,6 +337,7 @@ if test -n "$gonkdir" ; then
|
||||
|
||||
AC_DEFINE(ANDROID)
|
||||
AC_DEFINE(HAVE_SYS_UIO_H)
|
||||
AC_DEFINE(HAVE_PTHREADS)
|
||||
CROSS_COMPILE=1
|
||||
MOZ_CHROME_FILE_FORMAT=omni
|
||||
ZLIB_DIR=yes
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
|
||||
#include "nsIDOMStyleSheet.h"
|
||||
#include "nsDOMAttribute.h"
|
||||
@@ -5024,11 +5025,15 @@ NS_IMETHODIMP
|
||||
nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aEntityReferenceExpansion,
|
||||
PRUint8 aOptionalArgc,
|
||||
nsIDOMNodeIterator **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
if (!aOptionalArgc) {
|
||||
aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
|
||||
}
|
||||
|
||||
if (!aRoot)
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
|
||||
@@ -5042,24 +5047,27 @@ nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
|
||||
|
||||
nsNodeIterator *iterator = new nsNodeIterator(root,
|
||||
aWhatToShow,
|
||||
aFilter,
|
||||
aEntityReferenceExpansion);
|
||||
aFilter);
|
||||
NS_ENSURE_TRUE(iterator, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*_retval = iterator);
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aEntityReferenceExpansion,
|
||||
PRUint8 aOptionalArgc,
|
||||
nsIDOMTreeWalker **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
if (!aOptionalArgc) {
|
||||
aWhatToShow = nsIDOMNodeFilter::SHOW_ALL;
|
||||
}
|
||||
|
||||
if (!aRoot)
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
|
||||
@@ -5073,8 +5081,7 @@ nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
|
||||
|
||||
nsTreeWalker* walker = new nsTreeWalker(root,
|
||||
aWhatToShow,
|
||||
aFilter,
|
||||
aEntityReferenceExpansion);
|
||||
aFilter);
|
||||
NS_ENSURE_TRUE(walker, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*_retval = walker);
|
||||
|
||||
@@ -170,9 +170,8 @@ void nsNodeIterator::NodePointer::MoveBackward(nsINode *aParent, nsINode *aNode)
|
||||
|
||||
nsNodeIterator::nsNodeIterator(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences) :
|
||||
nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
|
||||
nsIDOMNodeFilter *aFilter) :
|
||||
nsTraversal(aRoot, aWhatToShow, aFilter),
|
||||
mDetached(false),
|
||||
mPointer(mRoot, true)
|
||||
{
|
||||
@@ -247,7 +246,7 @@ NS_IMETHODIMP nsNodeIterator::GetFilter(nsIDOMNodeFilter **aFilter)
|
||||
/* readonly attribute boolean expandEntityReferences; */
|
||||
NS_IMETHODIMP nsNodeIterator::GetExpandEntityReferences(bool *aExpandEntityReferences)
|
||||
{
|
||||
*aExpandEntityReferences = mExpandEntityReferences;
|
||||
*aExpandEntityReferences = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,7 @@ public:
|
||||
|
||||
nsNodeIterator(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences);
|
||||
nsIDOMNodeFilter *aFilter);
|
||||
virtual ~nsNodeIterator();
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
@@ -49,12 +49,10 @@
|
||||
|
||||
nsTraversal::nsTraversal(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences) :
|
||||
nsIDOMNodeFilter *aFilter) :
|
||||
mRoot(aRoot),
|
||||
mWhatToShow(aWhatToShow),
|
||||
mFilter(aFilter),
|
||||
mExpandEntityReferences(aExpandEntityReferences),
|
||||
mInAcceptNode(false)
|
||||
{
|
||||
NS_ASSERTION(aRoot, "invalid root in call to nsTraversal constructor");
|
||||
|
||||
@@ -54,15 +54,13 @@ class nsTraversal
|
||||
public:
|
||||
nsTraversal(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences);
|
||||
nsIDOMNodeFilter *aFilter);
|
||||
virtual ~nsTraversal();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsINode> mRoot;
|
||||
PRUint32 mWhatToShow;
|
||||
nsCOMPtr<nsIDOMNodeFilter> mFilter;
|
||||
bool mExpandEntityReferences;
|
||||
bool mInAcceptNode;
|
||||
|
||||
/*
|
||||
|
||||
@@ -58,9 +58,8 @@
|
||||
|
||||
nsTreeWalker::nsTreeWalker(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences) :
|
||||
nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
|
||||
nsIDOMNodeFilter *aFilter) :
|
||||
nsTraversal(aRoot, aWhatToShow, aFilter),
|
||||
mCurrentNode(aRoot)
|
||||
{
|
||||
}
|
||||
@@ -127,7 +126,7 @@ NS_IMETHODIMP nsTreeWalker::GetFilter(nsIDOMNodeFilter * *aFilter)
|
||||
NS_IMETHODIMP
|
||||
nsTreeWalker::GetExpandEntityReferences(bool *aExpandEntityReferences)
|
||||
{
|
||||
*aExpandEntityReferences = mExpandEntityReferences;
|
||||
*aExpandEntityReferences = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,7 @@ public:
|
||||
|
||||
nsTreeWalker(nsINode *aRoot,
|
||||
PRUint32 aWhatToShow,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
bool aExpandEntityReferences);
|
||||
nsIDOMNodeFilter *aFilter);
|
||||
virtual ~nsTreeWalker();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeWalker)
|
||||
|
||||
@@ -542,6 +542,7 @@ _TEST_FILES2 = \
|
||||
test_bug708620.html \
|
||||
file_bug708620.html \
|
||||
file_bug708620-2.html \
|
||||
test_bug698384.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
||||
62
content/base/test/test_bug698384.html
Normal file
62
content/base/test/test_bug698384.html
Normal 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>
|
||||
@@ -816,7 +816,7 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener)
|
||||
}
|
||||
#endif
|
||||
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
|
||||
nsJSContext::CycleCollectNow(aListener);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -2272,7 +2272,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
|
||||
}
|
||||
|
||||
mContext->GC();
|
||||
mContext->GC(js::gcreason::SET_NEW_DOCUMENT);
|
||||
mContext->DidInitializeContext();
|
||||
|
||||
if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
|
||||
@@ -2429,7 +2429,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
|
||||
}
|
||||
|
||||
if (mContext) {
|
||||
mContext->GC();
|
||||
mContext->GC(js::gcreason::SET_DOC_SHELL);
|
||||
mContext->FinalizeContext();
|
||||
mContext = nsnull;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIProgrammingLanguage.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jspubtd.h"
|
||||
|
||||
class nsIScriptGlobalObject;
|
||||
@@ -354,7 +355,7 @@ public:
|
||||
*
|
||||
* @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.
|
||||
|
||||
@@ -203,7 +203,7 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
if (sGCOnMemoryPressure) {
|
||||
nsJSContext::GarbageCollectNow(true);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking);
|
||||
nsJSContext::CycleCollectNow();
|
||||
}
|
||||
return NS_OK;
|
||||
@@ -1111,7 +1111,7 @@ nsJSContext::DestroyJSContext()
|
||||
js_options_dot_str, this);
|
||||
|
||||
if (mGCOnDestruction) {
|
||||
PokeGC();
|
||||
PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
|
||||
}
|
||||
|
||||
// Let xpconnect destroy the JSContext when it thinks the time is right.
|
||||
@@ -3220,7 +3220,7 @@ nsJSContext::ScriptExecuted()
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::GarbageCollectNow(bool shrinkingGC)
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
||||
{
|
||||
NS_TIME_FUNCTION_MIN(1.0);
|
||||
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
||||
@@ -3238,7 +3238,7 @@ nsJSContext::GarbageCollectNow(bool shrinkingGC)
|
||||
sLoadingInProgress = false;
|
||||
|
||||
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
|
||||
// might be unreachable now.
|
||||
if (sCCollectedWaitingForGC > 250) {
|
||||
PokeGC();
|
||||
PokeGC(js::gcreason::CC_WAITING);
|
||||
}
|
||||
|
||||
PRTime now = PR_Now();
|
||||
@@ -3315,7 +3315,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_RELEASE(sGCTimer);
|
||||
|
||||
nsJSContext::GarbageCollectNow();
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason), nsGCNormal);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3359,12 +3360,12 @@ nsJSContext::LoadEnd()
|
||||
|
||||
// Its probably a good idea to GC soon since we have finished loading.
|
||||
sLoadingInProgress = false;
|
||||
PokeGC();
|
||||
PokeGC(js::gcreason::LOAD_END);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsJSContext::PokeGC()
|
||||
nsJSContext::PokeGC(js::gcreason::Reason aReason)
|
||||
{
|
||||
if (sGCTimer) {
|
||||
// There's already a timer for GC'ing, just return
|
||||
@@ -3380,7 +3381,7 @@ nsJSContext::PokeGC()
|
||||
|
||||
static bool first = true;
|
||||
|
||||
sGCTimer->InitWithFuncCallback(GCTimerFired, nsnull,
|
||||
sGCTimer->InitWithFuncCallback(GCTimerFired, reinterpret_cast<void *>(aReason),
|
||||
first
|
||||
? NS_FIRST_GC_DELAY
|
||||
: NS_GC_DELAY,
|
||||
@@ -3473,9 +3474,9 @@ nsJSContext::KillCCTimer()
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::GC()
|
||||
nsJSContext::GC(js::gcreason::Reason aReason)
|
||||
{
|
||||
PokeGC();
|
||||
PokeGC(aReason);
|
||||
}
|
||||
|
||||
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
|
||||
// the full GC, but we do want it to happen eventually.
|
||||
if (comp) {
|
||||
nsJSContext::PokeGC();
|
||||
nsJSContext::PokeGC(js::gcreason::POST_COMPARTMENT);
|
||||
|
||||
// We poked the GC, so we can kill any pending CC here.
|
||||
nsJSContext::KillCCTimer();
|
||||
|
||||
@@ -41,10 +41,12 @@
|
||||
#include "nsIScriptRuntime.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIXPCScriptNotify.h"
|
||||
#include "prtime.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
class nsIXPConnectJSObjectHolder;
|
||||
class nsRootedJSValueArray;
|
||||
@@ -179,11 +181,11 @@ public:
|
||||
static void LoadStart();
|
||||
static void LoadEnd();
|
||||
|
||||
static void GarbageCollectNow(bool shrinkingGC = false);
|
||||
static void GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind = nsGCNormal);
|
||||
static void ShrinkGCBuffersNow();
|
||||
static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull);
|
||||
|
||||
static void PokeGC();
|
||||
static void PokeGC(js::gcreason::Reason aReason);
|
||||
static void KillGCTimer();
|
||||
|
||||
static void PokeShrinkGCBuffers();
|
||||
@@ -193,7 +195,7 @@ public:
|
||||
static void MaybePokeCC();
|
||||
static void KillCCTimer();
|
||||
|
||||
virtual void GC();
|
||||
virtual void GC(js::gcreason::Reason aReason);
|
||||
|
||||
protected:
|
||||
nsresult InitializeExternalClasses();
|
||||
|
||||
@@ -66,7 +66,7 @@ interface nsIDOMLocation;
|
||||
* 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
|
||||
{
|
||||
readonly attribute nsIDOMDocumentType doctype;
|
||||
@@ -118,16 +118,14 @@ interface nsIDOMDocument : nsIDOMNode
|
||||
*/
|
||||
nsIDOMRange createRange();
|
||||
|
||||
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);
|
||||
[optional_argc] nsIDOMNodeIterator createNodeIterator(in nsIDOMNode root,
|
||||
[optional] in unsigned long whatToShow,
|
||||
[optional] in nsIDOMNodeFilter filter)
|
||||
raises(DOMException);
|
||||
[optional_argc] nsIDOMTreeWalker createTreeWalker(in nsIDOMNode root,
|
||||
[optional] in unsigned long whatToShow,
|
||||
[optional] in nsIDOMNodeFilter filter)
|
||||
raises(DOMException);
|
||||
|
||||
nsIDOMEvent createEvent(in DOMString eventType)
|
||||
raises(DOMException);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
@@ -44,7 +44,7 @@ interface nsIDOMNodeFilter;
|
||||
|
||||
|
||||
[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
|
||||
{
|
||||
readonly attribute nsIDOMNode root;
|
||||
|
||||
@@ -800,14 +800,14 @@ ContentChild::GetIndexedDBPath()
|
||||
bool
|
||||
ContentChild::RecvGarbageCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvCycleCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
||||
nsJSContext::CycleCollectNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -634,8 +634,6 @@ nsJSONListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
|
||||
nsIInputStream *aStream,
|
||||
PRUint32 aOffset, PRUint32 aLength)
|
||||
{
|
||||
PRUint32 contentLength;
|
||||
aStream->Available(&contentLength);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mNeedsConverter && mSniffBuffer.Length() < 4) {
|
||||
|
||||
@@ -3794,10 +3794,10 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
if (aShrinking) {
|
||||
JS_ShrinkingGC(aCx);
|
||||
js::ShrinkingGC(aCx, js::gcreason::DOM_WORKER);
|
||||
}
|
||||
else {
|
||||
JS_GC(aCx);
|
||||
js::GCForReason(aCx, js::gcreason::DOM_WORKER);
|
||||
}
|
||||
|
||||
if (aCollectChildren) {
|
||||
|
||||
@@ -486,7 +486,7 @@ GetTextNode(nsISelection *selection, nsEditor *editor) {
|
||||
// if node is null, return it to indicate there's no text
|
||||
NS_ENSURE_TRUE(node, nsnull);
|
||||
// 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)) {
|
||||
if (NS_FAILED(res = iter.NextNode(getter_AddRefs(selNode))) || !selNode) {
|
||||
return nsnull;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscrashformat.h"
|
||||
@@ -52,6 +53,22 @@
|
||||
namespace js {
|
||||
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)
|
||||
: title(title)
|
||||
{
|
||||
@@ -117,8 +134,8 @@ Statistics::makeTable(ColumnInfo *cols)
|
||||
}
|
||||
|
||||
Statistics::Statistics(JSRuntime *rt)
|
||||
: runtime(rt)
|
||||
, triggerReason(PUBLIC_API) //dummy reason to satisfy makeTable
|
||||
: runtime(rt),
|
||||
triggerReason(gcreason::NO_REASON)
|
||||
{
|
||||
PodArrayZero(counts);
|
||||
PodArrayZero(totals);
|
||||
@@ -178,7 +195,7 @@ struct GCCrashData
|
||||
};
|
||||
|
||||
void
|
||||
Statistics::beginGC(JSCompartment *comp, Reason reason)
|
||||
Statistics::beginGC(JSCompartment *comp, gcreason::Reason reason)
|
||||
{
|
||||
compartment = comp;
|
||||
|
||||
@@ -276,7 +293,6 @@ Statistics::endGC()
|
||||
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
|
||||
(*cb)(JS_TELEMETRY_GC_REASON, triggerReason);
|
||||
(*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_MARK_MS, t(PHASE_MARK));
|
||||
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(PHASE_SWEEP));
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
@@ -50,32 +51,6 @@ struct JSCompartment;
|
||||
namespace js {
|
||||
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 {
|
||||
PHASE_GC,
|
||||
PHASE_MARK,
|
||||
@@ -103,7 +78,7 @@ struct Statistics {
|
||||
Statistics(JSRuntime *rt);
|
||||
~Statistics();
|
||||
|
||||
void beginGC(JSCompartment *comp, Reason reason);
|
||||
void beginGC(JSCompartment *comp, gcreason::Reason reason);
|
||||
void endGC();
|
||||
|
||||
void beginPhase(Phase phase);
|
||||
@@ -122,7 +97,7 @@ struct Statistics {
|
||||
FILE *fp;
|
||||
bool fullFormat;
|
||||
|
||||
Reason triggerReason;
|
||||
gcreason::Reason triggerReason;
|
||||
JSCompartment *compartment;
|
||||
|
||||
uint64_t phaseStarts[PHASE_LIMIT];
|
||||
@@ -140,8 +115,8 @@ struct Statistics {
|
||||
|
||||
struct ColumnInfo {
|
||||
const char *title;
|
||||
char str[12];
|
||||
char totalStr[12];
|
||||
char str[32];
|
||||
char totalStr[32];
|
||||
int width;
|
||||
|
||||
ColumnInfo() {}
|
||||
@@ -155,7 +130,8 @@ struct Statistics {
|
||||
};
|
||||
|
||||
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); }
|
||||
~AutoGC() { stats.endGC(); }
|
||||
|
||||
|
||||
21
js/src/jit-test/tests/jaeger/in.js
Normal file
21
js/src/jit-test/tests/jaeger/in.js
Normal 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);
|
||||
}
|
||||
@@ -735,6 +735,7 @@ JSRuntime::JSRuntime()
|
||||
gcIsNeeded(0),
|
||||
gcWeakMapList(NULL),
|
||||
gcStats(thisFromCtor()),
|
||||
gcTriggerReason(gcreason::NO_REASON),
|
||||
gcTriggerCompartment(NULL),
|
||||
gcCurrentCompartment(NULL),
|
||||
gcCheckCompartment(NULL),
|
||||
@@ -2857,7 +2858,7 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp)
|
||||
JS_ASSERT(comp != cx->runtime->atomsCompartment);
|
||||
|
||||
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)
|
||||
|
||||
@@ -323,13 +323,13 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
|
||||
#endif
|
||||
|
||||
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. */
|
||||
JS_LOCK_GC(rt);
|
||||
} else {
|
||||
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)
|
||||
JS_MaybeGC(cx);
|
||||
|
||||
@@ -1179,7 +1179,7 @@ JSContext::runningWithTrustedPrincipals() const
|
||||
JS_FRIEND_API(void)
|
||||
JSRuntime::onTooMuchMalloc()
|
||||
{
|
||||
TriggerGC(this, gcstats::TOOMUCHMALLOC);
|
||||
TriggerGC(this, gcreason::TOO_MUCH_MALLOC);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void *)
|
||||
|
||||
@@ -318,7 +318,7 @@ struct JSRuntime
|
||||
js::gcstats::Statistics gcStats;
|
||||
|
||||
/* 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. */
|
||||
uintptr_t gcMarkStackArray[js::MARK_STACK_LENGTH];
|
||||
|
||||
@@ -128,9 +128,15 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -72,9 +72,6 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObj
|
||||
extern JS_FRIEND_API(uint32_t)
|
||||
JS_ObjectCountDynamicSlots(JSObject *obj);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
JS_ShrinkingGC(JSContext *cx);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
JS_ShrinkGCBuffers(JSRuntime *rt);
|
||||
|
||||
@@ -101,7 +98,6 @@ JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape);
|
||||
enum {
|
||||
JS_TELEMETRY_GC_REASON,
|
||||
JS_TELEMETRY_GC_IS_COMPARTMENTAL,
|
||||
JS_TELEMETRY_GC_IS_SHAPE_REGEN,
|
||||
JS_TELEMETRY_GC_MS,
|
||||
JS_TELEMETRY_GC_MARK_MS,
|
||||
JS_TELEMETRY_GC_SWEEP_MS
|
||||
@@ -572,6 +568,56 @@ GetRuntimeCompartments(JSRuntime *rt);
|
||||
extern JS_FRIEND_API(size_t)
|
||||
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)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt);
|
||||
|
||||
|
||||
@@ -742,7 +742,7 @@ Chunk::allocateArena(JSCompartment *comp, AllocKind thingKind)
|
||||
rt->gcBytes += ArenaSize;
|
||||
comp->gcBytes += ArenaSize;
|
||||
if (comp->gcBytes >= comp->gcTriggerBytes)
|
||||
TriggerCompartmentGC(comp, gcstats::ALLOCTRIGGER);
|
||||
TriggerCompartmentGC(comp, gcreason::ALLOC_TRIGGER);
|
||||
|
||||
return aheader;
|
||||
}
|
||||
@@ -1647,7 +1647,7 @@ RunLastDitchGC(JSContext *cx)
|
||||
|
||||
/* The last ditch GC preserves all atoms. */
|
||||
AutoKeepAtoms keep(rt);
|
||||
js_GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcstats::LASTDITCH);
|
||||
js_GC(cx, rt->gcTriggerCompartment, GC_NORMAL, gcreason::LAST_DITCH);
|
||||
}
|
||||
|
||||
/* static */ void *
|
||||
@@ -2137,7 +2137,7 @@ MarkRuntime(JSTracer *trc)
|
||||
}
|
||||
|
||||
void
|
||||
TriggerGC(JSRuntime *rt, gcstats::Reason reason)
|
||||
TriggerGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
JS_ASSERT(rt->onOwnerThread());
|
||||
|
||||
@@ -2152,7 +2152,7 @@ TriggerGC(JSRuntime *rt, gcstats::Reason reason)
|
||||
}
|
||||
|
||||
void
|
||||
TriggerCompartmentGC(JSCompartment *comp, gcstats::Reason reason)
|
||||
TriggerCompartmentGC(JSCompartment *comp, gcreason::Reason reason)
|
||||
{
|
||||
JSRuntime *rt = comp->rt;
|
||||
JS_ASSERT(!rt->gcRunning);
|
||||
@@ -2198,18 +2198,18 @@ MaybeGC(JSContext *cx)
|
||||
JS_ASSERT(rt->onOwnerThread());
|
||||
|
||||
if (rt->gcZeal()) {
|
||||
js_GC(cx, NULL, GC_NORMAL, gcstats::MAYBEGC);
|
||||
js_GC(cx, NULL, GC_NORMAL, gcreason::MAYBEGC);
|
||||
return;
|
||||
}
|
||||
|
||||
JSCompartment *comp = cx->compartment;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2223,7 +2223,7 @@ MaybeGC(JSContext *cx)
|
||||
if (rt->gcChunkAllocationSinceLastGC ||
|
||||
rt->gcNumArenasFreeCommitted > FreeCommittedArenasThreshold)
|
||||
{
|
||||
js_GC(cx, NULL, GC_SHRINK, gcstats::MAYBEGC);
|
||||
js_GC(cx, NULL, GC_SHRINK, gcreason::MAYBEGC);
|
||||
} else {
|
||||
rt->gcNextFullGCTime = now + GC_IDLE_FULL_SPAN;
|
||||
}
|
||||
@@ -2966,7 +2966,7 @@ GCCycle(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind)
|
||||
}
|
||||
|
||||
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;
|
||||
JS_AbortIfWrongThread(rt);
|
||||
|
||||
@@ -1382,11 +1382,11 @@ MarkContext(JSTracer *trc, JSContext *acx);
|
||||
|
||||
/* Must be called with GC lock taken. */
|
||||
extern void
|
||||
TriggerGC(JSRuntime *rt, js::gcstats::Reason reason);
|
||||
TriggerGC(JSRuntime *rt, js::gcreason::Reason reason);
|
||||
|
||||
/* Must be called with GC lock taken. */
|
||||
extern void
|
||||
TriggerCompartmentGC(JSCompartment *comp, js::gcstats::Reason reason);
|
||||
TriggerCompartmentGC(JSCompartment *comp, js::gcreason::Reason reason);
|
||||
|
||||
extern void
|
||||
MaybeGC(JSContext *cx);
|
||||
@@ -1409,7 +1409,7 @@ typedef enum JSGCInvocationKind {
|
||||
|
||||
/* Pass NULL for |comp| to get a full GC. */
|
||||
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 {
|
||||
|
||||
|
||||
@@ -791,6 +791,20 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
|
||||
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.
|
||||
FastArrayLoadFails fastArrayLoad(RegisterID objReg, const Int32Key &key,
|
||||
RegisterID typeReg, RegisterID dataReg) {
|
||||
|
||||
@@ -2966,11 +2966,7 @@ mjit::Compiler::generateMethod()
|
||||
|
||||
BEGIN_CASE(JSOP_IN)
|
||||
{
|
||||
prepareStubCall(Uses(2));
|
||||
INLINE_STUBCALL(stubs::In, REJOIN_PUSH_BOOLEAN);
|
||||
frame.popn(2);
|
||||
frame.takeReg(Registers::ReturnReg);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_BOOLEAN, Registers::ReturnReg);
|
||||
jsop_in();
|
||||
}
|
||||
END_CASE(JSOP_IN)
|
||||
|
||||
@@ -7448,6 +7444,76 @@ mjit::Compiler::jsop_toid()
|
||||
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
|
||||
* doubles by the type inference, convert to double. These will be assumed to be
|
||||
|
||||
@@ -753,6 +753,7 @@ private:
|
||||
CompileStatus jsop_equality_obj_obj(JSOp op, jsbytecode *target, JSOp fused);
|
||||
bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
|
||||
void jsop_pos();
|
||||
void jsop_in();
|
||||
|
||||
static inline Assembler::Condition
|
||||
GetCompareCondition(JSOp op, JSOp fused)
|
||||
|
||||
@@ -390,9 +390,15 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
||||
#define NS_XPCONNECT_CID \
|
||||
{ 0xcb6593e0, 0xf9b2, 0x11d2, \
|
||||
{ 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
|
||||
{
|
||||
%{ C++
|
||||
@@ -723,8 +729,10 @@ interface nsIXPConnect : nsISupports
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -3600,7 +3600,7 @@ nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx,
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::ForceGC(JSContext *cx)
|
||||
{
|
||||
JS_GC(cx);
|
||||
js::GCForReason(cx, js::gcreason::COMPONENT_UTILS);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3608,7 +3608,7 @@ nsXPCComponents_Utils::ForceGC(JSContext *cx)
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx)
|
||||
{
|
||||
JS_ShrinkingGC(cx);
|
||||
js::ShrinkingGC(cx, js::gcreason::COMPONENT_UTILS);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3636,9 +3636,9 @@ class PreciseGCRunnable : public nsRunnable
|
||||
}
|
||||
|
||||
if (mShrinking)
|
||||
JS_ShrinkingGC(mCx);
|
||||
js::ShrinkingGC(mCx, js::gcreason::COMPONENT_UTILS);
|
||||
else
|
||||
JS_GC(mCx);
|
||||
js::GCForReason(mCx, js::gcreason::COMPONENT_UTILS);
|
||||
|
||||
mCallback->Callback();
|
||||
return NS_OK;
|
||||
|
||||
@@ -1870,9 +1870,6 @@ AccumulateTelemetryCallback(int id, uint32_t sample)
|
||||
case JS_TELEMETRY_GC_IS_COMPARTMENTAL:
|
||||
Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample);
|
||||
break;
|
||||
case JS_TELEMETRY_GC_IS_SHAPE_REGEN:
|
||||
Telemetry::Accumulate(Telemetry::GC_IS_SHAPE_REGEN, sample);
|
||||
break;
|
||||
case JS_TELEMETRY_GC_MS:
|
||||
Telemetry::Accumulate(Telemetry::GC_MS, sample);
|
||||
break;
|
||||
|
||||
@@ -365,7 +365,7 @@ nsXPConnect::NeedCollect()
|
||||
}
|
||||
|
||||
void
|
||||
nsXPConnect::Collect(bool shrinkingGC)
|
||||
nsXPConnect::Collect(PRUint32 reason, PRUint32 kind)
|
||||
{
|
||||
// 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
|
||||
// has started the request on this thread.
|
||||
js::AutoSkipConservativeScan ascs(cx);
|
||||
if (shrinkingGC)
|
||||
JS_ShrinkingGC(cx);
|
||||
else
|
||||
JS_GC(cx);
|
||||
MOZ_ASSERT(reason < js::gcreason::NUM_REASONS);
|
||||
js::gcreason::Reason gcreason = (js::gcreason::Reason)reason;
|
||||
if (kind == nsGCShrinking) {
|
||||
js::ShrinkingGC(cx, gcreason);
|
||||
} else {
|
||||
MOZ_ASSERT(kind == nsGCNormal);
|
||||
js::GCForReason(cx, gcreason);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GarbageCollect(bool shrinkingGC)
|
||||
nsXPConnect::GarbageCollect(PRUint32 reason, PRUint32 kind)
|
||||
{
|
||||
Collect(shrinkingGC);
|
||||
Collect(reason, kind);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -549,7 +549,7 @@ public:
|
||||
virtual nsresult FinishCycleCollection();
|
||||
virtual nsCycleCollectionParticipant *ToParticipant(void *p);
|
||||
virtual bool NeedCollect();
|
||||
virtual void Collect(bool shrinkingGC=false);
|
||||
virtual void Collect(PRUint32 reason, PRUint32 kind);
|
||||
#ifdef DEBUG_CC
|
||||
virtual void PrintAllReferencesTo(void *p);
|
||||
#endif
|
||||
|
||||
@@ -198,6 +198,8 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
@@ -1287,7 +1289,7 @@ DocumentViewerImpl::PageHide(bool aIsUnload)
|
||||
|
||||
if (aIsUnload) {
|
||||
// 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.
|
||||
NS_ENSURE_STATE(mDocument);
|
||||
|
||||
@@ -310,7 +310,7 @@ nsContentDLF::CreateInstance(const char* aCommand,
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if(pluginHost &&
|
||||
NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType))) {
|
||||
NS_SUCCEEDED(pluginHost->IsPluginEnabledForType(aContentType, true))) {
|
||||
return CreateDocument(aCommand,
|
||||
aChannel, aLoadGroup,
|
||||
aContainer, kPluginDocumentCID,
|
||||
|
||||
@@ -405,6 +405,11 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
|
||||
ExpandableListView exList = (ExpandableListView)list;
|
||||
int childPosition = ExpandableListView.getPackedPositionChild(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);
|
||||
|
||||
Map map = (Map)selectedItem;
|
||||
|
||||
@@ -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_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_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_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
|
||||
@@ -143,7 +146,6 @@ FENNEC_PP_JAVA_FILES = \
|
||||
db/BrowserContract.java \
|
||||
db/BrowserProvider.java \
|
||||
SmsManager.java \
|
||||
SyncPreference.java \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -539,6 +541,9 @@ RES_DIRS= \
|
||||
res/xml \
|
||||
res/anim \
|
||||
res/drawable-nodpi \
|
||||
res/drawable-ldpi \
|
||||
res/drawable-mdpi \
|
||||
res/drawable-hdpi \
|
||||
res/drawable-mdpi-v8 \
|
||||
res/drawable-hdpi-v8 \
|
||||
res/drawable-mdpi-v9 \
|
||||
@@ -576,7 +581,10 @@ $(PP_RES_XML): $(subst res/,$(srcdir)/resources/, $(PP_RES_XML).in)
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
$(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
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
|
||||
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
|
||||
@@ -594,6 +602,21 @@ $(RES_DRAWABLE): $(addprefix $(topsrcdir)/,$(MOZ_ANDROID_DRAWABLES))
|
||||
$(NSINSTALL) -D 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
|
||||
$(NSINSTALL) -D res/values
|
||||
$(NSINSTALL) $^ res/values
|
||||
@@ -607,10 +630,10 @@ $(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
|
||||
$(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
|
||||
|
||||
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 $@
|
||||
|
||||
libs:: classes.dex package-name.txt
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -182,6 +182,7 @@ public class BrowserProvider extends ContentProvider {
|
||||
|
||||
// Images
|
||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "images", IMAGES);
|
||||
URI_MATCHER.addURI(BrowserContract.AUTHORITY, "images/#", IMAGES_ID);
|
||||
|
||||
map = IMAGES_PROJECTION_MAP;
|
||||
map.put(Images._ID, Images._ID);
|
||||
|
||||
@@ -69,7 +69,6 @@
|
||||
<!ENTITY pref_font_size_large "Large">
|
||||
<!ENTITY pref_font_size_xlarge "Extra Large">
|
||||
<!ENTITY pref_use_master_password "Use master password">
|
||||
<!ENTITY pref_sync "Sync">
|
||||
|
||||
<!ENTITY quit "Quit">
|
||||
|
||||
|
||||
@@ -6,13 +6,18 @@
|
||||
<!-- Main titles. -->
|
||||
<!ENTITY sync.app.name.label '&syncBrand.fullName.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'>
|
||||
|
||||
<!-- 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.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.pin.default.label '...\n...\n...\n'>
|
||||
<!ENTITY sync.pin.oneline.label '...'>
|
||||
<!ENTITY sync.link.show.label 'Show me how.'>
|
||||
<!ENTITY sync.link.advancedsetup.label 'Advanced setup...'>
|
||||
<!ENTITY sync.link.nodevice.label 'I don\'t have the device with me…'>
|
||||
|
||||
<!-- J-PAKE Waiting Screen -->
|
||||
|
||||
10
mobile/android/base/resources/drawable/pin_background.xml
Normal file
10
mobile/android/base/resources/drawable/pin_background.xml
Normal 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>
|
||||
@@ -1,23 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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
|
||||
style="@style/SyncLayout" >
|
||||
|
||||
android:id="@+id/account_content"
|
||||
style="@style/SyncLayout"
|
||||
android:layout_below="@id/account_top"
|
||||
android:layout_above="@+id/account_bottom">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SyncLayout" >
|
||||
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_connect" />
|
||||
|
||||
<View
|
||||
style="@style/SyncViewLine" />
|
||||
|
||||
style="@style/SyncLayout.Vertical"
|
||||
android:padding="20dp" >
|
||||
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:text="@string/sync_subtitle_account" />
|
||||
android:text="@string/sync_subtitle_account"
|
||||
android:layout_marginBottom="10dp" />
|
||||
|
||||
<EditText android:id="@+id/usernameInput"
|
||||
style="@style/SyncEditItem"
|
||||
@@ -43,26 +51,26 @@
|
||||
style="@style/SyncEditItem"
|
||||
android:visibility="gone"
|
||||
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>
|
||||
</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>
|
||||
@@ -1,65 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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
|
||||
style="@style/SyncLayout" >
|
||||
style="@style/SyncLayout"
|
||||
android:fillViewport="true"
|
||||
android:layout_below="@id/setup_top"
|
||||
android:layout_above="@+id/setup_bottom" >
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SyncLayout" >
|
||||
<RelativeLayout
|
||||
style="@style/SyncLayout.Vertical"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="15dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setup_title"
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_connect" />
|
||||
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="2dp"
|
||||
android:background="#FFFFFF" />
|
||||
android:id="@+id/setup_header"
|
||||
style="@style/SyncTextItem"
|
||||
android:gravity="left"
|
||||
android:layout_marginTop="15dp"
|
||||
android:text="@string/sync_subtitle_header"
|
||||
android:textStyle="bold" />
|
||||
<TextView
|
||||
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
|
||||
android:id="@+id/setup_subtitle"
|
||||
style="@style/SyncTextItem"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/sync_subtitle_pair" />
|
||||
|
||||
<TextView
|
||||
style="@style/SyncLinkItem"
|
||||
android:onClick="showClickHandler"
|
||||
android:text="@string/sync_link_show" />
|
||||
android:id="@+id/setup_showme"
|
||||
style="@style/SyncLinkItem"
|
||||
android:layout_below="@id/setup_subtitle"
|
||||
android:layout_marginTop="2dp"
|
||||
android:onClick="showClickHandler"
|
||||
android:text="@string/sync_link_show" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SyncTextItem"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_pin"
|
||||
style="@style/SyncTextItem"
|
||||
android:text="@string/sync_pin_default"
|
||||
android:textSize="40dp" />
|
||||
style="@style/SyncLayout"
|
||||
android:layout_below="@id/setup_showme"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingLeft="-15dp"
|
||||
android:orientation="vertical" >
|
||||
<TextView
|
||||
android:id="@+id/text_pin1"
|
||||
style="@style/SyncPinText" />
|
||||
<TextView
|
||||
android:id="@+id/text_pin2"
|
||||
style="@style/SyncPinText" />
|
||||
<TextView
|
||||
android:id="@+id/text_pin3"
|
||||
style="@style/SyncPinText" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/link_nodevice"
|
||||
style="@style/SyncLinkItem"
|
||||
android:onClick="manualClickHandler"
|
||||
android:text="@string/sync_link_nodevice" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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>
|
||||
android:id="@+id/link_nodevice"
|
||||
style="@style/SyncLinkItem"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="5dp"
|
||||
android:onClick="manualClickHandler"
|
||||
android:text="@string/sync_link_advancedsetup" />
|
||||
</RelativeLayout>
|
||||
</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>
|
||||
@@ -1,41 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_fail" />
|
||||
<View
|
||||
style="@style/SyncViewLine" />
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncLayout" >
|
||||
<LinearLayout
|
||||
android:id="@+id/failure_top"
|
||||
style="@style/SyncTop" >
|
||||
<ImageView
|
||||
style="@style/SyncTopIcon" />
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_fail" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:text="@string/sync_subtitle_fail" />
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
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
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:onClick="tryAgainClickHandler"
|
||||
android:text="@string/sync_button_tryagain" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<Button
|
||||
style="@style/SyncButtonCommon"
|
||||
android:onClick="tryAgainClickHandler"
|
||||
android:text="@string/sync_button_tryagain" />
|
||||
|
||||
<Button
|
||||
style="@style/SyncButtonCommon"
|
||||
android:onClick="manualClickHandler"
|
||||
android:text="@string/sync_button_manual" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
style="@style/SyncButtonCommon"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_cancel" />
|
||||
</LinearLayout>
|
||||
|
||||
</TableLayout>
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:onClick="manualClickHandler"
|
||||
android:text="@string/sync_button_manual" />
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_cancel" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_connect" />
|
||||
<View
|
||||
style="@style/SyncViewLine" />
|
||||
<ProgressBar
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateOnly="true"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp" />
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:text="@string/sync_jpake_subtitle_waiting" />
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncLayout" >
|
||||
<LinearLayout
|
||||
android:id="@+id/waiting_top"
|
||||
style="@style/SyncTop" >
|
||||
<ImageView
|
||||
style="@style/SyncTopIcon" />
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_connect" />
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/waiting_content1"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
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
|
||||
style="@style/SyncButtonCommon"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_cancel" />
|
||||
</TableLayout>
|
||||
style="@style/SyncButton"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_cancel" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncLayout" >
|
||||
<LinearLayout
|
||||
android:id="@+id/internet_top"
|
||||
style="@style/SyncTop">
|
||||
<ImageView
|
||||
style="@style/SyncTopIcon" />
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_fail" />
|
||||
<View
|
||||
style="@style/SyncViewLine"/>
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:text="@string/sync_subtitle_nointernet" />
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_fail" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:layout_below="@id/internet_top"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/sync_subtitle_nointernet" />
|
||||
<LinearLayout
|
||||
style="@style/SyncBottom" >
|
||||
<Button
|
||||
style="@style/SyncButtonCommon"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_ok" />
|
||||
</TableLayout>
|
||||
style="@style/SyncButton"
|
||||
android:onClick="cancelClickHandler"
|
||||
android:text="@string/sync_button_ok" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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
|
||||
style="@style/SyncLayout" >
|
||||
style="@style/SyncLayout"
|
||||
android:layout_below="@id/pair_top"
|
||||
android:layout_above="@+id/pair_bottom" >
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SyncLayout" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setup_title"
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_pair" />
|
||||
|
||||
<View
|
||||
style="@style/SyncViewLine" />
|
||||
style="@style/SyncLayout.Vertical"
|
||||
android:gravity="center"
|
||||
android:padding="10dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setup_subtitle"
|
||||
style="@style/SyncTextItem"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/sync_subtitle_connect" />
|
||||
|
||||
<TextView
|
||||
style="@style/SyncLinkItem"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:onClick="showClickHandler"
|
||||
android:text="@string/sync_link_show" />
|
||||
|
||||
@@ -32,16 +40,16 @@
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/pair_row1"
|
||||
style="@style/SyncEditPin" />
|
||||
<EditText
|
||||
android:id="@+id/pair_row2"
|
||||
style="@style/SyncEditPin" />
|
||||
<EditText
|
||||
android:id="@+id/pair_row3"
|
||||
style="@style/SyncEditPin"
|
||||
android:imeOptions="actionDone" />
|
||||
<EditText
|
||||
android:id="@+id/pair_row1"
|
||||
style="@style/SyncEditPin" />
|
||||
<EditText
|
||||
android:id="@+id/pair_row2"
|
||||
style="@style/SyncEditPin" />
|
||||
<EditText
|
||||
android:id="@+id/pair_row3"
|
||||
style="@style/SyncEditPin"
|
||||
android:imeOptions="actionDone" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@@ -54,31 +62,28 @@
|
||||
|
||||
<TextView
|
||||
style="@style/SyncTextItem"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_margin="10dp"
|
||||
android:text="@string/sync_pair_tryagain"
|
||||
android:textSize="10dp" />
|
||||
</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>
|
||||
</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>
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncTextFrame" >
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/SyncLayout" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/success_top"
|
||||
style="@style/SyncTop" >
|
||||
<ImageView
|
||||
style="@style/SyncTopIcon"/>
|
||||
<TextView
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_success" />
|
||||
|
||||
<View style="@style/SyncViewLine" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setup_success_subtitle"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:text="@string/sync_subtitle_success" />
|
||||
style="@style/SyncTextTitle"
|
||||
android:text="@string/sync_title_success" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/setup_success_subtitle"
|
||||
style="@style/SyncTextItem"
|
||||
android:gravity="left"
|
||||
android:padding="20dp"
|
||||
android:layout_below="@id/success_top"
|
||||
android:text="@string/sync_subtitle_success" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/SyncBottom" >
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:onClick="settingsClickHandler"
|
||||
android:text="@string/sync_settings" />
|
||||
|
||||
<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>
|
||||
style="@style/SyncButton"
|
||||
android:onClick="settingsClickHandler"
|
||||
android:text="@string/sync_settings" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
@@ -1,34 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="SyncLayout" parent="@android:style/Widget">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<style name="SyncLayout">
|
||||
<item name="android:layout_width">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>
|
||||
</style>
|
||||
<style name="SyncLayout.Horizontal" parent="@style/SyncLayout">
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<!-- TextView Styles -->
|
||||
<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_gravity">center</item>
|
||||
<item name="android:padding">20dp</item>
|
||||
<item name="android:orientation">vertical</item>
|
||||
<item name="android:background">#82818A</item>
|
||||
</style>
|
||||
<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_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:textSize">15dp</item>
|
||||
</style>
|
||||
<style name="SyncLinkItem" parent="SyncTextItem">
|
||||
<item name="android:clickable">true</item>
|
||||
<item name="android:textColor">#99CCFF</item>
|
||||
<item name="android:textColor">#ACC4D5</item>
|
||||
</style>
|
||||
<style name="SyncTextTitle" parent="@style/SyncTextItem">
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:paddingBottom">10dp</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:paddingLeft">4dp</item>
|
||||
<item name="android:gravity">left</item>
|
||||
<item name="android:textSize">20dp</item>
|
||||
</style>
|
||||
<!-- EditView Styles -->
|
||||
@@ -44,16 +47,48 @@
|
||||
<item name="android:maxLength">4</item>
|
||||
<item name="android:imeOptions">actionNext</item>
|
||||
</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_height">wrap_content</item>
|
||||
</style>
|
||||
<style name="SyncViewLine">
|
||||
<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>
|
||||
<item name="android:paddingTop">2dp</item>
|
||||
<item name="android:paddingLeft">4dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
<org.mozilla.gecko.LinkPreference android:title="@string/pref_about_firefox"
|
||||
url="about:" />
|
||||
|
||||
<org.mozilla.gecko.SyncPreference android:title="@string/pref_sync"
|
||||
android:persistent="false" />
|
||||
<!-- TODO: Default Search Engine -->
|
||||
|
||||
<!-- TODO: Sync -->
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
<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_xlarge">&pref_font_size_xlarge;</string>
|
||||
<string name="pref_sync">&pref_sync;</string>
|
||||
|
||||
<string name="reload">&reload;</string>
|
||||
<string name="forward">&forward;</string>
|
||||
|
||||
@@ -63,9 +63,9 @@ public class SyncConfiguration implements CredentialsSource {
|
||||
this.editor = config.getEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
this.editor.apply();
|
||||
// Android <=r8 SharedPreferences.Editor does not contain apply() for overriding.
|
||||
this.editor.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,7 +41,6 @@ package org.mozilla.gecko.sync;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -128,8 +127,10 @@ public class Utils {
|
||||
totalLength += array.length;
|
||||
}
|
||||
|
||||
byte[] result = Arrays.copyOf(first, totalLength);
|
||||
byte[] result = new byte[totalLength];
|
||||
int offset = first.length;
|
||||
|
||||
System.arraycopy(first, 0, result, 0, offset);
|
||||
|
||||
for (byte[] array : rest) {
|
||||
System.arraycopy(array, 0, result, offset, array.length);
|
||||
|
||||
@@ -40,7 +40,6 @@ package org.mozilla.gecko.sync.crypto;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
@@ -98,7 +97,9 @@ public class HKDF {
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
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.
|
||||
*/
|
||||
public static final BigInteger P = new BigInteger(
|
||||
"90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C"
|
||||
+ "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F"
|
||||
+ "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1"
|
||||
+ "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B"
|
||||
+ "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394"
|
||||
+ "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0"
|
||||
+ "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E"
|
||||
+ "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D"
|
||||
+ "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F"
|
||||
+ "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D"
|
||||
+ "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E"
|
||||
+ "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73",
|
||||
16);
|
||||
public static final BigInteger P = new BigInteger(
|
||||
"90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" +
|
||||
"7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" +
|
||||
"009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" +
|
||||
"29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" +
|
||||
"6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" +
|
||||
"87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" +
|
||||
"E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" +
|
||||
"BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" +
|
||||
"AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" +
|
||||
"B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" +
|
||||
"597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" +
|
||||
"C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73",
|
||||
16);
|
||||
|
||||
public static final BigInteger Q = new BigInteger(
|
||||
"CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D",
|
||||
16);
|
||||
public static final BigInteger Q = new BigInteger(
|
||||
"CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D",
|
||||
16);
|
||||
|
||||
public static final BigInteger G = new BigInteger(
|
||||
"5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37"
|
||||
+ "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB"
|
||||
+ "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1"
|
||||
+ "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8"
|
||||
+ "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17"
|
||||
+ "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C"
|
||||
+ "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3"
|
||||
+ "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B"
|
||||
+ "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8"
|
||||
+ "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828"
|
||||
+ "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33"
|
||||
+ "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B",
|
||||
16);
|
||||
public static final BigInteger G = new BigInteger(
|
||||
"5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" +
|
||||
"F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" +
|
||||
"805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" +
|
||||
"F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" +
|
||||
"A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" +
|
||||
"A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" +
|
||||
"4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" +
|
||||
"9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" +
|
||||
"9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" +
|
||||
"E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" +
|
||||
"E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" +
|
||||
"787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B",
|
||||
16);
|
||||
|
||||
/**
|
||||
*
|
||||
* Round 1 of JPAKE protocol.
|
||||
* Round 1 of J-PAKE protocol.
|
||||
* Generate x1, x2, and ZKP for other party.
|
||||
*
|
||||
* @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.
|
||||
* 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,
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -159,11 +160,11 @@ public class JPakeCrypto {
|
||||
jp.thisZkpA = createZkp(y1, y2, a, jp.signerId, gen);
|
||||
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 zkp
|
||||
@@ -174,7 +175,7 @@ public class JPakeCrypto {
|
||||
*/
|
||||
public static KeyBundle finalRound(String secret, JPakeParty jp)
|
||||
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)
|
||||
.mod(P);
|
||||
checkZkp(gb, jp.otherA, jp.otherZkpA);
|
||||
@@ -188,7 +189,7 @@ public class JPakeCrypto {
|
||||
byte[] hmac = new byte[32];
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -198,8 +199,7 @@ public class JPakeCrypto {
|
||||
try {
|
||||
Mac hmacSha256;
|
||||
hmacSha256 = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secret_key = new SecretKeySpec(key,
|
||||
"HmacSHA256");
|
||||
SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
|
||||
hmacSha256.init(secret_key);
|
||||
result = hmacSha256.doFinal(data);
|
||||
} catch (GeneralSecurityException e) {
|
||||
@@ -243,14 +243,18 @@ public class JPakeCrypto {
|
||||
// Check parameters of zkp, and compare to computed hash. These shouldn't
|
||||
// fail.
|
||||
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();
|
||||
} 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();
|
||||
} else if (gx.modPow(Q, P).compareTo(BigInteger.ONE) != 0) {
|
||||
Log.e(LOG_TAG, "g^x^q % p = 1 fails");
|
||||
} else if (zkp.gr.compareTo(g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P)) != 0) {
|
||||
}
|
||||
if (gx.modPow(Q, P).compareTo(BigInteger.ONE) != 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)
|
||||
Log.i(LOG_TAG, "gb*g(xh) = "
|
||||
+ 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, "gx = " + gx.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();
|
||||
} else {
|
||||
Log.d(LOG_TAG, "*** ZKP SUCCESS ***");
|
||||
}
|
||||
Log.d(LOG_TAG, "*** ZKP SUCCESS ***");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.util.Log;
|
||||
import ch.boye.httpclientandroidlib.Header;
|
||||
import ch.boye.httpclientandroidlib.HttpEntity;
|
||||
import ch.boye.httpclientandroidlib.HttpResponse;
|
||||
import ch.boye.httpclientandroidlib.HttpVersion;
|
||||
import ch.boye.httpclientandroidlib.auth.Credentials;
|
||||
import ch.boye.httpclientandroidlib.auth.UsernamePasswordCredentials;
|
||||
import ch.boye.httpclientandroidlib.client.ClientProtocolException;
|
||||
@@ -157,6 +158,7 @@ public class BaseResource implements Resource {
|
||||
HttpConnectionParams.setConnectionTimeout(params, delegate.connectionTimeout());
|
||||
HttpConnectionParams.setSoTimeout(params, delegate.socketTimeout());
|
||||
HttpProtocolParams.setContentCharset(params, charset);
|
||||
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
|
||||
delegate.addHeaders(request, client);
|
||||
}
|
||||
|
||||
@@ -182,8 +184,7 @@ public class BaseResource implements Resource {
|
||||
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
||||
schemeRegistry.register(new Scheme("https", 443, sf));
|
||||
schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory()));
|
||||
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(
|
||||
schemeRegistry);
|
||||
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
|
||||
connManager = cm;
|
||||
return cm;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
public SyncStorageRequestDelegate delegate;
|
||||
protected BaseResource resource;
|
||||
|
||||
@@ -43,19 +43,59 @@ import java.net.Socket;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import ch.boye.httpclientandroidlib.conn.ssl.SSLSocketFactory;
|
||||
import ch.boye.httpclientandroidlib.params.HttpParams;
|
||||
|
||||
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) {
|
||||
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
|
||||
public Socket createSocket(HttpParams params) throws IOException {
|
||||
SSLSocket socket = (SSLSocket) super.createSocket(params);
|
||||
socket.setEnabledProtocols(new String[] { "SSLv3", "TLSv1" });
|
||||
socket.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_SHA" });
|
||||
socket.setEnabledProtocols(DEFAULT_PROTOCOLS);
|
||||
setEnabledCipherSuites(socket);
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ public class AccountActivity extends AccountAuthenticatorActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.SyncTheme);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.sync_account);
|
||||
mContext = getApplicationContext();
|
||||
@@ -132,7 +133,7 @@ public class AccountActivity extends AccountAuthenticatorActivity {
|
||||
}
|
||||
|
||||
public void cancelClickHandler(View target) {
|
||||
moveTaskToBack(true);
|
||||
finish();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -50,6 +50,7 @@ public class SetupFailureActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.SyncTheme);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.sync_setup_failure);
|
||||
mContext = this.getApplicationContext();
|
||||
|
||||
@@ -44,15 +44,18 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class SetupSuccessActivity extends Activity {
|
||||
private final static String LOG_TAG = "SetupSuccessActivity";
|
||||
private TextView setupSubtitle;
|
||||
private Context mContext;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.SyncTheme);
|
||||
super.onCreate(savedInstanceState);
|
||||
mContext = getApplicationContext();
|
||||
Bundle extras = this.getIntent().getExtras();
|
||||
@@ -68,7 +71,7 @@ public class SetupSuccessActivity extends Activity {
|
||||
|
||||
/* Click Handlers */
|
||||
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);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
|
||||
@@ -53,6 +53,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
@@ -79,7 +80,9 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
|
||||
private TextView setupTitleView;
|
||||
private TextView setupNoDeviceLinkTitleView;
|
||||
private TextView setupSubtitleView;
|
||||
private TextView pinTextView;
|
||||
private TextView pinTextView1;
|
||||
private TextView pinTextView2;
|
||||
private TextView pinTextView3;
|
||||
private JPakeClient jClient;
|
||||
|
||||
// Android context.
|
||||
@@ -94,6 +97,7 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(R.style.SyncTheme);
|
||||
Log.i(LOG_TAG, "Called SetupSyncActivity.onCreate.");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@@ -134,9 +138,14 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
|
||||
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.show();
|
||||
|
||||
Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
|
||||
intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
|
||||
startActivity(intent);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -202,20 +211,23 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
|
||||
}
|
||||
// Format PIN for display.
|
||||
int charPerLine = pin.length() / 3;
|
||||
String prettyPin = pin.substring(0, charPerLine) + "\n";
|
||||
prettyPin += pin.substring(charPerLine, 2 * charPerLine) + "\n";
|
||||
prettyPin += pin.substring(2 * charPerLine, pin.length());
|
||||
final String pin1 = pin.substring(0, charPerLine);
|
||||
final String pin2 = pin.substring(charPerLine, 2 * charPerLine);
|
||||
final String pin3 = pin.substring(2 * charPerLine, pin.length());
|
||||
|
||||
final String toDisplay = prettyPin;
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TextView view = pinTextView;
|
||||
if (view == null) {
|
||||
TextView view1 = pinTextView1;
|
||||
TextView view2 = pinTextView2;
|
||||
TextView view3 = pinTextView3;
|
||||
if (view1 == null || view2 == null || view3 == null) {
|
||||
Log.w(LOG_TAG, "Couldn't find view to display PIN.");
|
||||
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));
|
||||
setupSubtitleView = (TextView) findViewById(R.id.setup_subtitle);
|
||||
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.
|
||||
if (setupTitleView == null) {
|
||||
|
||||
@@ -6,7 +6,7 @@ mk_add_options AUTOCONF=autoconf213
|
||||
ac_cv_visibility_pragma=no
|
||||
|
||||
ac_add_options --disable-install-strip
|
||||
ac_add_options --disable-installer
|
||||
|
||||
ac_add_options --enable-application=mobile/android
|
||||
|
||||
# Nightlies only since this has a cost in performance
|
||||
|
||||
1
mobile/android/sync/android-drawable-hdpi-resources.mn
Normal file
1
mobile/android/sync/android-drawable-hdpi-resources.mn
Normal file
@@ -0,0 +1 @@
|
||||
mobile/android/base/resources/drawable-hdpi/sync_ic_launcher.png
|
||||
1
mobile/android/sync/android-drawable-ldpi-resources.mn
Normal file
1
mobile/android/sync/android-drawable-ldpi-resources.mn
Normal file
@@ -0,0 +1 @@
|
||||
mobile/android/base/resources/drawable-ldpi/sync_ic_launcher.png
|
||||
1
mobile/android/sync/android-drawable-mdpi-resources.mn
Normal file
1
mobile/android/sync/android-drawable-mdpi-resources.mn
Normal file
@@ -0,0 +1 @@
|
||||
mobile/android/base/resources/drawable-mdpi/sync_ic_launcher.png
|
||||
@@ -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-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
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<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>
|
||||
|
||||
<!-- 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_pin_default">&sync.pin.default.label;</string>
|
||||
<string name="sync_link_show">&sync.link.show.label;</string>
|
||||
<string name="sync_link_nodevice">&sync.link.nodevice.label;</string>
|
||||
<string name="sync_pin_default">&sync.pin.oneline.label;</string>
|
||||
<string name="sync_link_show"><u>&sync.link.show.label;</u></string>
|
||||
<string name="sync_link_advancedsetup"><u>&sync.link.advancedsetup.label;</u></string>
|
||||
|
||||
<!-- J-PAKE Waiting Screen -->
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ mk_add_options AUTOCONF=autoconf213
|
||||
ac_cv_visibility_pragma=no
|
||||
|
||||
ac_add_options --disable-install-strip
|
||||
ac_add_options --disable-installer
|
||||
|
||||
ac_add_options --enable-application=mobile
|
||||
|
||||
# Nightlies only since this has a cost in performance
|
||||
|
||||
@@ -586,7 +586,6 @@ nsSocketOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *countWrit
|
||||
PRInt32 n = PR_Write(fd, buf, count);
|
||||
|
||||
SOCKET_LOG((" PR_Write returned [n=%d]\n", n));
|
||||
NS_ASSERTION(n != 0, "unexpected return value");
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
|
||||
4
netwerk/cache/nsCacheEntryDescriptor.cpp
vendored
4
netwerk/cache/nsCacheEntryDescriptor.cpp
vendored
@@ -915,6 +915,8 @@ nsCompressOutputStreamWrapper::Write(const char * buf,
|
||||
while (mZstream.avail_in > 0) {
|
||||
zerr = deflate(&mZstream, Z_NO_FLUSH);
|
||||
if (zerr == Z_STREAM_ERROR) {
|
||||
deflateEnd(&mZstream);
|
||||
mStreamInitialized = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// 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) {
|
||||
rv = WriteBuffer();
|
||||
if (NS_FAILED(rv)) {
|
||||
deflateEnd(&mZstream);
|
||||
mStreamInitialized = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,6 +851,8 @@ SpdySession::HandleSynReply(SpdySession *self)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
self->mFrameDataStream->UpdateTransportReadEvents(self->mFrameDataSize);
|
||||
|
||||
if (!self->mFrameDataStream->SetFullyOpen()) {
|
||||
// "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
|
||||
@@ -1128,6 +1130,9 @@ SpdySession::HandleHeaders(SpdySession *self)
|
||||
// this is actually not legal in the HTTP mapping of SPDY. All
|
||||
// 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. "
|
||||
"They are ignored in the HTTP/SPDY mapping.",
|
||||
self, streamID));
|
||||
@@ -1148,29 +1153,6 @@ SpdySession::HandleWindowUpdate(SpdySession *self)
|
||||
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
|
||||
// of these methods
|
||||
@@ -1183,21 +1165,47 @@ SpdySession::OnTransportStatus(nsITransport* aTransport,
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
|
||||
// nsHttpChannel synthesizes progress events in OnDataAvailable
|
||||
if (aStatus == nsISocketTransport::STATUS_RECEIVING_FROM)
|
||||
return;
|
||||
switch (aStatus) {
|
||||
// These should appear only once, deliver to the first
|
||||
// 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
|
||||
if (aStatus == nsISocketTransport::STATUS_SENDING_TO)
|
||||
return;
|
||||
default:
|
||||
// The other transport events are ignored here because there is no good
|
||||
// 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;
|
||||
|
||||
status.transport = aTransport;
|
||||
status.status = aStatus;
|
||||
status.progress = aProgress;
|
||||
// NS_NET_STATUS_SENDING_TO:
|
||||
// This is generated by the socket transport when (part) of
|
||||
// a transaction is written out
|
||||
//
|
||||
// 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
|
||||
@@ -1675,6 +1683,7 @@ SpdySession::OnWriteSegment(char *buf,
|
||||
|
||||
mFrameDataRead += *countWritten;
|
||||
|
||||
mFrameDataStream->UpdateTransportReadEvents(*countWritten);
|
||||
if ((mFrameDataRead == mFrameDataSize) && !mFrameDataLast)
|
||||
ChangeDownstreamState(BUFFERING_FRAME_HEADER);
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
|
||||
mSentFinOnData(0),
|
||||
mRecvdFin(0),
|
||||
mFullyOpen(0),
|
||||
mSentWaitingFor(0),
|
||||
mTxInlineFrameAllocation(SpdySession::kDefaultBufferSize),
|
||||
mTxInlineFrameSize(0),
|
||||
mTxInlineFrameSent(0),
|
||||
@@ -82,7 +83,9 @@ SpdyStream::SpdyStream(nsAHttpTransaction *httpTransaction,
|
||||
mTxStreamFrameSent(0),
|
||||
mZlib(compressionContext),
|
||||
mRequestBodyLen(0),
|
||||
mPriority(priority)
|
||||
mPriority(priority),
|
||||
mTotalSent(0),
|
||||
mTotalRead(0)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
|
||||
@@ -458,6 +461,36 @@ SpdyStream::ParseHttpRequestHeaders(const char *buf,
|
||||
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
|
||||
SpdyStream::TransmitFrame(const char *buf,
|
||||
PRUint32 *countUsed)
|
||||
@@ -538,16 +571,11 @@ SpdyStream::TransmitFrame(const char *buf,
|
||||
SpdySession::LogIO(mSession, this, "Writing from Transaction Buffer",
|
||||
buf + offset, transmittedCount);
|
||||
|
||||
if (mUpstreamState == SENDING_REQUEST_BODY) {
|
||||
mTransaction->OnTransportStatus(mSocketTransport,
|
||||
nsISocketTransport::STATUS_SENDING_TO,
|
||||
transmittedCount);
|
||||
}
|
||||
|
||||
*countUsed += transmittedCount;
|
||||
avail -= transmittedCount;
|
||||
offset += transmittedCount;
|
||||
mTxStreamFrameSent += transmittedCount;
|
||||
UpdateTransportSendEvents(transmittedCount);
|
||||
}
|
||||
|
||||
if (!avail) {
|
||||
|
||||
@@ -89,6 +89,9 @@ public:
|
||||
void SetRecvdFin(bool aStatus) { mRecvdFin = aStatus ? 1 : 0; }
|
||||
bool RecvdFin() { return mRecvdFin; }
|
||||
|
||||
void UpdateTransportSendEvents(PRUint32 count);
|
||||
void UpdateTransportReadEvents(PRUint32 count);
|
||||
|
||||
// The zlib header compression dictionary defined by SPDY,
|
||||
// and hooks to the mozilla allocator for zlib to use.
|
||||
static const char *kDictionary;
|
||||
@@ -171,6 +174,9 @@ private:
|
||||
// Flag is set after syn reply received
|
||||
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
|
||||
// frames and data frame headers.
|
||||
nsAutoArrayPtr<char> mTxInlineFrame;
|
||||
@@ -200,6 +206,9 @@ private:
|
||||
// based on nsISupportsPriority definitions
|
||||
PRInt32 mPriority;
|
||||
|
||||
// For Progress Events
|
||||
PRUint64 mTotalSent;
|
||||
PRUint64 mTotalRead;
|
||||
};
|
||||
|
||||
}} // namespace mozilla::net
|
||||
|
||||
@@ -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_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_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)")
|
||||
|
||||
@@ -137,6 +137,42 @@ function getSimpleMeasurements() {
|
||||
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() {}
|
||||
|
||||
TelemetryPing.prototype = {
|
||||
@@ -231,7 +267,8 @@ TelemetryPing.prototype = {
|
||||
appVersion: ai.version,
|
||||
appName: ai.name,
|
||||
appBuildID: ai.appBuildID,
|
||||
platformBuildID: ai.platformBuildID,
|
||||
appUpdateChannel: getUpdateChannel(),
|
||||
platformBuildID: ai.platformBuildID
|
||||
};
|
||||
|
||||
// sysinfo fields are not always available, get what we can.
|
||||
|
||||
@@ -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 *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@@ -214,8 +214,17 @@ static const char kOOMAllocationSizeParameter[] = "OOMAllocationSize=";
|
||||
static const int kOOMAllocationSizeParameterLen =
|
||||
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
|
||||
static Mutex* crashReporterAPILock;
|
||||
static Mutex* notesFieldLock;
|
||||
static AnnotationTable* crashReporterAPIData_Hash;
|
||||
static nsCString* crashReporterAPIData = nsnull;
|
||||
static nsCString* notesField = nsnull;
|
||||
@@ -454,34 +463,31 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
&nBytes, NULL);
|
||||
WriteFile(hFile, "\n", 1, &nBytes, NULL);
|
||||
}
|
||||
|
||||
// Try to get some information about memory.
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
if (GlobalMemoryStatusEx(&statex)) {
|
||||
char buffer[128];
|
||||
int bufferLen;
|
||||
WriteFile(hFile, kSysMemoryParameter,
|
||||
kSysMemoryParameterLen, &nBytes, NULL);
|
||||
ltoa(statex.dwMemoryLoad, buffer, 10);
|
||||
bufferLen = strlen(buffer);
|
||||
WriteFile(hFile, buffer, bufferLen,
|
||||
&nBytes, NULL);
|
||||
WriteFile(hFile, "\n", 1, &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);
|
||||
|
||||
#define WRITE_STATEX_FIELD(field, paramName, conversionFunc) \
|
||||
WriteFile(hFile, k##paramName##Parameter, \
|
||||
k##paramName##ParameterLen, &nBytes, NULL); \
|
||||
conversionFunc(statex.field, buffer, 10); \
|
||||
bufferLen = strlen(buffer); \
|
||||
WriteFile(hFile, buffer, bufferLen, &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) {
|
||||
WriteFile(hFile, kOOMAllocationSizeParameter,
|
||||
kOOMAllocationSizeParameterLen, &nBytes, NULL);
|
||||
@@ -657,6 +663,8 @@ nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
|
||||
|
||||
NS_ASSERTION(!crashReporterAPILock, "Shouldn't have a lock yet");
|
||||
crashReporterAPILock = new Mutex("crashReporterAPILock");
|
||||
NS_ASSERTION(!notesFieldLock, "Shouldn't have a lock yet");
|
||||
notesFieldLock = new Mutex("notesFieldLock");
|
||||
|
||||
crashReporterAPIData_Hash =
|
||||
new nsDataHashtable<nsCStringHashKey,nsCString>();
|
||||
@@ -1086,6 +1094,9 @@ nsresult UnsetExceptionHandler()
|
||||
delete crashReporterAPILock;
|
||||
crashReporterAPILock = nsnull;
|
||||
|
||||
delete notesFieldLock;
|
||||
notesFieldLock = nsnull;
|
||||
|
||||
delete crashReporterAPIData;
|
||||
crashReporterAPIData = nsnull;
|
||||
|
||||
@@ -1255,6 +1266,10 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
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();
|
||||
if (!reporter) {
|
||||
EnqueueDelayedNote(new DelayedNote(data));
|
||||
@@ -1274,6 +1289,8 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(*notesFieldLock);
|
||||
|
||||
notesField->Append(data);
|
||||
return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField);
|
||||
}
|
||||
|
||||
@@ -66,11 +66,12 @@ bool GetMinidumpPath(nsAString& aPath);
|
||||
nsresult SetMinidumpPath(const nsAString& aPath);
|
||||
|
||||
|
||||
// AnnotateCrashReport may be called from any thread in a chrome process,
|
||||
// but may only be called from the main thread in a content process.
|
||||
// AnnotateCrashReport and AppendAppNotesToCrashReport may be called from any
|
||||
// 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 AppendAppNotesToCrashReport(const nsACString& data);
|
||||
|
||||
nsresult SetRestartArgs(int argc, char** argv);
|
||||
nsresult SetupExtraData(nsILocalFile* aAppDataDirectory,
|
||||
const nsACString& aBuildID);
|
||||
|
||||
@@ -6,9 +6,13 @@ function run_test()
|
||||
}
|
||||
|
||||
var is_win7_or_newer = false;
|
||||
var is_windows = false;
|
||||
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Components.interfaces.nsIHttpProtocolHandler);
|
||||
var match = ph.userAgent.match(/Windows NT (\d+).(\d+)/);
|
||||
if (match) {
|
||||
is_windows = true;
|
||||
}
|
||||
if (match && (parseInt(match[1]) > 6 ||
|
||||
parseInt(match[1]) == 6 && parseInt(match[2]) >= 1)) {
|
||||
is_win7_or_newer = true;
|
||||
@@ -22,6 +26,12 @@ function run_test()
|
||||
do_check_true('CrashTime' in extra);
|
||||
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_THREAD_LIST_STREAM));
|
||||
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)
|
||||
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM));
|
||||
});
|
||||
|
||||
@@ -425,6 +425,7 @@ OS_LIBS += \
|
||||
-lmedia \
|
||||
-lhardware_legacy \
|
||||
-lhardware \
|
||||
-lutils \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
#include <signal.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -53,6 +52,7 @@
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsAppShell.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@@ -61,26 +61,9 @@
|
||||
#include "nsWindow.h"
|
||||
|
||||
#include "android/log.h"
|
||||
|
||||
#ifndef ABS_MT_TOUCH_MAJOR
|
||||
// Taken from include/linux/input.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
|
||||
#include "ui/EventHub.h"
|
||||
#include "ui/InputReader.h"
|
||||
#include "ui/InputDispatcher.h"
|
||||
|
||||
#define LOG(args...) \
|
||||
__android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
|
||||
@@ -93,6 +76,7 @@
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace android;
|
||||
|
||||
bool gDrawRequest = false;
|
||||
static nsAppShell *gAppShell = NULL;
|
||||
@@ -123,21 +107,15 @@ pipeHandler(int fd, FdHandler *data)
|
||||
} while (len > 0);
|
||||
}
|
||||
|
||||
static
|
||||
PRUint64 timevalToMS(const struct timeval &time)
|
||||
{
|
||||
return time.tv_sec * 1000 + time.tv_usec / 1000;
|
||||
}
|
||||
|
||||
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::eReal, nsMouseEvent::eNormal);
|
||||
|
||||
event.refPoint.x = x;
|
||||
event.refPoint.y = y;
|
||||
event.time = timevalToMS(time);
|
||||
event.time = timeMs;
|
||||
event.isShift = false;
|
||||
event.isControl = false;
|
||||
event.isMeta = false;
|
||||
@@ -152,64 +130,64 @@ sendMouseEvent(PRUint32 msg, struct timeval& time, int x, int y)
|
||||
static nsEventStatus
|
||||
sendKeyEventWithMsg(PRUint32 keyCode,
|
||||
PRUint32 msg,
|
||||
const timeval &time,
|
||||
uint64_t timeMs,
|
||||
PRUint32 flags)
|
||||
{
|
||||
nsKeyEvent event(true, msg, NULL);
|
||||
event.keyCode = keyCode;
|
||||
event.time = timevalToMS(time);
|
||||
event.time = timeMs;
|
||||
event.flags |= flags;
|
||||
return nsWindow::DispatchInputEvent(event);
|
||||
}
|
||||
|
||||
static void
|
||||
sendKeyEvent(PRUint32 keyCode, bool down, const timeval &time)
|
||||
sendKeyEvent(PRUint32 keyCode, bool down, uint64_t timeMs)
|
||||
{
|
||||
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) {
|
||||
sendKeyEventWithMsg(keyCode, NS_KEY_PRESS, time,
|
||||
sendKeyEventWithMsg(keyCode, NS_KEY_PRESS, timeMs,
|
||||
status == nsEventStatus_eConsumeNoDefault ?
|
||||
NS_EVENT_FLAG_NO_DEFAULT : 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sendSpecialKeyEvent(nsIAtom *command, const timeval &time)
|
||||
sendSpecialKeyEvent(nsIAtom *command, uint64_t timeMs)
|
||||
{
|
||||
nsCommandEvent event(true, nsGkAtoms::onAppCommand, command, NULL);
|
||||
event.time = timevalToMS(time);
|
||||
event.time = timeMs;
|
||||
nsWindow::DispatchInputEvent(event);
|
||||
}
|
||||
|
||||
static void
|
||||
maybeSendKeyEvent(int keyCode, bool pressed, const timeval& time)
|
||||
maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs)
|
||||
{
|
||||
switch (keyCode) {
|
||||
case KEY_BACK:
|
||||
sendKeyEvent(NS_VK_ESCAPE, pressed, time);
|
||||
sendKeyEvent(NS_VK_ESCAPE, pressed, timeMs);
|
||||
break;
|
||||
case KEY_MENU:
|
||||
if (!pressed)
|
||||
sendSpecialKeyEvent(nsGkAtoms::Menu, time);
|
||||
sendSpecialKeyEvent(nsGkAtoms::Menu, timeMs);
|
||||
break;
|
||||
case KEY_SEARCH:
|
||||
if (pressed)
|
||||
sendSpecialKeyEvent(nsGkAtoms::Search, time);
|
||||
sendSpecialKeyEvent(nsGkAtoms::Search, timeMs);
|
||||
break;
|
||||
case KEY_HOME:
|
||||
sendKeyEvent(NS_VK_HOME, pressed, time);
|
||||
sendKeyEvent(NS_VK_HOME, pressed, timeMs);
|
||||
break;
|
||||
case KEY_POWER:
|
||||
sendKeyEvent(NS_VK_SLEEP, pressed, time);
|
||||
sendKeyEvent(NS_VK_SLEEP, pressed, timeMs);
|
||||
break;
|
||||
case KEY_VOLUMEUP:
|
||||
if (pressed)
|
||||
sendSpecialKeyEvent(nsGkAtoms::VolumeUp, time);
|
||||
sendSpecialKeyEvent(nsGkAtoms::VolumeUp, timeMs);
|
||||
break;
|
||||
case KEY_VOLUMEDOWN:
|
||||
if (pressed)
|
||||
sendSpecialKeyEvent(nsGkAtoms::VolumeDown, time);
|
||||
sendSpecialKeyEvent(nsGkAtoms::VolumeDown, timeMs);
|
||||
break;
|
||||
default:
|
||||
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
|
||||
maybeSendKeyEvent(const input_event& e)
|
||||
struct UserInputData {
|
||||
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) {
|
||||
VERBOSE_LOG("Got unknown key event type. type 0x%04x code 0x%04x value %d",
|
||||
e.type, e.code, e.value);
|
||||
return;
|
||||
}
|
||||
// 0 is the default displayId. We only support one display
|
||||
if (displayId)
|
||||
return false;
|
||||
|
||||
if (e.value != 0 && e.value != 1) {
|
||||
VERBOSE_LOG("Got unknown key event value. type 0x%04x code 0x%04x value %d",
|
||||
e.type, e.code, e.value);
|
||||
return;
|
||||
}
|
||||
|
||||
bool pressed = e.value == 1;
|
||||
maybeSendKeyEvent(e.code, pressed, e.time);
|
||||
if (width)
|
||||
*width = gScreenBounds.width;
|
||||
if (height)
|
||||
*height = gScreenBounds.height;
|
||||
if (orientation)
|
||||
*orientation = ROTATION_0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
configureVButtons(FdHandler& data)
|
||||
bool
|
||||
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];
|
||||
snprintf(vbuttonsPath, sizeof(vbuttonsPath),
|
||||
"/sys/board_properties/virtualkeys.%s",
|
||||
data.name);
|
||||
deviceName.string());
|
||||
ScopedClose fd(open(vbuttonsPath, O_RDONLY));
|
||||
if (0 > fd.mFd) {
|
||||
LOG("No vbuttons for mt device %s", data.name);
|
||||
LOG("No vbuttons for mt device %s", deviceName.string());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -263,31 +345,23 @@ configureVButtons(FdHandler& data)
|
||||
|
||||
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;
|
||||
for (size_t i = 0; i < FdHandler::kMaxVButtons; ++i) {
|
||||
FdHandler::VButton& vbutton = data.vbuttons[i];
|
||||
char* token;
|
||||
char* state;
|
||||
|
||||
char* first = config;
|
||||
char* magic;
|
||||
char* state;
|
||||
while ((magic = strtok_r(first, ":", &state))) {
|
||||
// XXX not clear what "0x01" is ... maybe a version
|
||||
// number? See InputManager.java.
|
||||
if (!(token = strtok_r(startStr, ":", &state)) ||
|
||||
strcmp(token, "0x01")) {
|
||||
if (strcmp(magic, "0x01")) {
|
||||
LOG(" magic 0x01 tag missing");
|
||||
break;
|
||||
}
|
||||
startStr = NULL;
|
||||
first = NULL;
|
||||
|
||||
if (!(token = strtok_r(NULL, ":", &state))) {
|
||||
LOG(" failed to read keycode");
|
||||
break;
|
||||
}
|
||||
vbutton.keyCode = atoi(token);
|
||||
|
||||
const char *centerX, *centerY, *width, *height;
|
||||
if (!((centerX = strtok_r(NULL, ":", &state)) &&
|
||||
const char *scanCode, *centerX, *centerY, *width, *height;
|
||||
if (!((scanCode = strtok_r(NULL, ":", &state)) &&
|
||||
(centerX = strtok_r(NULL, ":", &state)) &&
|
||||
(centerY = strtok_r(NULL, ":", &state)) &&
|
||||
(width = 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
|
||||
// assumptions about how the raw input events are mapped
|
||||
// ... le sigh.
|
||||
nsIntRect rect;
|
||||
rect.width = atoi(width);
|
||||
rect.height = atoi(height);
|
||||
rect.x = atoi(centerX) - rect.width / 2;
|
||||
rect.y = atoi(centerY) - rect.height / 2;
|
||||
vbutton.buttonRect = rect;
|
||||
VirtualKeyDefinition def;
|
||||
def.scanCode = atoi(scanCode);
|
||||
def.centerX = atoi(centerX);
|
||||
def.centerY = atoi(centerY);
|
||||
def.width = atoi(width);
|
||||
def.height = atoi(height);
|
||||
outVirtualKeyDefinitions.push(def);
|
||||
|
||||
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
|
||||
calibrateMultitouchDevice(FdHandler& data)
|
||||
void
|
||||
GeckoInputReaderPolicy::getInputDeviceCalibration(const String8& deviceName, InputDeviceCalibration& outCalibration)
|
||||
{
|
||||
if (data.calibrated)
|
||||
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;
|
||||
outCalibration.clear();
|
||||
}
|
||||
|
||||
static void
|
||||
multitouchHandler(int fd, FdHandler *data)
|
||||
void
|
||||
GeckoInputReaderPolicy::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames)
|
||||
{
|
||||
if (!calibrateMultitouchDevice(*data))
|
||||
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);
|
||||
}
|
||||
outExcludedDeviceNames.clear();
|
||||
}
|
||||
|
||||
static void
|
||||
singleTouchHandler(int fd, FdHandler *data)
|
||||
// GeckoInputDispatcher
|
||||
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];
|
||||
int event_count = read(fd, events, sizeof(events));
|
||||
if (event_count < 0) {
|
||||
LOG("Error reading in singleTouchHandler");
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoInputDispatcher::dispatchOnce()
|
||||
{
|
||||
UserInputData data;
|
||||
{
|
||||
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);
|
||||
|
||||
for (int i = 0; i < event_count; i++) {
|
||||
input_event *event = &events[i];
|
||||
|
||||
if (event->type == EV_KEY) {
|
||||
switch (event->code) {
|
||||
case BTN_TOUCH:
|
||||
data->mtDown = event->value;
|
||||
break;
|
||||
default:
|
||||
maybeSendKeyEvent(*event);
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
switch (data.type) {
|
||||
case UserInputData::MOTION_DATA: {
|
||||
PRUint32 msg;
|
||||
switch (data.action) {
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
msg = NS_MOUSE_BUTTON_DOWN;
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
msg = NS_MOUSE_MOVE;
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
msg = NS_MOUSE_BUTTON_UP;
|
||||
break;
|
||||
}
|
||||
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) {
|
||||
LOG("Error reading in keyHandler");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
nanosecsToMillisecs(nsecs_t nsecs)
|
||||
{
|
||||
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++) {
|
||||
const input_event &e = events[i];
|
||||
|
||||
if (e.type == EV_SYN) {
|
||||
// Ignore this event; it just signifies that a key was pressed.
|
||||
continue;
|
||||
}
|
||||
|
||||
maybeSendKeyEvent(e);
|
||||
void
|
||||
GeckoInputDispatcher::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)
|
||||
{
|
||||
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()
|
||||
@@ -551,6 +572,9 @@ nsAppShell::nsAppShell()
|
||||
|
||||
nsAppShell::~nsAppShell()
|
||||
{
|
||||
status_t result = mReaderThread->requestExitAndWait();
|
||||
if (result)
|
||||
LOG("Could not stop reader thread - %d", result);
|
||||
gAppShell = NULL;
|
||||
}
|
||||
|
||||
@@ -569,52 +593,15 @@ nsAppShell::Init()
|
||||
rv = AddFdHandler(signalfds[0], pipeHandler, "");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
DIR *dir = opendir("/dev/input");
|
||||
NS_ENSURE_TRUE(dir, NS_ERROR_UNEXPECTED);
|
||||
mEventHub = new EventHub();
|
||||
mReaderPolicy = new GeckoInputReaderPolicy();
|
||||
mDispatcher = new GeckoInputDispatcher();
|
||||
|
||||
#define IS_BIT_SET(bit, flags) (flags[bit >> 3] & (1 << (bit & 0x7)))
|
||||
|
||||
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");
|
||||
}
|
||||
mReader = new InputReader(mEventHub, mReaderPolicy, mDispatcher);
|
||||
mReaderThread = new InputReaderThread(mReader);
|
||||
|
||||
status_t result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
|
||||
NS_ENSURE_FALSE(result, NS_ERROR_UNEXPECTED);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -655,6 +642,8 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
for (int i = 0; i < event_count; i++)
|
||||
mHandlers[events[i].data.u32].run();
|
||||
|
||||
mDispatcher->dispatchOnce();
|
||||
|
||||
// NativeEventCallback always schedules more if it needs it
|
||||
// so we can coalesce these.
|
||||
// See the implementation in nsBaseAppShell.cpp for more info
|
||||
|
||||
@@ -38,10 +38,15 @@
|
||||
#ifndef nsAppShell_h
|
||||
#define nsAppShell_h
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsBaseAppShell.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "utils/RefBase.h"
|
||||
|
||||
namespace mozilla {
|
||||
bool ProcessNextEvent();
|
||||
void NotifyEvent();
|
||||
@@ -55,10 +60,6 @@ typedef void(*FdHandlerCallback)(int, FdHandler *);
|
||||
class FdHandler {
|
||||
public:
|
||||
FdHandler()
|
||||
: mtState(MT_START)
|
||||
, keyCode(0)
|
||||
, mtDown(false)
|
||||
, calibrated(false)
|
||||
{
|
||||
memset(name, 0, sizeof(name));
|
||||
}
|
||||
@@ -66,57 +67,21 @@ public:
|
||||
int fd;
|
||||
char name[64];
|
||||
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()
|
||||
{
|
||||
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 {
|
||||
public:
|
||||
nsAppShell();
|
||||
@@ -138,6 +103,12 @@ private:
|
||||
// This is somewhat racy but is perfectly safe given how the callback works
|
||||
bool mNativeCallbackRequest;
|
||||
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 */
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "nsAppShellSingleton.h"
|
||||
#include "nsScreenManagerGonk.h"
|
||||
#include "nsIdleServiceGonk.h"
|
||||
#include "nsTransferable.h"
|
||||
|
||||
#include "nsHTMLFormatConverter.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@@ -55,6 +56,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerGonk)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceGonk)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_APPSHELL_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_HTMLFORMATCONVERTER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_WINDOW_CID, false, NULL, nsWindowConstructor },
|
||||
@@ -70,6 +73,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerGonkConstructor },
|
||||
{ &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor },
|
||||
{ &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceGonkConstructor },
|
||||
{ &kNS_TRANSFERABLE_CID, false, NULL, nsTransferableConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -80,6 +84,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
|
||||
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
|
||||
{ "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -2823,7 +2823,7 @@ nsCycleCollector::GCIfNeeded(bool aForceGC)
|
||||
// rt->Collect() must be called from the main thread,
|
||||
// because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN)
|
||||
// which returns false if not in the main thread.
|
||||
rt->Collect();
|
||||
rt->Collect(js::gcreason::CC_FORCED, nsGCNormal);
|
||||
#ifdef COLLECT_TIME_DEBUG
|
||||
printf("cc: GC() took %lldms\n", (PR_Now() - start) / PR_USEC_PER_MSEC);
|
||||
#endif
|
||||
|
||||
@@ -106,9 +106,10 @@ struct nsCycleCollectionJSRuntime : public nsCycleCollectionLanguageRuntime
|
||||
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
|
||||
|
||||
@@ -3,7 +3,6 @@ export JAVA_HOME=/d/jdk1.6.0_14
|
||||
|
||||
ac_add_options --enable-application=xulrunner
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --disable-installer
|
||||
ac_add_options --disable-tests
|
||||
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
|
||||
@@ -6,7 +6,6 @@ export JAVA_HOME=/d/jdk1.6.0_14
|
||||
|
||||
ac_add_options --enable-application=xulrunner
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --disable-installer
|
||||
ac_add_options --disable-tests
|
||||
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
|
||||
Reference in New Issue
Block a user