зеркало из https://github.com/mozilla/pjs.git
Merge mozilla-central to inbound
This commit is contained in:
Коммит
2d95d4ff31
|
@ -318,3 +318,12 @@ nsBrowserAccess.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
// Pipe `console` log messages to the nsIConsoleService which writes them
|
||||
// to logcat.
|
||||
Services.obs.addObserver(function onConsoleAPILogEvent(subject, topic, data) {
|
||||
let message = subject.wrappedJSObject;
|
||||
let prefix = "Content JS " + message.level.toUpperCase() +
|
||||
" at " + message.filename + ":" + message.lineNumber +
|
||||
" in " + (message.functionName || "anonymous") + ": ";
|
||||
Services.console.logStringMessage(prefix + Array.join(message.arguments, " "));
|
||||
}, "console-api-log-event", false);
|
||||
|
|
|
@ -817,7 +817,7 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS, nsGCNormal, true);
|
||||
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -135,6 +135,8 @@ static PRLogModuleInfo* gJSDiagnostics;
|
|||
// doing the first GC.
|
||||
#define NS_FIRST_GC_DELAY 10000 // ms
|
||||
|
||||
#define NS_FULL_GC_DELAY 60000 // ms
|
||||
|
||||
// The amount of time we wait between a request to CC (after GC ran)
|
||||
// and doing the actual CC.
|
||||
#define NS_CC_DELAY 5000 // ms
|
||||
|
@ -148,6 +150,7 @@ static PRLogModuleInfo* gJSDiagnostics;
|
|||
// if you add statics here, add them to the list in nsJSRuntime::Startup
|
||||
|
||||
static nsITimer *sGCTimer;
|
||||
static nsITimer *sFullGCTimer;
|
||||
static nsITimer *sShrinkGCBuffersTimer;
|
||||
static nsITimer *sCCTimer;
|
||||
|
||||
|
@ -166,6 +169,7 @@ static bool sLoadingInProgress;
|
|||
|
||||
static PRUint32 sCCollectedWaitingForGC;
|
||||
static bool sPostGCEventsToConsole;
|
||||
static bool sDisableExplicitCompartmentGC;
|
||||
static PRUint32 sCCTimerFireCount = 0;
|
||||
static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
|
||||
static PRUint32 sMaxForgetSkippableTime = 0;
|
||||
|
@ -173,9 +177,15 @@ static PRUint32 sTotalForgetSkippableTime = 0;
|
|||
static PRUint32 sRemovedPurples = 0;
|
||||
static PRUint32 sForgetSkippableBeforeCC = 0;
|
||||
static PRUint32 sPreviousSuspectedCount = 0;
|
||||
static PRUint32 sCompartmentGCCount = 0;
|
||||
static nsJSContext* sTopEvaluator = nsnull;
|
||||
static bool sContextDeleted = false;
|
||||
static bool sPreviousWasChromeCompGC = false;
|
||||
|
||||
static bool sCleanupSinceLastGC = true;
|
||||
|
||||
PRUint32 nsJSContext::sGlobalGCEpoch = 0;
|
||||
|
||||
nsScriptNameSpaceManager *gNameSpaceManager;
|
||||
|
||||
static nsIJSRuntimeService *sRuntimeService;
|
||||
|
@ -216,7 +226,8 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
const PRUnichar* aData)
|
||||
{
|
||||
if (sGCOnMemoryPressure) {
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking,
|
||||
true);
|
||||
nsJSContext::CycleCollectNow();
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -938,6 +949,8 @@ static const char js_pccounts_content_str[] = JS_OPTIONS_DOT_STR "pccounts.con
|
|||
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
||||
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
|
||||
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
||||
static const char js_disable_explicit_compartment_gc[] =
|
||||
JS_OPTIONS_DOT_STR "disable_explicit_compartment_gc";
|
||||
|
||||
int
|
||||
nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
|
@ -947,6 +960,8 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
|||
PRUint32 newDefaultJSOptions = oldDefaultJSOptions;
|
||||
|
||||
sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
|
||||
sDisableExplicitCompartmentGC =
|
||||
Preferences::GetBool(js_disable_explicit_compartment_gc);
|
||||
|
||||
bool strict = Preferences::GetBool(js_strict_option_str);
|
||||
if (strict)
|
||||
|
@ -1048,6 +1063,9 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
|||
|
||||
nsJSContext::nsJSContext(JSRuntime *aRuntime)
|
||||
: mGCOnDestruction(true),
|
||||
mChromeComp(false),
|
||||
mGlobalGCEpoch(0),
|
||||
mEvaluationCount(0),
|
||||
mExecuteDepth(0)
|
||||
{
|
||||
|
||||
|
@ -1098,6 +1116,9 @@ nsJSContext::~nsJSContext()
|
|||
DestroyJSContext();
|
||||
|
||||
--sContextCount;
|
||||
if (sTopEvaluator == this) {
|
||||
sTopEvaluator = nsnull;
|
||||
}
|
||||
|
||||
if (!sContextCount && sDidShutdown) {
|
||||
// The last context is being deleted, and we're already in the
|
||||
|
@ -1124,6 +1145,7 @@ nsJSContext::DestroyJSContext()
|
|||
js_options_dot_str, this);
|
||||
|
||||
if (mGCOnDestruction) {
|
||||
sContextDeleted = true;
|
||||
PokeGC(js::gcreason::NSJSCONTEXT_DESTROY);
|
||||
}
|
||||
|
||||
|
@ -2237,6 +2259,7 @@ nsJSContext::CreateNativeGlobalForInner(
|
|||
{
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
PRUint32 flags = aIsChrome? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
|
||||
mChromeComp = aIsChrome;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> systemPrincipal;
|
||||
if (aIsChrome) {
|
||||
|
@ -3159,6 +3182,12 @@ nsJSContext::ScriptEvaluated(bool aTerminated)
|
|||
if (aTerminated && mExecuteDepth == 0 && !JS_IsRunning(mContext)) {
|
||||
mOperationCallbackTime = 0;
|
||||
mModalStateTime = 0;
|
||||
|
||||
IncreaseEvaluationCount(this);
|
||||
if (EvaluationCount(sTopEvaluator) < EvaluationCount(this) &&
|
||||
(!mChromeComp || !sPreviousWasChromeCompGC)) {
|
||||
sTopEvaluator = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3231,9 +3260,20 @@ nsJSContext::ScriptExecuted()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FullGCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
NS_RELEASE(sFullGCTimer);
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||
nsGCNormal, true);
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
|
||||
bool aGlobal)
|
||||
{
|
||||
NS_TIME_FUNCTION_MIN(1.0);
|
||||
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
||||
|
@ -3250,9 +3290,44 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
|||
sPendingLoadCount = 0;
|
||||
sLoadingInProgress = false;
|
||||
|
||||
if (nsContentUtils::XPConnect()) {
|
||||
nsContentUtils::XPConnect()->GarbageCollect(reason, gckind);
|
||||
if (!nsContentUtils::XPConnect()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use compartment GC when we're not asked to do a shrinking GC nor
|
||||
// global GC and compartment GC has been called less than 10 times after
|
||||
// the previous global GC. If a top level browsing context has been
|
||||
// deleted, we do a global GC.
|
||||
if (!sDisableExplicitCompartmentGC &&
|
||||
aGckind != nsGCShrinking && !aGlobal &&
|
||||
EvaluationCount(sTopEvaluator) > 0 &&
|
||||
!sContextDeleted && sCompartmentGCCount < 10) {
|
||||
nsJSContext* top = sTopEvaluator;
|
||||
sTopEvaluator = nsnull;
|
||||
ResetEvaluationCount(top);
|
||||
JSContext* cx = top->GetNativeContext();
|
||||
if (cx) {
|
||||
JSObject* global = top->GetNativeGlobal();
|
||||
if (global) {
|
||||
if (!sFullGCTimer) {
|
||||
CallCreateInstance("@mozilla.org/timer;1", &sFullGCTimer);
|
||||
}
|
||||
if (sFullGCTimer) {
|
||||
sFullGCTimer->Cancel();
|
||||
js::gcreason::Reason reason = js::gcreason::FULL_GC_TIMER;
|
||||
sFullGCTimer->InitWithFuncCallback(FullGCTimerFired,
|
||||
reinterpret_cast<void *>(reason),
|
||||
NS_FULL_GC_DELAY,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
JSCompartment* comp = js::GetObjectCompartment(global);
|
||||
js::CompartmentGCForReason(cx, comp, aReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsContentUtils::XPConnect()->GarbageCollect(aReason, aGckind);
|
||||
}
|
||||
|
||||
//static
|
||||
|
@ -3356,7 +3431,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
NS_RELEASE(sGCTimer);
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason), nsGCNormal);
|
||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||
nsGCNormal, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3524,6 +3600,16 @@ nsJSContext::KillGCTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::KillFullGCTimer()
|
||||
{
|
||||
if (sFullGCTimer) {
|
||||
sFullGCTimer->Cancel();
|
||||
|
||||
NS_RELEASE(sFullGCTimer);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillShrinkGCBuffersTimer()
|
||||
|
@ -3552,8 +3638,8 @@ nsJSContext::GC(js::gcreason::Reason aReason)
|
|||
PokeGC(aReason);
|
||||
}
|
||||
|
||||
static void
|
||||
DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
||||
void
|
||||
nsJSContext::DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
|
||||
|
||||
|
@ -3579,6 +3665,19 @@ DOMGCFinishedCallback(JSRuntime *rt, JSCompartment *comp, const char *status)
|
|||
sCCollectedWaitingForGC = 0;
|
||||
sCleanupSinceLastGC = false;
|
||||
|
||||
if (!comp) {
|
||||
sPreviousWasChromeCompGC = false;
|
||||
sContextDeleted = false;
|
||||
sCompartmentGCCount = 0;
|
||||
++sGlobalGCEpoch;
|
||||
KillFullGCTimer();
|
||||
} else {
|
||||
// Only every other compartment GC is allowed to collect a chrome
|
||||
// compartment. Otherwise we'd collect chrome compartment all the time.
|
||||
sPreviousWasChromeCompGC = xpc::AccessCheck::isChrome(comp);
|
||||
++sCompartmentGCCount;
|
||||
}
|
||||
|
||||
if (sGCTimer) {
|
||||
// If we were waiting for a GC to happen, kill the timer.
|
||||
nsJSContext::KillGCTimer();
|
||||
|
@ -3699,13 +3798,14 @@ void
|
|||
nsJSRuntime::Startup()
|
||||
{
|
||||
// initialize all our statics, so that we can restart XPCOM
|
||||
sGCTimer = sCCTimer = nsnull;
|
||||
sGCTimer = sFullGCTimer = sCCTimer = nsnull;
|
||||
sGCHasRun = false;
|
||||
sLastCCEndTime = 0;
|
||||
sPendingLoadCount = 0;
|
||||
sLoadingInProgress = false;
|
||||
sCCollectedWaitingForGC = 0;
|
||||
sPostGCEventsToConsole = false;
|
||||
sDisableExplicitCompartmentGC = false;
|
||||
gNameSpaceManager = nsnull;
|
||||
sRuntimeService = nsnull;
|
||||
sRuntime = nsnull;
|
||||
|
@ -3862,7 +3962,7 @@ nsJSRuntime::Init()
|
|||
// Let's make sure that our main thread is the same as the xpcom main thread.
|
||||
NS_ASSERTION(NS_IsMainThread(), "bad");
|
||||
|
||||
::JS_SetGCFinishedCallback(sRuntime, DOMGCFinishedCallback);
|
||||
::JS_SetGCFinishedCallback(sRuntime, nsJSContext::DOMGCFinishedCallback);
|
||||
|
||||
JSSecurityCallbacks *callbacks = JS_GetRuntimeSecurityCallbacks(sRuntime);
|
||||
NS_ASSERTION(callbacks, "SecMan should have set security callbacks!");
|
||||
|
@ -3947,6 +4047,7 @@ void
|
|||
nsJSRuntime::Shutdown()
|
||||
{
|
||||
nsJSContext::KillGCTimer();
|
||||
nsJSContext::KillFullGCTimer();
|
||||
nsJSContext::KillShrinkGCBuffersTimer();
|
||||
nsJSContext::KillCCTimer();
|
||||
|
||||
|
|
|
@ -181,7 +181,9 @@ public:
|
|||
static void LoadStart();
|
||||
static void LoadEnd();
|
||||
|
||||
static void GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind = nsGCNormal);
|
||||
static void GarbageCollectNow(js::gcreason::Reason aReason,
|
||||
PRUint32 aGckind,
|
||||
bool aGlobal);
|
||||
static void ShrinkGCBuffersNow();
|
||||
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
||||
// called even if the previous collection was GC.
|
||||
|
@ -190,6 +192,7 @@ public:
|
|||
|
||||
static void PokeGC(js::gcreason::Reason aReason);
|
||||
static void KillGCTimer();
|
||||
static void KillFullGCTimer();
|
||||
|
||||
static void PokeShrinkGCBuffers();
|
||||
static void KillShrinkGCBuffersTimer();
|
||||
|
@ -208,6 +211,29 @@ public:
|
|||
JSObject* global = JS_GetGlobalObject(mContext);
|
||||
return global ? mGlobalObjectRef.get() : nsnull;
|
||||
}
|
||||
|
||||
static PRUint32 EvaluationCount(nsJSContext* aCx)
|
||||
{
|
||||
return aCx && aCx->mGlobalGCEpoch == sGlobalGCEpoch ?
|
||||
aCx->mEvaluationCount : 0;
|
||||
}
|
||||
|
||||
static void IncreaseEvaluationCount(nsJSContext* aCx)
|
||||
{
|
||||
if (aCx->mGlobalGCEpoch != sGlobalGCEpoch) {
|
||||
aCx->mEvaluationCount = 0;
|
||||
aCx->mGlobalGCEpoch = sGlobalGCEpoch;
|
||||
}
|
||||
++(aCx->mEvaluationCount);
|
||||
}
|
||||
|
||||
static void ResetEvaluationCount(nsJSContext* aCx)
|
||||
{
|
||||
aCx->mEvaluationCount = 0;
|
||||
}
|
||||
|
||||
static void DOMGCFinishedCallback(JSRuntime* aRt, JSCompartment* aComp,
|
||||
const char* aStatus);
|
||||
protected:
|
||||
nsresult InitializeExternalClasses();
|
||||
|
||||
|
@ -296,7 +322,9 @@ private:
|
|||
bool mScriptsEnabled;
|
||||
bool mGCOnDestruction;
|
||||
bool mProcessingScriptTag;
|
||||
|
||||
bool mChromeComp;
|
||||
PRUint32 mGlobalGCEpoch;
|
||||
PRUint32 mEvaluationCount;
|
||||
PRUint32 mExecuteDepth;
|
||||
PRUint32 mDefaultJSOptions;
|
||||
PRTime mOperationCallbackTime;
|
||||
|
@ -308,6 +336,8 @@ private:
|
|||
// context does. It is eventually collected by the cycle collector.
|
||||
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
|
||||
|
||||
static PRUint32 sGlobalGCEpoch;
|
||||
|
||||
static int JSOptionChangedCallback(const char *pref, void *data);
|
||||
|
||||
static JSBool DOMOperationCallback(JSContext *cx);
|
||||
|
|
|
@ -800,14 +800,14 @@ ContentChild::GetIndexedDBPath()
|
|||
bool
|
||||
ContentChild::RecvGarbageCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvCycleCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||
nsJSContext::CycleCollectNow();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ EXTRA_COMPONENTS = \
|
|||
EXTRA_JS_MODULES = \
|
||||
ril_consts.js \
|
||||
ril_worker.js \
|
||||
systemlibs.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -47,7 +47,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
var RIL = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
||||
|
||||
const DEBUG = true; // set to false to suppress debug messages
|
||||
const DEBUG = false; // set to true to see debug messages
|
||||
|
||||
const RADIOINTERFACELAYER_CID =
|
||||
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
||||
|
@ -241,7 +241,9 @@ RadioInterfaceLayer.prototype = {
|
|||
handleCallStateChange: function handleCallStateChange(call) {
|
||||
debug("handleCallStateChange: " + JSON.stringify(call));
|
||||
call.state = convertRILCallState(call.state);
|
||||
if (call.state == nsIRadioInterfaceLayer.CALL_STATE_CONNECTED) {
|
||||
if (call.state == nsIRadioInterfaceLayer.CALL_STATE_DIALING ||
|
||||
call.state == nsIRadioInterfaceLayer.CALL_STATE_RINGING ||
|
||||
call.state == nsIRadioInterfaceLayer.CALL_STATE_CONNECTED) {
|
||||
// This is now the active call.
|
||||
this._activeCall = call;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
importScripts("ril_consts.js");
|
||||
importScripts("ril_consts.js", "systemlibs.js");
|
||||
|
||||
let DEBUG = false;
|
||||
|
||||
|
@ -72,6 +72,8 @@ const UINT16_SIZE = 2;
|
|||
const UINT32_SIZE = 4;
|
||||
const PARCEL_SIZE_SIZE = UINT32_SIZE;
|
||||
|
||||
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
|
||||
|
||||
/**
|
||||
* This object contains helpers buffering incoming data & deconstructing it
|
||||
* into parcels as well as buffering outgoing data & constructing parcels.
|
||||
|
@ -432,7 +434,6 @@ let Buf = {
|
|||
/**
|
||||
* Process one parcel.
|
||||
*/
|
||||
|
||||
processParcel: function processParcel() {
|
||||
let response_type = this.readUint32();
|
||||
let length = this.readIncoming - UINT32_SIZE;
|
||||
|
@ -445,20 +446,24 @@ let Buf = {
|
|||
request_type = this.tokenRequestMap[token];
|
||||
if (error) {
|
||||
//TODO
|
||||
debug("Received error " + error + " for solicited parcel type " +
|
||||
request_type);
|
||||
if (DEBUG) {
|
||||
debug("Received error " + error + " for solicited parcel type " +
|
||||
request_type);
|
||||
}
|
||||
return;
|
||||
}
|
||||
debug("Solicited response for request type " + request_type +
|
||||
", token " + token);
|
||||
if (DEBUG) {
|
||||
debug("Solicited response for request type " + request_type +
|
||||
", token " + token);
|
||||
}
|
||||
delete this.tokenRequestMap[token];
|
||||
this.lastSolicitedToken = token;
|
||||
} else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
|
||||
request_type = this.readUint32();
|
||||
length -= UINT32_SIZE;
|
||||
debug("Unsolicited response for request type " + request_type);
|
||||
if (DEBUG) debug("Unsolicited response for request type " + request_type);
|
||||
} else {
|
||||
debug("Unknown response type: " + response_type);
|
||||
if (DEBUG) debug("Unknown response type: " + response_type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -483,9 +488,8 @@ let Buf = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Communication with the RIL IPC thread.
|
||||
* Communicate with the RIL IPC thread.
|
||||
*/
|
||||
|
||||
sendParcel: function sendParcel() {
|
||||
// Compute the size of the parcel and write it to the front of the parcel
|
||||
// where we left room for it. Note that he parcel size does not include
|
||||
|
@ -496,7 +500,7 @@ let Buf = {
|
|||
// This assumes that postRILMessage will make a copy of the ArrayBufferView
|
||||
// right away!
|
||||
let parcel = this.outgoingBytes.subarray(0, this.outgoingIndex);
|
||||
debug("Outgoing parcel: " + Array.slice(parcel));
|
||||
if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel));
|
||||
postRILMessage(parcel);
|
||||
this.outgoingIndex = PARCEL_SIZE_SIZE;
|
||||
},
|
||||
|
@ -516,6 +520,25 @@ let Buf = {
|
|||
*/
|
||||
let RIL = {
|
||||
|
||||
/**
|
||||
* Set quirk flags based on the RIL model detected. Note that this
|
||||
* requires the RIL being "warmed up" first, which happens when on
|
||||
* an incoming or outgoing call.
|
||||
*/
|
||||
rilQuirksInitialized: false,
|
||||
initRILQuirks: function initRILQuirks() {
|
||||
// The Samsung Galaxy S2 I-9100 radio sends an extra Uint32 in the
|
||||
// call state.
|
||||
let model_id = libcutils.property_get("ril.model_id");
|
||||
if (DEBUG) debug("Detected RIL model " + model_id);
|
||||
if (model_id == "I9100") {
|
||||
if (DEBUG) debug("Enabling RILQUIRKS_CALLSTATE_EXTRA_UINT32 for I9100.");
|
||||
RILQUIRKS_CALLSTATE_EXTRA_UINT32 = true;
|
||||
}
|
||||
|
||||
this.rilQuirksInitialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the ICC's status.
|
||||
*
|
||||
|
@ -865,7 +888,7 @@ let RIL = {
|
|||
handleParcel: function handleParcel(request_type, length) {
|
||||
let method = this[request_type];
|
||||
if (typeof method == "function") {
|
||||
debug("Handling parcel as " + method.name);
|
||||
if (DEBUG) debug("Handling parcel as " + method.name);
|
||||
method.call(this, length);
|
||||
}
|
||||
}
|
||||
|
@ -915,6 +938,10 @@ RIL[REQUEST_CHANGE_SIM_PIN] = function REQUEST_CHANGE_SIM_PIN() {
|
|||
RIL[REQUEST_CHANGE_SIM_PIN2] = null;
|
||||
RIL[REQUEST_ENTER_NETWORK_DEPERSONALIZATION] = null;
|
||||
RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
||||
if (!this.rilQuirksInitialized) {
|
||||
this.initRILQuirks();
|
||||
}
|
||||
|
||||
let calls_length = 0;
|
||||
// The RIL won't even send us the length integer if there are no active calls.
|
||||
// So only read this integer if the parcel actually has it.
|
||||
|
@ -928,22 +955,24 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
|||
|
||||
let calls = {};
|
||||
for (let i = 0; i < calls_length; i++) {
|
||||
let call = {
|
||||
state: Buf.readUint32(), // CALL_STATE_*
|
||||
callIndex: Buf.readUint32(), // GSM index (1-based)
|
||||
toa: Buf.readUint32(),
|
||||
isMpty: Boolean(Buf.readUint32()),
|
||||
isMT: Boolean(Buf.readUint32()),
|
||||
als: Buf.readUint32(),
|
||||
isVoice: Boolean(Buf.readUint32()),
|
||||
isVoicePrivacy: Boolean(Buf.readUint32()),
|
||||
somethingOrOther: Buf.readUint32(), //XXX TODO whatziz? not in ril.h, but it's in the output...
|
||||
number: Buf.readString(), //TODO munge with TOA
|
||||
numberPresentation: Buf.readUint32(), // CALL_PRESENTATION_*
|
||||
name: Buf.readString(),
|
||||
namePresentation: Buf.readUint32(),
|
||||
uusInfo: null
|
||||
};
|
||||
let call = {};
|
||||
call.state = Buf.readUint32(); // CALL_STATE_*
|
||||
call.callIndex = Buf.readUint32(); // GSM index (1-based)
|
||||
call.toa = Buf.readUint32();
|
||||
call.isMpty = Boolean(Buf.readUint32());
|
||||
call.isMT = Boolean(Buf.readUint32());
|
||||
call.als = Buf.readUint32();
|
||||
call.isVoice = Boolean(Buf.readUint32());
|
||||
call.isVoicePrivacy = Boolean(Buf.readUint32());
|
||||
if (RILQUIRKS_CALLSTATE_EXTRA_UINT32) {
|
||||
Buf.readUint32();
|
||||
}
|
||||
call.number = Buf.readString(); //TODO munge with TOA
|
||||
call.numberPresentation = Buf.readUint32(); // CALL_PRESENTATION_*
|
||||
call.name = Buf.readString();
|
||||
call.namePresentation = Buf.readUint32();
|
||||
|
||||
call.uusInfo = null;
|
||||
let uusInfoPresent = Buf.readUint32();
|
||||
if (uusInfoPresent == 1) {
|
||||
call.uusInfo = {
|
||||
|
@ -952,6 +981,7 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
|
|||
userData: null //XXX TODO byte array?!?
|
||||
};
|
||||
}
|
||||
|
||||
calls[call.callIndex] = call;
|
||||
}
|
||||
Phone.onCurrentCalls(calls);
|
||||
|
@ -1218,9 +1248,6 @@ RIL[UNSOLICITED_RESEND_INCALL_MUTE] = null;
|
|||
*/
|
||||
let Phone = {
|
||||
|
||||
//XXX TODO beware, this is just demo code. It's still missing
|
||||
// communication with the UI thread.
|
||||
|
||||
/**
|
||||
* One of the RADIO_STATE_* constants.
|
||||
*/
|
||||
|
@ -1313,7 +1340,9 @@ let Phone = {
|
|||
*/
|
||||
|
||||
onRadioStateChanged: function onRadioStateChanged(newState) {
|
||||
debug("Radio state changed from " + this.radioState + " to " + newState);
|
||||
if (DEBUG) {
|
||||
debug("Radio state changed from " + this.radioState + " to " + newState);
|
||||
}
|
||||
if (this.radioState == newState) {
|
||||
// No change in state, return.
|
||||
return;
|
||||
|
@ -1455,13 +1484,13 @@ let Phone = {
|
|||
},
|
||||
|
||||
onNetworkStateChanged: function onNetworkStateChanged() {
|
||||
debug("Network state changed, re-requesting phone state.");
|
||||
if (DEBUG) debug("Network state changed, re-requesting phone state.");
|
||||
this.requestNetworkInfo();
|
||||
},
|
||||
|
||||
onICCStatus: function onICCStatus(iccStatus) {
|
||||
if (DEBUG) {
|
||||
debug("iccStatus: " + JSON.stringify(iccStatus));
|
||||
debug("iccStatus: " + JSON.stringify(iccStatus));
|
||||
}
|
||||
this.iccStatus = iccStatus;
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const SYSTEM_PROPERTY_KEY_MAX = 32;
|
||||
const SYSTEM_PROPERTY_VALUE_MAX = 92;
|
||||
|
||||
/**
|
||||
* Expose some system-level functions.
|
||||
*/
|
||||
let libcutils = (function() {
|
||||
let lib;
|
||||
try {
|
||||
lib = ctypes.open("libcutils.so");
|
||||
} catch(ex) {
|
||||
// Return a fallback option in case libcutils.so isn't present (e.g.
|
||||
// when building Firefox with MOZ_B2G_RIL.
|
||||
dump("Could not load libcutils.so. Using fake propdb.");
|
||||
let fake_propdb = Object.create(null);
|
||||
return {
|
||||
property_get: function fake_property_get(key, defaultValue) {
|
||||
if (key in fake_propdb) {
|
||||
return fake_propdb[key];
|
||||
}
|
||||
return defaultValue === undefined ? null : defaultValue;
|
||||
},
|
||||
property_set: function fake_property_set(key, value) {
|
||||
fake_propdb[key] = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let c_property_get = lib.declare("property_get", ctypes.default_abi,
|
||||
ctypes.int, // return value: length
|
||||
ctypes.char.ptr, // key
|
||||
ctypes.char.ptr, // value
|
||||
ctypes.char.ptr); // default
|
||||
let c_property_set = lib.declare("property_set", ctypes.default_abi,
|
||||
ctypes.int, // return value: success
|
||||
ctypes.char.ptr, // key
|
||||
ctypes.char.ptr); // value
|
||||
let c_value_buf = ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)();
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* Get a system property.
|
||||
*
|
||||
* @param key
|
||||
* Name of the property
|
||||
* @param defaultValue [optional]
|
||||
* Default value to return if the property isn't set (default: null)
|
||||
*/
|
||||
property_get: function property_get(key, defaultValue) {
|
||||
if (defaultValue === undefined) {
|
||||
defaultValue = null;
|
||||
}
|
||||
c_property_get(key, c_value_buf, defaultValue);
|
||||
return c_value_buf.readString();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a system property
|
||||
*
|
||||
* @param key
|
||||
* Name of the property
|
||||
* @param value
|
||||
* Value to set the property to.
|
||||
*/
|
||||
property_set: function property_set(key, value) {
|
||||
let rv = c_property_set(key, value);
|
||||
if (rv) {
|
||||
throw Error('libcutils.property_set("' + key + '", "' + value +
|
||||
'") failed with error ' + rv);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
})();
|
|
@ -657,7 +657,8 @@ SizeOfJSContext();
|
|||
D(DOM_IPC) \
|
||||
D(DOM_WORKER) \
|
||||
D(INTER_SLICE_GC) \
|
||||
D(REFRESH_FRAME)
|
||||
D(REFRESH_FRAME) \
|
||||
D(FULL_GC_TIMER)
|
||||
|
||||
namespace gcreason {
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
{
|
||||
"talos_zip": "http://build.mozilla.org/talos/zips/talos.bug721857.05f01e049452.zip"
|
||||
"talos.zip": {
|
||||
"url": "http://build.mozilla.org/talos/zips/talos.bug721857.05f01e049452.zip",
|
||||
"path": ""
|
||||
},
|
||||
"pageloader.xpi": {
|
||||
"url": "http://build.mozilla.org/talos/xpis/pageloader.xpi",
|
||||
"path": "talos/page_load_test"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
#! /usr/bin/env python
|
||||
#
|
||||
# Script name: talos_from_code.py
|
||||
# Purpose: Read from a talos.json file the different files to download for a talos job
|
||||
# Author(s): Zambrano Gasparnian, Armen <armenzg@mozilla.com>
|
||||
# Target: Python 2.5
|
||||
#
|
||||
from optparse import OptionParser
|
||||
try:
|
||||
import json
|
||||
|
@ -8,41 +14,49 @@ import re
|
|||
import urllib2
|
||||
import urlparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
def main():
|
||||
'''
|
||||
This script downloads a talos.json file which indicates which files to download
|
||||
for a talos job.
|
||||
See a talos.json file for a better understand:
|
||||
http://hg.mozilla.org/mozilla-central/raw-file/default/testing/talos/talos.json
|
||||
'''
|
||||
parser = OptionParser()
|
||||
parser.add_option("--talos-json-url", dest="talos_json_url", type="string",
|
||||
help="It indicates from where to download the talos.json file.")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# 1) check that the url was passed
|
||||
if options.talos_json_url == None:
|
||||
print "You need to specify --talos-json-url."
|
||||
sys.exit(1)
|
||||
|
||||
# json file with info on which talos.zip to use
|
||||
# the json file URL should look like this:
|
||||
# %(repo_path)s/raw-file/%(revision)s/testing/talos/talos.json
|
||||
# 2) try to download the talos.json file
|
||||
try:
|
||||
jsonFilename = download_file(options.talos_json_url)
|
||||
except Exception, e:
|
||||
print "ERROR: We have been unable to download the talos.zip indicated " + \
|
||||
"in the talos.json file."
|
||||
print "ERROR: We tried to download the talos.json file but something failed."
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
|
||||
print "INFO: talos.json URL: %s" % options.talos_json_url
|
||||
talos_zip_url = get_value(jsonFilename, "talos_zip")
|
||||
print "INFO: talos.zip URL: '%s'" % talos_zip_url
|
||||
# 3) download the necessary files
|
||||
print "INFO: talos.json URL: %s" % options.talos_json_url
|
||||
try:
|
||||
if passesRestrictions(options.talos_json_url, talos_zip_url) == False:
|
||||
print "ERROR: You have tried to download a talos.zip from a location " + \
|
||||
"different than http://build.mozilla.org/talos/zips"
|
||||
print "ERROR: This is only allowed for the 'try' branch."
|
||||
sys.exit(1)
|
||||
download_file(talos_zip_url, "talos.zip")
|
||||
for key in ('talos.zip', 'pageloader.xpi',):
|
||||
entity = get_value(jsonFilename, key)
|
||||
if passesRestrictions(options.talos_json_url, entity["url"]):
|
||||
# the key is at the same time the filename e.g. talos.zip
|
||||
download_file(entity["url"], entity["path"], key)
|
||||
print "INFO: %s -> %s" % (entity["url"], os.path.join(entity["path"], key))
|
||||
else:
|
||||
print "ERROR: You have tried to download a file " + \
|
||||
"from: %s " % fileUrl + \
|
||||
"which is a location different than http://build.mozilla.org/talos/"
|
||||
print "ERROR: This is only allowed for the certain branches."
|
||||
sys.exit(1)
|
||||
except Exception, e:
|
||||
print "ERROR: We have been unable to download the talos.zip indicated " + \
|
||||
"in the talos.json file."
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -73,15 +87,21 @@ def get_filename_from_url(url):
|
|||
"but the URL seems to be incorrect."
|
||||
sys.exit(1)
|
||||
|
||||
def download_file(url, saveAs=None):
|
||||
def download_file(url, path="", saveAs=None):
|
||||
'''
|
||||
It downloads a file from the URL indicated and can be saved locally with
|
||||
a different name if needed.
|
||||
It downloads a file from URL to the indicated path
|
||||
'''
|
||||
req = urllib2.Request(url)
|
||||
filename = get_filename_from_url(url)
|
||||
f = urllib2.urlopen(req)
|
||||
local_file = open(saveAs if saveAs else filename, 'wb')
|
||||
if path != "" and not os.path.isdir(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
print "INFO: directory %s created" % path
|
||||
except Exception, e:
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
filename = saveAs if saveAs else get_filename_from_url(url)
|
||||
local_file = open(os.path.join(path, filename), 'wb')
|
||||
local_file.write(f.read())
|
||||
local_file.close()
|
||||
return filename
|
||||
|
|
|
@ -12,7 +12,7 @@ Form History test: form field autocomplete
|
|||
<p id="display"></p>
|
||||
|
||||
<!-- we presumably can't hide the content for this test. -->
|
||||
<div id="content">
|
||||
<div id="content" style="direction: rtl;">
|
||||
<!-- unused -->
|
||||
<form id="unused" onsubmit="return false;">
|
||||
<input type="text" name="field1" value="unused">
|
||||
|
@ -32,6 +32,7 @@ Form History test: form field autocomplete
|
|||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
|
||||
var autocompletePopup = getAutocompletePopup();
|
||||
autocompletePopup.style.direction = "ltr";
|
||||
|
||||
var input = $_(1, "field1");
|
||||
|
||||
|
@ -366,6 +367,7 @@ function runTest(testNum) {
|
|||
case 211:
|
||||
checkPopupOpen(false);
|
||||
checkForm("");
|
||||
is(autocompletePopup.style.direction, "rtl", "direction should have been changed from ltr to rtl");
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
|
|
|
@ -72,7 +72,6 @@ _TEST_FILES = findbar_window.xul \
|
|||
test_bug570192.xul \
|
||||
test_bug624329.xul \
|
||||
bug624329_window.xul \
|
||||
test_bug649840.xul \
|
||||
test_popup_preventdefault_chrome.xul \
|
||||
window_popup_preventdefault_chrome.xul \
|
||||
test_largemenu.xul \
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=649840
|
||||
-->
|
||||
<window title="Mozilla Bug 649840"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<textbox id="textLTR" type="autocomplete" autocompletesearch="simple"/>
|
||||
<textbox id="textRTL" type="autocomplete" autocompletesearch="simple"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=649840"
|
||||
target="_blank">Mozilla Bug 649840</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 649840 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(runTest);
|
||||
|
||||
function runTest()
|
||||
{
|
||||
var textLTR = $("textLTR");
|
||||
var textRTL = $("textRTL");
|
||||
|
||||
textLTR.style.direction = "ltr";
|
||||
textRTL.style.direction = "rtl";
|
||||
|
||||
textLTR.value="abcd";
|
||||
textRTL.value="ابجد";
|
||||
|
||||
// open and close the popups to update the popupdir attribute value
|
||||
textLTR.openPopup();
|
||||
textLTR.closePopup();
|
||||
textRTL.openPopup();
|
||||
textRTL.closePopup();
|
||||
|
||||
is(textLTR.popup.style.direction, textLTR.style.direction, "LTR textbox test fails");
|
||||
is(textRTL.popup.style.direction, textRTL.style.direction, "RTL textbox test fails");
|
||||
|
||||
// switch directions of the two textboxes
|
||||
textLTR.style.direction = "rtl";
|
||||
textRTL.style.direction = "ltr";
|
||||
|
||||
// open and close the popups to update the popupdir attribute value
|
||||
textLTR.openPopup();
|
||||
textLTR.closePopup();
|
||||
textRTL.openPopup();
|
||||
textRTL.closePopup();
|
||||
|
||||
is(textLTR.popup.style.direction, textLTR.style.direction, "RTL-switched textbox test fails");
|
||||
is(textRTL.popup.style.direction, textRTL.style.direction, "LTR-switched textbox test fails");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
Загрузка…
Ссылка в новой задаче