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) {
// We access this when considering starting a new content process.
// Because there is no complete list of content process types,

View file

@ -885,7 +885,7 @@ Console::Console(JSContext* aCx, nsIGlobalObject* aGlobal,
mInnerID(aInnerWindowID),
mDumpToStdout(false),
mChromeInstance(false),
mMaxLogLevel(ConsoleLogLevel::All),
mCurrentLogLevel(WebIDLLogLevelToInteger(ConsoleLogLevel::All)),
mStatus(eUnknown),
mCreationTimeStamp(TimeStamp::Now()) {
// Let's enable the dumping to stdout by default for chrome.
@ -2832,43 +2832,8 @@ void Console::ExecuteDumpFunction(const nsAString& aMessage) {
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 {
ConsoleLogLevel maxLogLevel = PrefToValue(mMaxLogLevelPref, mMaxLogLevel);
return WebIDLLogLevelToInteger(maxLogLevel) <=
InternalLogLevelToInteger(aName);
return mCurrentLogLevel <= InternalLogLevelToInteger(aName);
}
uint32_t Console::WebIDLLogLevelToInteger(ConsoleLogLevel aLevel) const {

View file

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

View file

@ -44,7 +44,8 @@ ConsoleUtils::Level WebIDLevelToConsoleUtilsLevel(ConsoleLevel aLevel) {
ConsoleInstance::ConsoleInstance(JSContext* aCx,
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->mPassedInnerID = aOptions.mInnerID;
@ -58,27 +59,81 @@ ConsoleInstance::ConsoleInstance(JSContext* aCx,
mConsole->mChromeInstance = true;
if (aOptions.mMaxLogLevel.WasPassed()) {
mConsole->mMaxLogLevel = aOptions.mMaxLogLevel.Value();
mMaxLogLevel = aOptions.mMaxLogLevel.Value();
}
if (!aOptions.mMaxLogLevelPref.IsEmpty()) {
mConsole->mMaxLogLevelPref = aOptions.mMaxLogLevelPref;
NS_ConvertUTF16toUTF8 pref(aOptions.mMaxLogLevelPref);
if (!NS_IsMainThread()) {
NS_WARNING("Console.maxLogLevelPref is not supported on workers!");
// Set the log level based on what we have.
SetLogLevel();
return;
}
CopyUTF16toUTF8(aOptions.mMaxLogLevelPref, mMaxLogLevelPref);
Preferences::RegisterCallback(MaxLogLevelPrefChangedCallback,
mMaxLogLevelPref, this);
}
SetLogLevel();
}
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(pref.get(), 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(aOptions.mMaxLogLevelPref);
message.Append(NS_ConvertUTF8toUTF16(aPref));
nsContentUtils::LogSimpleConsoleError(message, "chrome"_ns, false,
true /* from chrome context*/);
}
}
return aLevel;
}
ConsoleInstance::~ConsoleInstance() = default;
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,
JS::Handle<JSObject*> aGivenProto) {

View file

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

View file

@ -83,6 +83,9 @@ async function test() {
await SpecialPowers.pushPrefEnv({set: [["pref.test.console", "log"]]})
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({
set: [["pref.test.console.notset", "Log"]],
});