Bug 1876589 - Avoid getting and processing preferences for each logging call to ConsoleInstance. r=emilio

This moves handling of the preferences and log value setting into ConsoleInstance, which is where the preferences
are received. It also makes ConsoleInstance add a listener on the preferences service so that updates are triggered.

The functionality is already covered by dom/console/tests/test_jsm.xhtml

Differential Revision: https://phabricator.services.mozilla.com/D199657
This commit is contained in:
Mark Banner 2024-02-13 18:31:21 +00:00
parent f140123e7d
commit fbb22918a3
6 changed files with 82 additions and 64 deletions

View file

@ -190,16 +190,6 @@ add_task(async function navigate_around() {
}, },
}; };
if (Services.prefs.getBoolPref("browser.translations.enable")) {
// The translations pref logs the translation decision on each DOMContentLoaded,
// and only shows the log by the preferences set in the console.createInstance.
// See Bug 1835693. This means that it is invoked on each page load.
knownProblematicPrefs["browser.translations.logLevel"] = {
min: 50,
max: 150,
};
}
if (SpecialPowers.useRemoteSubframes) { if (SpecialPowers.useRemoteSubframes) {
// We access this when considering starting a new content process. // We access this when considering starting a new content process.
// Because there is no complete list of content process types, // Because there is no complete list of content process types,

View file

@ -885,7 +885,7 @@ Console::Console(JSContext* aCx, nsIGlobalObject* aGlobal,
mInnerID(aInnerWindowID), mInnerID(aInnerWindowID),
mDumpToStdout(false), mDumpToStdout(false),
mChromeInstance(false), mChromeInstance(false),
mMaxLogLevel(ConsoleLogLevel::All), mCurrentLogLevel(WebIDLLogLevelToInteger(ConsoleLogLevel::All)),
mStatus(eUnknown), mStatus(eUnknown),
mCreationTimeStamp(TimeStamp::Now()) { mCreationTimeStamp(TimeStamp::Now()) {
// Let's enable the dumping to stdout by default for chrome. // Let's enable the dumping to stdout by default for chrome.
@ -2832,43 +2832,8 @@ void Console::ExecuteDumpFunction(const nsAString& aMessage) {
fflush(stdout); fflush(stdout);
} }
ConsoleLogLevel PrefToValue(const nsAString& aPref,
const ConsoleLogLevel aLevel) {
if (!NS_IsMainThread()) {
NS_WARNING("Console.maxLogLevelPref is not supported on workers!");
return ConsoleLogLevel::All;
}
if (aPref.IsEmpty()) {
return aLevel;
}
NS_ConvertUTF16toUTF8 pref(aPref);
nsAutoCString value;
nsresult rv = Preferences::GetCString(pref.get(), value);
if (NS_WARN_IF(NS_FAILED(rv))) {
return aLevel;
}
int index = FindEnumStringIndexImpl(value.get(), value.Length(),
ConsoleLogLevelValues::strings);
if (NS_WARN_IF(index < 0)) {
nsString message;
message.AssignLiteral("Invalid Console.maxLogLevelPref value: ");
message.Append(NS_ConvertUTF8toUTF16(value));
nsContentUtils::LogSimpleConsoleError(message, "chrome"_ns, false,
true /* from chrome context*/);
return aLevel;
}
MOZ_ASSERT(index < (int)ConsoleLogLevelValues::Count);
return static_cast<ConsoleLogLevel>(index);
}
bool Console::ShouldProceed(MethodName aName) const { bool Console::ShouldProceed(MethodName aName) const {
ConsoleLogLevel maxLogLevel = PrefToValue(mMaxLogLevelPref, mMaxLogLevel); return mCurrentLogLevel <= InternalLogLevelToInteger(aName);
return WebIDLLogLevelToInteger(maxLogLevel) <=
InternalLogLevelToInteger(aName);
} }
uint32_t Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const { uint32_t Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const {

View file

@ -425,8 +425,7 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
bool mDumpToStdout; bool mDumpToStdout;
nsString mPrefix; nsString mPrefix;
bool mChromeInstance; bool mChromeInstance;
ConsoleLogLevel mMaxLogLevel; uint32_t mCurrentLogLevel;
nsString mMaxLogLevelPref;
enum { eUnknown, eInitialized, eShuttingDown } mStatus; enum { eUnknown, eInitialized, eShuttingDown } mStatus;

View file

@ -44,7 +44,8 @@ ConsoleUtils::Level WebIDLevelToConsoleUtilsLevel(ConsoleLevel aLevel) {
ConsoleInstance::ConsoleInstance(JSContext* aCx, ConsoleInstance::ConsoleInstance(JSContext* aCx,
const ConsoleInstanceOptions& aOptions) const ConsoleInstanceOptions& aOptions)
: mConsole(new Console(aCx, nullptr, 0, 0)) { : mMaxLogLevel(ConsoleLogLevel::All),
mConsole(new Console(aCx, nullptr, 0, 0)) {
mConsole->mConsoleID = aOptions.mConsoleID; mConsole->mConsoleID = aOptions.mConsoleID;
mConsole->mPassedInnerID = aOptions.mInnerID; mConsole->mPassedInnerID = aOptions.mInnerID;
@ -58,27 +59,81 @@ ConsoleInstance::ConsoleInstance(JSContext* aCx,
mConsole->mChromeInstance = true; mConsole->mChromeInstance = true;
if (aOptions.mMaxLogLevel.WasPassed()) { if (aOptions.mMaxLogLevel.WasPassed()) {
mConsole->mMaxLogLevel = aOptions.mMaxLogLevel.Value(); mMaxLogLevel = aOptions.mMaxLogLevel.Value();
} }
if (!aOptions.mMaxLogLevelPref.IsEmpty()) { if (!aOptions.mMaxLogLevelPref.IsEmpty()) {
mConsole->mMaxLogLevelPref = aOptions.mMaxLogLevelPref; if (!NS_IsMainThread()) {
NS_ConvertUTF16toUTF8 pref(aOptions.mMaxLogLevelPref); NS_WARNING("Console.maxLogLevelPref is not supported on workers!");
nsAutoCString value; // Set the log level based on what we have.
nsresult rv = Preferences::GetCString(pref.get(), value); SetLogLevel();
if (NS_WARN_IF(NS_FAILED(rv))) { return;
nsString message;
message.AssignLiteral(
"Console.maxLogLevelPref used with a non-existing pref: ");
message.Append(aOptions.mMaxLogLevelPref);
nsContentUtils::LogSimpleConsoleError(message, "chrome"_ns, false,
true /* from chrome context*/);
} }
CopyUTF16toUTF8(aOptions.mMaxLogLevelPref, mMaxLogLevelPref);
Preferences::RegisterCallback(MaxLogLevelPrefChangedCallback,
mMaxLogLevelPref, this);
} }
SetLogLevel();
} }
ConsoleInstance::~ConsoleInstance() = default; ConsoleInstance::~ConsoleInstance() {
AssertIsOnMainThread();
if (!mMaxLogLevelPref.IsEmpty()) {
Preferences::UnregisterCallback(MaxLogLevelPrefChangedCallback,
mMaxLogLevelPref, this);
}
};
ConsoleLogLevel PrefToValue(const nsACString& aPref,
const ConsoleLogLevel aLevel) {
if (aPref.IsEmpty()) {
return aLevel;
}
nsAutoCString value;
nsresult rv = Preferences::GetCString(PromiseFlatCString(aPref).get(), value);
if (NS_WARN_IF(NS_FAILED(rv))) {
nsString message;
message.AssignLiteral(
"Console.maxLogLevelPref used with a non-existing pref: ");
message.Append(NS_ConvertUTF8toUTF16(aPref));
nsContentUtils::LogSimpleConsoleError(message, "chrome"_ns, false,
true /* from chrome context*/);
return aLevel;
}
int index = FindEnumStringIndexImpl(value.get(), value.Length(),
ConsoleLogLevelValues::strings);
if (NS_WARN_IF(index < 0)) {
nsString message;
message.AssignLiteral("Invalid Console.maxLogLevelPref value: ");
message.Append(NS_ConvertUTF8toUTF16(value));
nsContentUtils::LogSimpleConsoleError(message, "chrome"_ns, false,
true /* from chrome context*/);
return aLevel;
}
MOZ_ASSERT(index < (int)ConsoleLogLevelValues::Count);
return static_cast<ConsoleLogLevel>(index);
}
void ConsoleInstance::SetLogLevel() {
mConsole->mCurrentLogLevel = mConsole->WebIDLLogLevelToInteger(
PrefToValue(mMaxLogLevelPref, mMaxLogLevel));
}
// static
void ConsoleInstance::MaxLogLevelPrefChangedCallback(
const char* /* aPrefName */, void* aSelf) {
AssertIsOnMainThread();
if (RefPtr console = static_cast<ConsoleInstance*>(aSelf)) {
console->SetLogLevel();
}
}
JSObject* ConsoleInstance::WrapObject(JSContext* aCx, JSObject* ConsoleInstance::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) { JS::Handle<JSObject*> aGivenProto) {

View file

@ -106,6 +106,12 @@ class ConsoleInstance final : public nsISupports, public nsWrapperCache {
private: private:
~ConsoleInstance(); ~ConsoleInstance();
void SetLogLevel();
static void MaxLogLevelPrefChangedCallback(const char* /* aPrefName */,
void* /* aClosure */);
ConsoleLogLevel mMaxLogLevel;
nsCString mMaxLogLevelPref;
RefPtr<Console> mConsole; RefPtr<Console> mConsole;
}; };

View file

@ -83,6 +83,9 @@ async function test() {
await SpecialPowers.pushPrefEnv({set: [["pref.test.console", "log"]]}) await SpecialPowers.pushPrefEnv({set: [["pref.test.console", "log"]]})
ConsoleTest.go(dumpFunction); ConsoleTest.go(dumpFunction);
// ConsoleTest.go() has already tested the console without this preference.
// This test checks that the addition of the preference is tracked and
// correctly applied.
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
set: [["pref.test.console.notset", "Log"]], set: [["pref.test.console.notset", "Log"]],
}); });