deleted file mode 100644
--- a/dom/ipc/ContentPrefs.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#include "ContentPrefs.h"
-
-/******************************************************************************
- *
- * DO NOT ADD PREFS TO THIS LIST WITHOUT DOM PEER REVIEW
- *
- * This is the list of preferences that are sent to the content process on
- * startup. Only prefs that are required immediately upon startup should be
- * listed here. The first IPC message received in the content process will
- * contain all the other prefs. Prefs should only be listed here if they must be
- * read before the first IPC message is received.
- *
- ******************************************************************************/
-
-const char* mozilla::dom::ContentPrefs::gEarlyPrefs[] = {
- "accessibility.monoaudio.enable",
- "accessibility.mouse_focuses_formcontrol",
- "accessibility.tabfocus_applies_to_xul",
- "app.update.channel",
- "browser.autofocus",
- "browser.dom.window.dump.enabled",
- "browser.sessionhistory.max_entries",
- "browser.sessionhistory.max_total_viewers",
-#if defined(NIGHTLY_BUILD) || defined(DEBUG)
- "browser.startup.record",
-#endif
-#if defined(ANDROID)
- "consoleservice.logcat",
-#endif
- "content.cors.disable",
- "content.cors.no_private_data",
- "content.notify.backoffcount",
- "content.notify.interval",
- "content.notify.ontimer",
- "content.sink.enable_perf_mode",
- "content.sink.event_probe_rate",
- "content.sink.initial_perf_time",
- "content.sink.interactive_deflect_count",
- "content.sink.interactive_parse_time",
- "content.sink.interactive_time",
- "content.sink.pending_event_mode",
- "content.sink.perf_deflect_count",
- "content.sink.perf_parse_time",
- "device.storage.prompt.testing",
- "device.storage.writable.name",
- "devtools.enabled",
- "dom.allow_XUL_XBL_for_file",
- "dom.allow_cut_copy",
- "dom.animations-api.core.enabled",
- "dom.animations-api.element-animate.enabled",
- "dom.animations-api.pending-member.enabled",
- "dom.enable_frame_timing",
- "dom.enable_performance",
- "dom.enable_performance_navigation_timing",
- "dom.enable_resource_timing",
- "dom.event.handling-user-input-time-limit",
- "dom.event.touch.coalescing.enabled",
- "dom.forms.autocomplete.formautofill",
- "dom.forms.inputmode",
- "dom.input.skip_cursor_move_for_same_value_set",
- "dom.ipc.processPriorityManager.backgroundGracePeriodMS",
- "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS",
- "dom.ipc.useNativeEventProcessing.content",
- "dom.max_chrome_script_run_time",
- "dom.max_ext_content_script_run_time",
- "dom.max_script_run_time",
- "dom.mozBrowserFramesEnabled",
- "dom.performance.enable_notify_performance_timing",
- "dom.performance.enable_user_timing_logging",
- "dom.placeholder.show_on_focus",
- "dom.requestIdleCallback.enabled",
- "dom.script_loader.bytecode_cache.enabled",
- "dom.script_loader.bytecode_cache.strategy",
- "dom.storage.testing",
- "dom.url.encode_decode_hash",
- "dom.url.getters_decode_hash",
- "dom.use_watchdog",
- "dom.vibrator.enabled",
- "dom.vibrator.max_vibrate_list_len",
- "dom.vibrator.max_vibrate_ms",
- "dom.webcomponents.customelements.enabled",
- "dom.webcomponents.shadowdom.enabled",
- "focusmanager.testmode",
- "font.size.inflation.disabledInMasterProcess",
- "font.size.inflation.emPerLine",
- "font.size.inflation.forceEnabled",
- "font.size.inflation.lineThreshold",
- "font.size.inflation.mappingIntercept",
- "font.size.inflation.maxRatio",
- "font.size.inflation.minTwips",
- "font.size.systemFontScale",
- "full-screen-api.allow-trusted-requests-only",
- "full-screen-api.enabled",
- "full-screen-api.unprefix.enabled",
-#ifdef FUZZING
- "fuzzing.enabled",
-#endif
- "gfx.font_rendering.opentype_svg.enabled",
- "hangmonitor.timeout",
- "html5.flushtimer.initialdelay",
- "html5.flushtimer.subsequentdelay",
- "html5.offmainthread",
- "intl.charset.fallback.tld",
- "intl.charset.fallback.utf8_for_file",
- "intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition",
- "javascript.enabled",
- "javascript.options.array_prototype_values",
- "javascript.options.asmjs",
- "javascript.options.asyncstack",
- "javascript.options.baselinejit",
- "javascript.options.baselinejit.threshold",
- "javascript.options.baselinejit.unsafe_eager_compilation",
- "javascript.options.discardSystemSource",
- "javascript.options.dump_stack_on_debuggee_would_run",
- "javascript.options.gczeal",
- "javascript.options.gczeal.frequency",
- "javascript.options.ion",
- "javascript.options.ion.offthread_compilation",
- "javascript.options.ion.threshold",
- "javascript.options.ion.unsafe_eager_compilation",
- "javascript.options.jit.full_debug_checks",
- "javascript.options.native_regexp",
- "javascript.options.parallel_parsing",
- "javascript.options.shared_memory",
- "javascript.options.spectre.index_masking",
- "javascript.options.spectre.jit_to_C++_calls",
- "javascript.options.spectre.object_mitigations.barriers",
- "javascript.options.spectre.object_mitigations.misc",
- "javascript.options.spectre.string_mitigations",
- "javascript.options.spectre.value_masking",
- "javascript.options.streams",
- "javascript.options.strict",
- "javascript.options.strict.debug",
- "javascript.options.throw_on_asmjs_validation_failure",
- "javascript.options.throw_on_debuggee_would_run",
- "javascript.options.wasm",
- "javascript.options.wasm_baselinejit",
- "javascript.options.wasm_ionjit",
- "javascript.options.werror",
- "javascript.use_us_english_locale",
- "jsloader.shareGlobal",
- "layout.css.all-shorthand.enabled",
- "layout.css.background-blend-mode.enabled",
- "layout.css.box-decoration-break.enabled",
- "layout.css.color-adjust.enabled",
- "layout.css.column-span.enabled",
- "layout.css.contain.enabled",
- "layout.css.control-characters.visible",
- "layout.css.emulate-moz-box-with-flex",
- "layout.css.expensive-style-struct-assertions.enabled",
- "layout.css.float-logical-values.enabled",
- "layout.css.font-display.enabled",
- "layout.css.font-variations.enabled",
- "layout.css.frames-timing.enabled",
- "layout.css.getBoxQuads.enabled",
- "layout.css.grid-template-subgrid-value.enabled",
- "layout.css.grid.enabled",
- "layout.css.image-orientation.enabled",
- "layout.css.individual-transform.enabled",
- "layout.css.initial-letter.enabled",
- "layout.css.isolation.enabled",
- "layout.css.mix-blend-mode.enabled",
- "layout.css.moz-document.content.enabled",
- "layout.css.osx-font-smoothing.enabled",
- "layout.css.overflow-clip-box.enabled",
- "layout.css.overscroll-behavior.enabled",
- "layout.css.prefixes.animations",
- "layout.css.prefixes.border-image",
- "layout.css.prefixes.box-sizing",
- "layout.css.prefixes.device-pixel-ratio-webkit",
- "layout.css.prefixes.font-features",
- "layout.css.prefixes.gradients",
- "layout.css.prefixes.transforms",
- "layout.css.prefixes.transitions",
- "layout.css.prefixes.webkit",
- "layout.css.scope-pseudo.enabled",
- "layout.css.scoped-style.enabled",
- "layout.css.scroll-behavior.property-enabled",
- "layout.css.scroll-snap.enabled",
-#ifdef MOZ_STYLO
- "layout.css.servo.chrome.enabled",
- "layout.css.servo.enabled",
-#endif
- "layout.css.shape-outside.enabled",
- "layout.css.text-align-unsafe-value.enabled",
- "layout.css.text-combine-upright-digits.enabled",
- "layout.css.text-combine-upright.enabled",
- "layout.css.text-justify.enabled",
- "layout.css.touch_action.enabled",
- "layout.css.visited_links_enabled",
- "layout.idle_period.required_quiescent_frames",
- "layout.idle_period.time_limit",
- "layout.interruptible-reflow.enabled",
- "mathml.disabled",
- "media.audio-max-decode-error",
- "media.cache_readahead_limit",
- "media.cache_resume_threshold",
- "media.cache_size",
- "media.clearkey.persistent-license.enabled",
- "media.cubeb.backend",
- "media.cubeb.sandbox",
- "media.cubeb_latency_msg_frames",
- "media.cubeb_latency_playback_ms",
- "media.decoder-doctor.wmf-disabled-is-failure",
- "media.decoder.recycle.enabled",
- "media.decoder.skip-to-next-key-frame.enabled",
- "media.dormant-on-pause-timeout-ms",
- "media.eme.audio.blank",
- "media.eme.chromium-api.video-shmems",
- "media.eme.enabled",
- "media.eme.video.blank",
- "media.ffmpeg.enabled",
- "media.ffmpeg.low-latency.enabled",
- "media.ffvpx.enabled",
- "media.ffvpx.low-latency.enabled",
- "media.flac.enabled",
- "media.forcestereo.enabled",
- "media.gmp.decoder.enabled",
- "media.gmp.insecure.allow",
- "media.gpu-process-decoder",
- "media.hls.enabled",
- "media.libavcodec.allow-obsolete",
- "media.memory_cache_max_size",
- "media.memory_caches_combined_limit_kb",
- "media.memory_caches_combined_limit_pc_sysmem",
- "media.mp4.enabled",
- "media.navigator.mediadatadecoder_enabled",
- "media.ogg.enabled",
- "media.ogg.flac.enabled",
- "media.playback.warnings-as-errors",
- "media.playback.warnings-as-errors.stagefright-vs-rust",
- "media.resampling.enabled",
- "media.resume-bkgnd-video-on-tabhover",
- "media.ruin-av-sync.enabled",
- "media.rust.mp4parser",
- "media.rust.test_mode",
- "media.seamless-looping",
- "media.suspend-bkgnd-video.delay-ms",
- "media.suspend-bkgnd-video.enabled",
- "media.use-blank-decoder",
- "media.video-max-decode-error",
- "media.video_stats.enabled",
- "media.videocontrols.lock-video-orientation",
- "media.volume_scale",
- "media.webspeech.recognition.enable",
- "media.webspeech.recognition.force_enable",
- "media.webspeech.synth.force_global_queue",
- "media.webspeech.test.enable",
- "media.webspeech.test.fake_fsm_events",
- "media.webspeech.test.fake_recognition_service",
- "media.wmf.allow-unsupported-resolutions",
- "media.wmf.enabled",
- "media.wmf.skip-blacklist",
- "media.wmf.vp9.enabled",
- "network.IDN.blacklist_chars",
- "network.IDN.restriction_profile",
- "network.IDN.use_whitelist",
- "network.IDN_show_punycode",
- "network.buffer.cache.count",
- "network.buffer.cache.size",
- "network.captive-portal-service.enabled",
- "network.cookie.cookieBehavior",
- "network.cookie.lifetimePolicy",
- "network.dns.disablePrefetch",
- "network.dns.disablePrefetchFromHTTPS",
- "network.http.tailing.enabled",
- "network.jar.block-remote-files",
- "network.loadinfo.skip_type_assertion",
- "network.notify.changed",
- "network.offline-mirrors-connectivity",
- "network.protocol-handler.external.jar",
- "network.proxy.type",
- "network.security.ports.banned",
- "network.security.ports.banned.override",
- "network.standard-url.enable-rust",
- "network.standard-url.max-length",
- "network.standard-url.punycode-host",
- "network.sts.max_time_for_events_between_two_polls",
- "network.sts.max_time_for_pr_close_during_shutdown",
- "network.tcp.keepalive.enabled",
- "network.tcp.keepalive.idle_time",
- "network.tcp.keepalive.probe_count",
- "network.tcp.keepalive.retry_interval",
- "network.tcp.sendbuffer",
- "nglayout.debug.invalidation",
- "privacy.donottrackheader.enabled",
- "privacy.firstparty.isolate",
- "privacy.firstparty.isolate.restrict_opener_access",
- "privacy.reduceTimerPrecision",
- "privacy.resistFingerprinting",
- "privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts",
- "privacy.resistFingerprinting.reduceTimerPrecision.jitter",
- "privacy.resistFingerprinting.reduceTimerPrecision.microseconds",
- "privacy.resistFingerprinting.target_video_res",
- "privacy.resistFingerprinting.video_dropped_ratio",
- "privacy.resistFingerprinting.video_frames_per_sec",
- "privacy.trackingprotection.lower_network_priority",
- "privacy.window.maxInnerHeight",
- "privacy.window.maxInnerWidth",
- "security.csp.enable",
- "security.data_uri.block_toplevel_data_uri_navigations",
- "security.data_uri.unique_opaque_origin",
- "security.fileuri.strict_origin_policy",
- "security.mixed_content.block_active_content",
- "security.mixed_content.block_display_content",
- "security.mixed_content.block_object_subrequest",
- "security.mixed_content.hsts_priming_cache_timeout",
- "security.mixed_content.send_hsts_priming",
- "security.mixed_content.upgrade_display_content",
- "security.mixed_content.use_hsts",
- "security.sandbox.content.level",
- "security.sandbox.content.tempDirSuffix",
- "security.sandbox.logging.enabled",
- "security.sandbox.mac.track.violations",
- "security.sandbox.windows.log.stackTraceDepth",
- "svg.disabled",
- "svg.display-lists.hit-testing.enabled",
- "svg.display-lists.painting.enabled",
- "svg.new-getBBox.enabled",
- "svg.path-caching.enabled",
- "svg.transform-box.enabled",
- "toolkit.asyncshutdown.crash_timeout",
- "toolkit.asyncshutdown.log",
- "toolkit.osfile.log",
- "toolkit.osfile.log.redirect",
- "toolkit.telemetry.enabled",
- "toolkit.telemetry.idleTimeout",
- "toolkit.telemetry.initDelay",
- "toolkit.telemetry.log.dump",
- "toolkit.telemetry.log.level",
- "toolkit.telemetry.minSubsessionLength",
- "toolkit.telemetry.scheduler.idleTickInterval",
- "toolkit.telemetry.scheduler.tickInterval",
- "toolkit.telemetry.testing.overridePreRelease",
- "toolkit.telemetry.unified",
- "ui.key.menuAccessKeyFocuses",
- "ui.popup.disable_autohide",
- "ui.use_activity_cursor",
- "view_source.editor.external",
- "zoom.maxPercent",
- "zoom.minPercent"
-};
-
-const char** mozilla::dom::ContentPrefs::GetEarlyPrefs(size_t* aCount)
-{
- *aCount = ArrayLength(ContentPrefs::gEarlyPrefs);
- return gEarlyPrefs;
-}
-
-const char* mozilla::dom::ContentPrefs::GetEarlyPref(size_t aIndex)
-{
- MOZ_ASSERT(aIndex < ArrayLength(ContentPrefs::gEarlyPrefs));
- return gEarlyPrefs[aIndex];
-}
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -10,17 +10,16 @@
#include "base/basictypes.h"
#include "GeckoProfiler.h"
#include "MainThreadUtils.h"
#include "mozilla/ArenaAllocatorExtensions.h"
#include "mozilla/ArenaAllocator.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
-#include "mozilla/dom/ContentPrefs.h"
#include "mozilla/dom/PContent.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/Logging.h"
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/Omnijar.h"
#include "mozilla/Preferences.h"
@@ -126,16 +125,39 @@ static const uint32_t MAX_ADVISABLE_PREF
enum class PrefType : uint8_t
{
None = 0, // only used when neither the default nor user value is set
String = 1,
Int = 2,
Bool = 3,
};
+// This is used for pref names and string pref values. We encode the string
+// length, then a '/', then the string chars. This encoding means there are no
+// special chars that are forbidden or require escaping.
+static void
+SerializeAndAppendString(const char* aChars, nsCString& aStr)
+{
+ aStr.AppendInt(uint32_t(strlen(aChars)));
+ aStr.Append('/');
+ aStr.Append(aChars);
+}
+
+static char*
+DeserializeString(char* aChars, nsCString& aStr)
+{
+ char* p = aChars;
+ uint32_t length = strtol(p, &p, 10);
+ MOZ_ASSERT(p[0] == '/');
+ p++; // move past the '/'
+ aStr.Assign(p, length);
+ p += length; // move past the string itself
+ return p;
+}
+
// Keep this in sync with PrefValue in prefs_parser/src/lib.rs.
union PrefValue {
const char* mStringVal;
int32_t mIntVal;
bool mBoolVal;
bool Equals(PrefType aType, PrefValue aValue)
{
@@ -218,16 +240,74 @@ union PrefValue {
case dom::PrefValue::Tbool:
mBoolVal = aDomValue.get_bool();
return PrefType::Bool;
default:
MOZ_CRASH();
}
}
+
+ void SerializeAndAppend(PrefType aType, nsCString& aStr)
+ {
+ switch (aType) {
+ case PrefType::Bool:
+ aStr.Append(mBoolVal ? 'T' : 'F');
+ break;
+
+ case PrefType::Int:
+ aStr.AppendInt(mIntVal);
+ break;
+
+ case PrefType::String: {
+ SerializeAndAppendString(mStringVal, aStr);
+ break;
+ }
+
+ case PrefType::None:
+ default:
+ MOZ_CRASH();
+ }
+ }
+
+ static char* Deserialize(PrefType aType,
+ char* aStr,
+ dom::MaybePrefValue* aDomValue)
+ {
+ char* p = aStr;
+
+ switch (aType) {
+ case PrefType::Bool:
+ if (*p == 'T') {
+ *aDomValue = true;
+ } else if (*p == 'F') {
+ *aDomValue = false;
+ } else {
+ *aDomValue = false;
+ NS_ERROR("bad bool pref value");
+ }
+ p++;
+ return p;
+
+ case PrefType::Int: {
+ *aDomValue = int32_t(strtol(p, &p, 10));
+ return p;
+ }
+
+ case PrefType::String: {
+ nsCString str;
+ p = DeserializeString(p, str);
+ *aDomValue = str;
+ return p;
+ }
+
+ default:
+ MOZ_CRASH();
+ }
+ }
};
#ifdef DEBUG
const char*
PrefTypeToString(PrefType aType)
{
switch (aType) {
case PrefType::None:
@@ -689,16 +769,169 @@ public:
}
return true;
}
// Do not save default prefs that haven't changed.
return false;
}
+ // Prefs are serialized in a manner that mirrors dom::Pref. The two should be
+ // kept in sync. E.g. if something is added to one it should also be added to
+ // the other. (It would be nice to be able to use the code generated from
+ // IPDL for serializing dom::Pref here instead of writing by hand this
+ // serialization/deserialization. Unfortunately, that generated code is
+ // difficult to use directly, outside of the IPDL IPC code.)
+ //
+ // The grammar for the serialized prefs has the following form.
+ //
+ // <pref> = <type> <locked> ':' <name> ':' <value>? ':' <value>? '\n'
+ // <type> = 'B' | 'I' | 'S'
+ // <locked> = 'L' | '-'
+ // <name> = <string-value>
+ // <value> = <bool-value> | <int-value> | <string-value>
+ // <bool-value> = 'T' | 'F'
+ // <int-value> = an integer literal accepted by strtol()
+ // <string-value> = <int-value> '/' <chars>
+ // <chars> = any char sequence of length dictated by the preceding
+ // <int-value>.
+ //
+ // No whitespace is tolerated between tokens. <type> must match the types of
+ // the values.
+ //
+ // The serialization is text-based, rather than binary, for the following
+ // reasons.
+ //
+ // - The size difference wouldn't be much different between text-based and
+ // binary. Most of the space is for strings (pref names and string pref
+ // values), which would be the same in both styles. And other differences
+ // would be minimal, e.g. small integers are shorter in text but long
+ // integers are longer in text.
+ //
+ // - Likewise, speed differences should be negligible.
+ //
+ // - It's much easier to debug a text-based serialization. E.g. you can
+ // print it and inspect it easily in a debugger.
+ //
+ // Examples of unlocked boolean prefs:
+ // - "B-:8/my.bool1:F:T\n"
+ // - "B-:8/my.bool2:F:\n"
+ // - "B-:8/my.bool3::T\n"
+ //
+ // Examples of locked integer prefs:
+ // - "IL:7/my.int1:0:1\n"
+ // - "IL:7/my.int2:123:\n"
+ // - "IL:7/my.int3::-99\n"
+ //
+ // Examples of unlocked string prefs:
+ // - "S-:10/my.string1:3/abc:4/wxyz\n"
+ // - "S-:10/my.string2:5/1.234:\n"
+ // - "S-:10/my.string3::7/string!\n"
+
+ void SerializeAndAppend(nsCString& aStr)
+ {
+ switch (Type()) {
+ case PrefType::Bool:
+ aStr.Append('B');
+ break;
+
+ case PrefType::Int:
+ aStr.Append('I');
+ break;
+
+ case PrefType::String: {
+ aStr.Append('S');
+ break;
+ }
+
+ case PrefType::None:
+ default:
+ MOZ_CRASH();
+ }
+
+ aStr.Append(mIsLocked ? 'L' : '-');
+ aStr.Append(':');
+
+ SerializeAndAppendString(mName, aStr);
+ aStr.Append(':');
+
+ if (mHasDefaultValue) {
+ mDefaultValue.SerializeAndAppend(Type(), aStr);
+ }
+ aStr.Append(':');
+
+ if (mHasUserValue) {
+ mUserValue.SerializeAndAppend(Type(), aStr);
+ }
+ aStr.Append('\n');
+ }
+
+ static char* Deserialize(char* aStr, dom::Pref* aDomPref)
+ {
+ char* p = aStr;
+
+ // The type.
+ PrefType type;
+ if (*p == 'B') {
+ type = PrefType::Bool;
+ } else if (*p == 'I') {
+ type = PrefType::Int;
+ } else if (*p == 'S') {
+ type = PrefType::String;
+ } else {
+ NS_ERROR("bad pref type");
+ type = PrefType::None;
+ }
+ p++; // move past the type char
+
+ // Locked?
+ bool isLocked;
+ if (*p == 'L') {
+ isLocked = true;
+ } else if (*p == '-') {
+ isLocked = false;
+ } else {
+ NS_ERROR("bad pref locked status");
+ isLocked = false;
+ }
+ p++; // move past the isLocked char
+
+ MOZ_ASSERT(*p == ':');
+ p++; // move past the ':'
+
+ // The pref name.
+ nsCString name;
+ p = DeserializeString(p, name);
+
+ MOZ_ASSERT(*p == ':');
+ p++; // move past the ':' preceding the default value
+
+ dom::MaybePrefValue maybeDefaultValue;
+ if (*p != ':') {
+ dom::PrefValue defaultValue;
+ p = PrefValue::Deserialize(type, p, &maybeDefaultValue);
+ }
+
+ MOZ_ASSERT(*p == ':');
+ p++; // move past the ':' between the default and user values
+
+ dom::MaybePrefValue maybeUserValue;
+ if (*p != '\n') {
+ dom::PrefValue userValue;
+ p = PrefValue::Deserialize(type, p, &maybeUserValue);
+ }
+
+ MOZ_ASSERT(*p == '\n');
+ p++; // move past the '\n' following the user value
+
+ *aDomPref = dom::Pref(name, isLocked, maybeDefaultValue, maybeUserValue);
+
+ return p;
+ }
+
void AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, PrefsSizes& aSizes)
{
// Note: mName is allocated in gPrefNameArena, measured elsewhere.
aSizes.mPrefValues += aMallocSizeOf(this);
if (IsTypeString()) {
if (mHasDefaultValue) {
aSizes.mStringValues += aMallocSizeOf(mDefaultValue.mStringVal);
}
@@ -868,76 +1101,28 @@ pref_savePrefs()
savedPrefs.AppendElement(str);
}
return savedPrefs;
}
#ifdef DEBUG
-// For content processes, what prefs have been initialized?
-enum class ContentProcessPhase
-{
- eNoPrefsSet,
- eEarlyPrefsSet,
- eEarlyAndLatePrefsSet,
-};
-
// Note that this never changes in the parent process, and is only read in
// content processes.
-static ContentProcessPhase gPhase = ContentProcessPhase::eNoPrefsSet;
-
-struct StringComparator
-{
- const char* mPrefName;
-
- explicit StringComparator(const char* aPrefName)
- : mPrefName(aPrefName)
- {
- }
-
- int operator()(const char* aPrefName) const
- {
- return strcmp(mPrefName, aPrefName);
- }
-};
-
-static bool
-IsEarlyPref(const char* aPrefName)
-{
- size_t prefsLen;
- size_t found;
- const char** list = mozilla::dom::ContentPrefs::GetEarlyPrefs(&prefsLen);
- return BinarySearchIf(list, 0, prefsLen, StringComparator(aPrefName), &found);
-}
+static bool gContentProcessPrefsAreInited = false;
#endif // DEBUG
static PrefEntry*
pref_HashTableLookupInner(const char* aPrefName)
{
MOZ_ASSERT(NS_IsMainThread() || mozilla::ServoStyleSet::IsInServoTraversal());
-#ifdef DEBUG
- if (!XRE_IsParentProcess()) {
- if (gPhase == ContentProcessPhase::eNoPrefsSet) {
- MOZ_CRASH_UNSAFE_PRINTF("accessing pref %s before early prefs are set",
- aPrefName);
- }
-
- if (gPhase == ContentProcessPhase::eEarlyPrefsSet &&
- !IsEarlyPref(aPrefName)) {
- // If you hit this crash, you have an early access of a non-early pref.
- // Consider moving the access later or add the pref to the whitelist of
- // early prefs in ContentPrefs.cpp and get review from a DOM peer.
- MOZ_CRASH_UNSAFE_PRINTF(
- "accessing non-early pref %s before late prefs are set", aPrefName);
- }
- }
-#endif
+ MOZ_ASSERT_IF(!XRE_IsParentProcess(), gContentProcessPrefsAreInited);
return static_cast<PrefEntry*>(gHashTable->Search(aPrefName));
}
static Pref*
pref_HashTableLookup(const char* aPrefName)
{
PrefEntry* entry = pref_HashTableLookupInner(aPrefName);
@@ -2915,18 +3100,18 @@ public:
NS_IMETHOD Run() override
{
return RegisterStrongMemoryReporter(new PreferenceServiceReporter());
}
};
} // namespace
-// A list of prefs sent early from the parent, via shared memory.
-static InfallibleTArray<dom::Pref>* gEarlyDomPrefs;
+// A list of changed prefs sent from the parent via shared memory.
+static InfallibleTArray<dom::Pref>* gChangedDomPrefs;
/* static */ already_AddRefed<Preferences>
Preferences::GetInstanceForService()
{
if (sPreferences) {
return do_AddRef(sPreferences);
}
@@ -2947,22 +3132,22 @@ Preferences::GetInstanceForService()
Result<Ok, const char*> res = InitInitialObjects();
if (res.isErr()) {
sPreferences = nullptr;
gCacheDataDesc = res.unwrapErr();
return nullptr;
}
if (!XRE_IsParentProcess()) {
- MOZ_ASSERT(gEarlyDomPrefs);
- for (unsigned int i = 0; i < gEarlyDomPrefs->Length(); i++) {
- Preferences::SetPreference(gEarlyDomPrefs->ElementAt(i));
+ MOZ_ASSERT(gChangedDomPrefs);
+ for (unsigned int i = 0; i < gChangedDomPrefs->Length(); i++) {
+ Preferences::SetPreference(gChangedDomPrefs->ElementAt(i));
}
- delete gEarlyDomPrefs;
- gEarlyDomPrefs = nullptr;
+ delete gChangedDomPrefs;
+ gChangedDomPrefs = nullptr;
} else {
// Check if there is a deployment configuration file. If so, set up the
// pref config machinery, which will actually read the file.
nsAutoCString lockFileName;
nsresult rv = Preferences::GetCString(
"general.config.filename", lockFileName, PrefValueKind::User);
if (NS_SUCCEEDED(rv)) {
@@ -3076,159 +3261,54 @@ Preferences::~Preferences()
NS_IMPL_ISUPPORTS(Preferences,
nsIPrefService,
nsIObserver,
nsIPrefBranch,
nsISupportsWeakReference)
/* static */ void
-Preferences::SerializeEarlyPreferences(nsCString& aStr)
+Preferences::SerializePreferences(nsCString& aStr)
{
MOZ_RELEASE_ASSERT(InitStaticMembers());
- nsAutoCStringN<256> boolPrefs, intPrefs, stringPrefs;
- size_t numEarlyPrefs;
- dom::ContentPrefs::GetEarlyPrefs(&numEarlyPrefs);
-
- for (unsigned int i = 0; i < numEarlyPrefs; i++) {
- const char* prefName = dom::ContentPrefs::GetEarlyPref(i);
- MOZ_ASSERT_IF(i > 0,
- strcmp(prefName, dom::ContentPrefs::GetEarlyPref(i - 1)) > 0);
-
- Pref* pref = pref_HashTableLookup(prefName);
- if (!pref || !pref->MustSendToContentProcesses()) {
- continue;
- }
-
- switch (pref->Type()) {
- case PrefType::Bool:
- boolPrefs.Append(
- nsPrintfCString("%u:%d|", i, Preferences::GetBool(prefName)));
- break;
- case PrefType::Int:
- intPrefs.Append(
- nsPrintfCString("%u:%d|", i, Preferences::GetInt(prefName)));
- break;
- case PrefType::String: {
- nsAutoCString value;
- Preferences::GetCString(prefName, value);
- stringPrefs.Append(
- nsPrintfCString("%u:%d;%s|", i, value.Length(), value.get()));
- } break;
- case PrefType::None:
- break;
- default:
- printf_stderr("preference type: %d\n", int(pref->Type()));
- MOZ_CRASH();
+ aStr.Truncate();
+
+ for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
+ Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
+ if (pref->MustSendToContentProcesses() && pref->HasAdvisablySizedValues()) {
+ pref->SerializeAndAppend(aStr);
}
}
- aStr.Truncate();
- aStr.Append(boolPrefs);
- aStr.Append('\n');
- aStr.Append(intPrefs);
- aStr.Append('\n');
- aStr.Append(stringPrefs);
- aStr.Append('\n');
aStr.Append('\0');
}
/* static */ void
-Preferences::DeserializeEarlyPreferences(char* aStr, size_t aStrLen)
+Preferences::DeserializePreferences(char* aStr, size_t aPrefsLen)
{
MOZ_ASSERT(!XRE_IsParentProcess());
- MOZ_ASSERT(!gEarlyDomPrefs);
- gEarlyDomPrefs = new InfallibleTArray<dom::Pref>();
+ MOZ_ASSERT(!gChangedDomPrefs);
+ gChangedDomPrefs = new InfallibleTArray<dom::Pref>();
char* p = aStr;
-
- // XXX: we assume these pref values are default values, which may not be
- // true. We also assume they are unlocked. Fortunately, these prefs get reset
- // properly by the first IPC message.
-
- // Get the bool prefs.
- while (*p != '\n') {
- int32_t index = strtol(p, &p, 10);
- MOZ_ASSERT(p[0] == ':');
- p++;
- int v = strtol(p, &p, 10);
- MOZ_ASSERT(v == 0 || v == 1);
- dom::MaybePrefValue value(dom::PrefValue(!!v));
- MOZ_ASSERT(p[0] == '|');
- p++;
- dom::Pref pref(nsCString(dom::ContentPrefs::GetEarlyPref(index)),
- /* isLocked */ false,
- value,
- dom::MaybePrefValue());
- gEarlyDomPrefs->AppendElement(pref);
+ while (*p != '\0') {
+ dom::Pref pref;
+ p = Pref::Deserialize(p, &pref);
+ gChangedDomPrefs->AppendElement(pref);
}
- p++;
-
- // Get the int prefs.
- while (*p != '\n') {
- int32_t index = strtol(p, &p, 10);
- MOZ_ASSERT(p[0] == ':');
- p++;
- dom::MaybePrefValue value(
- dom::PrefValue(static_cast<int32_t>(strtol(p, &p, 10))));
- MOZ_ASSERT(p[0] == '|');
- p++;
- dom::Pref pref(nsCString(dom::ContentPrefs::GetEarlyPref(index)),
- /* isLocked */ false,
- value,
- dom::MaybePrefValue());
- gEarlyDomPrefs->AppendElement(pref);
- }
- p++;
-
- // Get the string prefs.
- while (*p != '\n') {
- int32_t index = strtol(p, &p, 10);
- MOZ_ASSERT(p[0] == ':');
- p++;
- int32_t length = strtol(p, &p, 10);
- MOZ_ASSERT(p[0] == ';');
- p++;
- dom::MaybePrefValue value(dom::PrefValue(nsCString(p, length)));
- dom::Pref pref(nsCString(dom::ContentPrefs::GetEarlyPref(index)),
- /* isLocked */ false,
- value,
- dom::MaybePrefValue());
- gEarlyDomPrefs->AppendElement(pref);
- p += length + 1;
- MOZ_ASSERT(*(p - 1) == '|');
- }
- p++;
-
- MOZ_ASSERT(*p == '\0');
// We finished parsing on a '\0'. That should be the last char in the shared
- // memory.
- MOZ_ASSERT(aStr + aStrLen - 1 == p);
+ // memory. (aPrefsLen includes the '\0'.)
+ MOZ_ASSERT(p == aStr + aPrefsLen - 1);
#ifdef DEBUG
- MOZ_ASSERT(gPhase == ContentProcessPhase::eNoPrefsSet);
- gPhase = ContentProcessPhase::eEarlyPrefsSet;
-#endif
-}
-
-/* static */ void
-Preferences::SetLatePreferences(const nsTArray<dom::Pref>* aDomPrefs)
-{
- MOZ_ASSERT(!XRE_IsParentProcess());
-
- for (unsigned int i = 0; i < aDomPrefs->Length(); i++) {
- Preferences::SetPreference(aDomPrefs->ElementAt(i));
- }
-
-#ifdef DEBUG
- MOZ_ASSERT(gPhase == ContentProcessPhase::eEarlyPrefsSet);
- gPhase = ContentProcessPhase::eEarlyAndLatePrefsSet;
+ MOZ_ASSERT(!gContentProcessPrefsAreInited);
+ gContentProcessPrefsAreInited = true;
#endif
}
/* static */ void
Preferences::InitializeUserPrefs()
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!sPreferences->mCurrentFile, "Should only initialize prefs once");
@@ -3455,46 +3535,22 @@ Preferences::GetPreference(dom::Pref* aD
MOZ_ASSERT(XRE_IsParentProcess());
Pref* pref = pref_HashTableLookup(aDomPref->name().get());
if (pref && pref->HasAdvisablySizedValues()) {
pref->ToDomPref(aDomPref);
}
}
-void
-Preferences::GetPreferences(InfallibleTArray<dom::Pref>* aDomPrefs)
-{
- MOZ_ASSERT(XRE_IsParentProcess());
- MOZ_ASSERT(NS_IsMainThread());
-
- aDomPrefs->SetCapacity(gHashTable->EntryCount());
- for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) {
- Pref* pref = static_cast<PrefEntry*>(iter.Get())->mPref;
-
- if (!pref->MustSendToContentProcesses()) {
- // The pref value hasn't changed since it was initialized at startup.
- // Don't bother sending it, because the content process will initialize
- // it the same way.
- continue;
- }
-
- if (pref->HasAdvisablySizedValues()) {
- dom::Pref* setting = aDomPrefs->AppendElement();
- pref->ToDomPref(setting);
- }
- }
-}
-
#ifdef DEBUG
bool
-Preferences::AreAllPrefsSetInContentProcess()
+Preferences::ArePrefsInitedInContentProcess()
{
MOZ_ASSERT(!XRE_IsParentProcess());
- return gPhase == ContentProcessPhase::eEarlyAndLatePrefsSet;
+ return gContentProcessPrefsAreInited;
}
#endif
NS_IMETHODIMP
Preferences::GetBranch(const char* aPrefRoot, nsIPrefBranch** aRetVal)
{
if ((nullptr != aPrefRoot) && (*aPrefRoot != '\0')) {
// TODO: Cache this stuff and allow consumers to share branches (hold weak