b2g/chrome/content/settings.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
michael@0 2 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 "use strict;"
michael@0 8
michael@0 9 const Cc = Components.classes;
michael@0 10 const Ci = Components.interfaces;
michael@0 11 const Cu = Components.utils;
michael@0 12 const Cr = Components.results;
michael@0 13
michael@0 14 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
michael@0 15 Cu.import('resource://gre/modules/Services.jsm');
michael@0 16
michael@0 17 #ifdef MOZ_WIDGET_GONK
michael@0 18 XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
michael@0 19 Cu.import("resource://gre/modules/systemlibs.js");
michael@0 20 return libcutils;
michael@0 21 });
michael@0 22 #endif
michael@0 23
michael@0 24 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
michael@0 25 "@mozilla.org/uuid-generator;1",
michael@0 26 "nsIUUIDGenerator");
michael@0 27
michael@0 28 // Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget
michael@0 29 // is resolved this helper could be removed.
michael@0 30 var SettingsListener = {
michael@0 31 _callbacks: {},
michael@0 32
michael@0 33 init: function sl_init() {
michael@0 34 if ('mozSettings' in navigator && navigator.mozSettings) {
michael@0 35 navigator.mozSettings.onsettingchange = this.onchange.bind(this);
michael@0 36 }
michael@0 37 },
michael@0 38
michael@0 39 onchange: function sl_onchange(evt) {
michael@0 40 var callback = this._callbacks[evt.settingName];
michael@0 41 if (callback) {
michael@0 42 callback(evt.settingValue);
michael@0 43 }
michael@0 44 },
michael@0 45
michael@0 46 observe: function sl_observe(name, defaultValue, callback) {
michael@0 47 var settings = window.navigator.mozSettings;
michael@0 48 if (!settings) {
michael@0 49 window.setTimeout(function() { callback(defaultValue); });
michael@0 50 return;
michael@0 51 }
michael@0 52
michael@0 53 if (!callback || typeof callback !== 'function') {
michael@0 54 throw new Error('Callback is not a function');
michael@0 55 }
michael@0 56
michael@0 57 var req = settings.createLock().get(name);
michael@0 58 req.addEventListener('success', (function onsuccess() {
michael@0 59 callback(typeof(req.result[name]) != 'undefined' ?
michael@0 60 req.result[name] : defaultValue);
michael@0 61 }));
michael@0 62
michael@0 63 this._callbacks[name] = callback;
michael@0 64 }
michael@0 65 };
michael@0 66
michael@0 67 SettingsListener.init();
michael@0 68
michael@0 69 // =================== Console ======================
michael@0 70
michael@0 71 SettingsListener.observe('debug.console.enabled', true, function(value) {
michael@0 72 Services.prefs.setBoolPref('consoleservice.enabled', value);
michael@0 73 Services.prefs.setBoolPref('layout.css.report_errors', value);
michael@0 74 });
michael@0 75
michael@0 76 // =================== Languages ====================
michael@0 77 SettingsListener.observe('language.current', 'en-US', function(value) {
michael@0 78 Services.prefs.setCharPref('general.useragent.locale', value);
michael@0 79
michael@0 80 let prefName = 'intl.accept_languages';
michael@0 81 if (Services.prefs.prefHasUserValue(prefName)) {
michael@0 82 Services.prefs.clearUserPref(prefName);
michael@0 83 }
michael@0 84
michael@0 85 let intl = '';
michael@0 86 try {
michael@0 87 intl = Services.prefs.getComplexValue(prefName,
michael@0 88 Ci.nsIPrefLocalizedString).data;
michael@0 89 } catch(e) {}
michael@0 90
michael@0 91 // Bug 830782 - Homescreen is in English instead of selected locale after
michael@0 92 // the first run experience.
michael@0 93 // In order to ensure the current intl value is reflected on the child
michael@0 94 // process let's always write a user value, even if this one match the
michael@0 95 // current localized pref value.
michael@0 96 if (!((new RegExp('^' + value + '[^a-z-_] *[,;]?', 'i')).test(intl))) {
michael@0 97 value = value + ', ' + intl;
michael@0 98 } else {
michael@0 99 value = intl;
michael@0 100 }
michael@0 101 Services.prefs.setCharPref(prefName, value);
michael@0 102
michael@0 103 if (shell.hasStarted() == false) {
michael@0 104 shell.start();
michael@0 105 }
michael@0 106 });
michael@0 107
michael@0 108 // =================== RIL ====================
michael@0 109 (function RILSettingsToPrefs() {
michael@0 110 let strPrefs = ['ril.mms.mmsc', 'ril.mms.mmsproxy'];
michael@0 111 strPrefs.forEach(function(key) {
michael@0 112 SettingsListener.observe(key, "", function(value) {
michael@0 113 Services.prefs.setCharPref(key, value);
michael@0 114 });
michael@0 115 });
michael@0 116
michael@0 117 ['ril.mms.mmsport'].forEach(function(key) {
michael@0 118 SettingsListener.observe(key, null, function(value) {
michael@0 119 if (value != null) {
michael@0 120 Services.prefs.setIntPref(key, value);
michael@0 121 }
michael@0 122 });
michael@0 123 });
michael@0 124
michael@0 125 // DSDS default service IDs
michael@0 126 ['mms', 'sms', 'telephony', 'voicemail'].forEach(function(key) {
michael@0 127 SettingsListener.observe('ril.' + key + '.defaultServiceId', 0,
michael@0 128 function(value) {
michael@0 129 if (value != null) {
michael@0 130 Services.prefs.setIntPref('dom.' + key + '.defaultServiceId', value);
michael@0 131 }
michael@0 132 });
michael@0 133 });
michael@0 134 })();
michael@0 135
michael@0 136 //=================== DeviceInfo ====================
michael@0 137 Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
michael@0 138 Components.utils.import('resource://gre/modules/ctypes.jsm');
michael@0 139 (function DeviceInfoToSettings() {
michael@0 140 // MOZ_B2G_VERSION is set in b2g/confvars.sh, and is output as a #define value
michael@0 141 // from configure.in, defaults to 1.0.0 if this value is not exist.
michael@0 142 #filter attemptSubstitution
michael@0 143 let os_version = '@MOZ_B2G_VERSION@';
michael@0 144 let os_name = '@MOZ_B2G_OS_NAME@';
michael@0 145 #unfilter attemptSubstitution
michael@0 146
michael@0 147 let appInfo = Cc["@mozilla.org/xre/app-info;1"]
michael@0 148 .getService(Ci.nsIXULAppInfo);
michael@0 149
michael@0 150 // Get the hardware info and firmware revision from device properties.
michael@0 151 let hardware_info = null;
michael@0 152 let firmware_revision = null;
michael@0 153 let product_model = null;
michael@0 154 #ifdef MOZ_WIDGET_GONK
michael@0 155 hardware_info = libcutils.property_get('ro.hardware');
michael@0 156 firmware_revision = libcutils.property_get('ro.firmware_revision');
michael@0 157 product_model = libcutils.property_get('ro.product.model');
michael@0 158 #endif
michael@0 159
michael@0 160 let software = os_name + ' ' + os_version;
michael@0 161 let setting = {
michael@0 162 'deviceinfo.os': os_version,
michael@0 163 'deviceinfo.software': software,
michael@0 164 'deviceinfo.platform_version': appInfo.platformVersion,
michael@0 165 'deviceinfo.platform_build_id': appInfo.platformBuildID,
michael@0 166 'deviceinfo.hardware': hardware_info,
michael@0 167 'deviceinfo.firmware_revision': firmware_revision,
michael@0 168 'deviceinfo.product_model': product_model
michael@0 169 }
michael@0 170 window.navigator.mozSettings.createLock().set(setting);
michael@0 171 })();
michael@0 172
michael@0 173 // =================== DevTools ====================
michael@0 174
michael@0 175 let developerHUD;
michael@0 176 SettingsListener.observe('devtools.overlay', false, (value) => {
michael@0 177 if (value) {
michael@0 178 if (!developerHUD) {
michael@0 179 let scope = {};
michael@0 180 Services.scriptloader.loadSubScript('chrome://b2g/content/devtools.js', scope);
michael@0 181 developerHUD = scope.developerHUD;
michael@0 182 }
michael@0 183 developerHUD.init();
michael@0 184 } else {
michael@0 185 if (developerHUD) {
michael@0 186 developerHUD.uninit();
michael@0 187 }
michael@0 188 }
michael@0 189 });
michael@0 190
michael@0 191 // =================== Debugger / ADB ====================
michael@0 192
michael@0 193 #ifdef MOZ_WIDGET_GONK
michael@0 194 let AdbController = {
michael@0 195 DEBUG: false,
michael@0 196 locked: undefined,
michael@0 197 remoteDebuggerEnabled: undefined,
michael@0 198 lockEnabled: undefined,
michael@0 199 disableAdbTimer: null,
michael@0 200 disableAdbTimeoutHours: 12,
michael@0 201 umsActive: false,
michael@0 202
michael@0 203 debug: function(str) {
michael@0 204 dump("AdbController: " + str + "\n");
michael@0 205 },
michael@0 206
michael@0 207 setLockscreenEnabled: function(value) {
michael@0 208 this.lockEnabled = value;
michael@0 209 if (this.DEBUG) {
michael@0 210 this.debug("setLockscreenEnabled = " + this.lockEnabled);
michael@0 211 }
michael@0 212 this.updateState();
michael@0 213 },
michael@0 214
michael@0 215 setLockscreenState: function(value) {
michael@0 216 this.locked = value;
michael@0 217 if (this.DEBUG) {
michael@0 218 this.debug("setLockscreenState = " + this.locked);
michael@0 219 }
michael@0 220 this.updateState();
michael@0 221 },
michael@0 222
michael@0 223 setRemoteDebuggerState: function(value) {
michael@0 224 this.remoteDebuggerEnabled = value;
michael@0 225 if (this.DEBUG) {
michael@0 226 this.debug("setRemoteDebuggerState = " + this.remoteDebuggerEnabled);
michael@0 227 }
michael@0 228 this.updateState();
michael@0 229 },
michael@0 230
michael@0 231 startDisableAdbTimer: function() {
michael@0 232 if (this.disableAdbTimer) {
michael@0 233 this.disableAdbTimer.cancel();
michael@0 234 } else {
michael@0 235 this.disableAdbTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
michael@0 236 try {
michael@0 237 this.disableAdbTimeoutHours =
michael@0 238 Services.prefs.getIntPref("b2g.adb.timeout-hours");
michael@0 239 } catch (e) {
michael@0 240 // This happens if the pref doesn't exist, in which case
michael@0 241 // disableAdbTimeoutHours will still be set to the default.
michael@0 242 }
michael@0 243 }
michael@0 244 if (this.disableAdbTimeoutHours <= 0) {
michael@0 245 if (this.DEBUG) {
michael@0 246 this.debug("Timer to disable ADB not started due to zero timeout");
michael@0 247 }
michael@0 248 return;
michael@0 249 }
michael@0 250
michael@0 251 if (this.DEBUG) {
michael@0 252 this.debug("Starting timer to disable ADB in " +
michael@0 253 this.disableAdbTimeoutHours + " hours");
michael@0 254 }
michael@0 255 let timeoutMilliseconds = this.disableAdbTimeoutHours * 60 * 60 * 1000;
michael@0 256 this.disableAdbTimer.initWithCallback(this, timeoutMilliseconds,
michael@0 257 Ci.nsITimer.TYPE_ONE_SHOT);
michael@0 258 },
michael@0 259
michael@0 260 stopDisableAdbTimer: function() {
michael@0 261 if (this.DEBUG) {
michael@0 262 this.debug("Stopping timer to disable ADB");
michael@0 263 }
michael@0 264 if (this.disableAdbTimer) {
michael@0 265 this.disableAdbTimer.cancel();
michael@0 266 this.disableAdbTimer = null;
michael@0 267 }
michael@0 268 },
michael@0 269
michael@0 270 notify: function(aTimer) {
michael@0 271 if (aTimer == this.disableAdbTimer) {
michael@0 272 this.disableAdbTimer = null;
michael@0 273 // The following dump will be the last thing that shows up in logcat,
michael@0 274 // and will at least give the user a clue about why logcat was
michael@0 275 // disconnected, if the user happens to be using logcat.
michael@0 276 dump("AdbController: ADB timer expired - disabling ADB\n");
michael@0 277 navigator.mozSettings.createLock().set(
michael@0 278 {'devtools.debugger.remote-enabled': false});
michael@0 279 }
michael@0 280 },
michael@0 281
michael@0 282 updateState: function() {
michael@0 283 this.umsActive = false;
michael@0 284 this.storages = navigator.getDeviceStorages('sdcard');
michael@0 285 this.updateStorageState(0);
michael@0 286 },
michael@0 287
michael@0 288 updateStorageState: function(storageIndex) {
michael@0 289 if (storageIndex >= this.storages.length) {
michael@0 290 // We've iterated through all of the storage objects, now we can
michael@0 291 // really do updateStateInternal.
michael@0 292 this.updateStateInternal();
michael@0 293 return;
michael@0 294 }
michael@0 295 let storage = this.storages[storageIndex];
michael@0 296 if (this.DEBUG) {
michael@0 297 this.debug("Checking availability of storage: '" +
michael@0 298 storage.storageName);
michael@0 299 }
michael@0 300
michael@0 301 let req = storage.available();
michael@0 302 req.onsuccess = function(e) {
michael@0 303 if (this.DEBUG) {
michael@0 304 this.debug("Storage: '" + storage.storageName + "' is '" +
michael@0 305 e.target.result);
michael@0 306 }
michael@0 307 if (e.target.result == 'shared') {
michael@0 308 // We've found a storage area that's being shared with the PC.
michael@0 309 // We can stop looking now.
michael@0 310 this.umsActive = true;
michael@0 311 this.updateStateInternal();
michael@0 312 return;
michael@0 313 }
michael@0 314 this.updateStorageState(storageIndex + 1);
michael@0 315 }.bind(this);
michael@0 316 req.onerror = function(e) {
michael@0 317 dump("AdbController: error querying storage availability for '" +
michael@0 318 this.storages[storageIndex].storageName + "' (ignoring)\n");
michael@0 319 this.updateStorageState(storageIndex + 1);
michael@0 320 }.bind(this);
michael@0 321 },
michael@0 322
michael@0 323 updateStateInternal: function() {
michael@0 324 if (this.DEBUG) {
michael@0 325 this.debug("updateStateInternal: called");
michael@0 326 }
michael@0 327
michael@0 328 if (this.remoteDebuggerEnabled === undefined ||
michael@0 329 this.lockEnabled === undefined ||
michael@0 330 this.locked === undefined) {
michael@0 331 // Part of initializing the settings database will cause the observers
michael@0 332 // to trigger. We want to wait until both have been initialized before
michael@0 333 // we start changing ther adb state. Without this then we can wind up
michael@0 334 // toggling adb off and back on again (or on and back off again).
michael@0 335 //
michael@0 336 // For completeness, one scenario which toggles adb is using the unagi.
michael@0 337 // The unagi has adb enabled by default (prior to b2g starting). If you
michael@0 338 // have the phone lock disabled and remote debugging enabled, then we'll
michael@0 339 // receive an unlock event and an rde event. However at the time we
michael@0 340 // receive the unlock event we haven't yet received the rde event, so
michael@0 341 // we turn adb off momentarily, which disconnects a logcat that might
michael@0 342 // be running. Changing the defaults (in AdbController) just moves the
michael@0 343 // problem to a different phone, which has adb disabled by default and
michael@0 344 // we wind up turning on adb for a short period when we shouldn't.
michael@0 345 //
michael@0 346 // By waiting until both values are properly initialized, we avoid
michael@0 347 // turning adb on or off accidentally.
michael@0 348 if (this.DEBUG) {
michael@0 349 this.debug("updateState: Waiting for all vars to be initialized");
michael@0 350 }
michael@0 351 return;
michael@0 352 }
michael@0 353
michael@0 354 // Check if we have a remote debugging session going on. If so, we won't
michael@0 355 // disable adb even if the screen is locked.
michael@0 356 let isDebugging = RemoteDebugger.isDebugging;
michael@0 357 if (this.DEBUG) {
michael@0 358 this.debug("isDebugging=" + isDebugging);
michael@0 359 }
michael@0 360
michael@0 361 // If USB Mass Storage, USB tethering, or a debug session is active,
michael@0 362 // then we don't want to disable adb in an automatic fashion (i.e.
michael@0 363 // when the screen locks or due to timeout).
michael@0 364 let sysUsbConfig = libcutils.property_get("sys.usb.config");
michael@0 365 let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0);
michael@0 366 let usbFuncActive = rndisActive || this.umsActive || isDebugging;
michael@0 367
michael@0 368 let enableAdb = this.remoteDebuggerEnabled &&
michael@0 369 (!(this.lockEnabled && this.locked) || usbFuncActive);
michael@0 370
michael@0 371 let useDisableAdbTimer = true;
michael@0 372 try {
michael@0 373 if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
michael@0 374 // Marionette is enabled. Marionette requires that adb be on (and also
michael@0 375 // requires that remote debugging be off). The fact that marionette
michael@0 376 // is enabled also implies that we're doing a non-production build, so
michael@0 377 // we want adb enabled all of the time.
michael@0 378 enableAdb = true;
michael@0 379 useDisableAdbTimer = false;
michael@0 380 }
michael@0 381 } catch (e) {
michael@0 382 // This means that the pref doesn't exist. Which is fine. We just leave
michael@0 383 // enableAdb alone.
michael@0 384 }
michael@0 385 if (this.DEBUG) {
michael@0 386 this.debug("updateState: enableAdb = " + enableAdb +
michael@0 387 " remoteDebuggerEnabled = " + this.remoteDebuggerEnabled +
michael@0 388 " lockEnabled = " + this.lockEnabled +
michael@0 389 " locked = " + this.locked +
michael@0 390 " usbFuncActive = " + usbFuncActive);
michael@0 391 }
michael@0 392
michael@0 393 // Configure adb.
michael@0 394 let currentConfig = libcutils.property_get("persist.sys.usb.config");
michael@0 395 let configFuncs = currentConfig.split(",");
michael@0 396 let adbIndex = configFuncs.indexOf("adb");
michael@0 397
michael@0 398 if (enableAdb) {
michael@0 399 // Add adb to the list of functions, if not already present
michael@0 400 if (adbIndex < 0) {
michael@0 401 configFuncs.push("adb");
michael@0 402 }
michael@0 403 } else {
michael@0 404 // Remove adb from the list of functions, if present
michael@0 405 if (adbIndex >= 0) {
michael@0 406 configFuncs.splice(adbIndex, 1);
michael@0 407 }
michael@0 408 }
michael@0 409 let newConfig = configFuncs.join(",");
michael@0 410 if (newConfig != currentConfig) {
michael@0 411 if (this.DEBUG) {
michael@0 412 this.debug("updateState: currentConfig = " + currentConfig);
michael@0 413 this.debug("updateState: newConfig = " + newConfig);
michael@0 414 }
michael@0 415 try {
michael@0 416 libcutils.property_set("persist.sys.usb.config", newConfig);
michael@0 417 } catch(e) {
michael@0 418 dump("Error configuring adb: " + e);
michael@0 419 }
michael@0 420 }
michael@0 421 if (useDisableAdbTimer) {
michael@0 422 if (enableAdb && !usbFuncActive) {
michael@0 423 this.startDisableAdbTimer();
michael@0 424 } else {
michael@0 425 this.stopDisableAdbTimer();
michael@0 426 }
michael@0 427 }
michael@0 428 }
michael@0 429 };
michael@0 430
michael@0 431 SettingsListener.observe("lockscreen.locked", false,
michael@0 432 AdbController.setLockscreenState.bind(AdbController));
michael@0 433 SettingsListener.observe("lockscreen.enabled", false,
michael@0 434 AdbController.setLockscreenEnabled.bind(AdbController));
michael@0 435 #endif
michael@0 436
michael@0 437 // Keep the old setting to not break people that won't have updated
michael@0 438 // gaia and gecko.
michael@0 439 SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) {
michael@0 440 Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value);
michael@0 441 // This preference is consulted during startup
michael@0 442 Services.prefs.savePrefFile(null);
michael@0 443 try {
michael@0 444 value ? RemoteDebugger.start() : RemoteDebugger.stop();
michael@0 445 } catch(e) {
michael@0 446 dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
michael@0 447 }
michael@0 448
michael@0 449 #ifdef MOZ_WIDGET_GONK
michael@0 450 AdbController.setRemoteDebuggerState(value);
michael@0 451 #endif
michael@0 452 });
michael@0 453
michael@0 454 SettingsListener.observe('debugger.remote-mode', false, function(value) {
michael@0 455 if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) {
michael@0 456 dump('Illegal value for debugger.remote-mode: ' + value + '\n');
michael@0 457 return;
michael@0 458 }
michael@0 459
michael@0 460 Services.prefs.setBoolPref('devtools.debugger.remote-enabled',
michael@0 461 value == 'adb-devtools');
michael@0 462 // This preference is consulted during startup
michael@0 463 Services.prefs.savePrefFile(null);
michael@0 464
michael@0 465 try {
michael@0 466 (value == 'adb-devtools') ? RemoteDebugger.start()
michael@0 467 : RemoteDebugger.stop();
michael@0 468 } catch(e) {
michael@0 469 dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n");
michael@0 470 }
michael@0 471
michael@0 472 #ifdef MOZ_WIDGET_GONK
michael@0 473 AdbController.setRemoteDebuggerState(value != 'disabled');
michael@0 474 #endif
michael@0 475 });
michael@0 476
michael@0 477 // =================== Device Storage ====================
michael@0 478 SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
michael@0 479 if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {
michael@0 480 // We clear the pref because it used to be erroneously written as a bool
michael@0 481 // and we need to clear it before we can change it to have the correct type.
michael@0 482 Services.prefs.clearUserPref('device.storage.writable.name');
michael@0 483 }
michael@0 484 Services.prefs.setCharPref('device.storage.writable.name', value);
michael@0 485 });
michael@0 486
michael@0 487 // =================== Privacy ====================
michael@0 488 SettingsListener.observe('privacy.donottrackheader.value', 1, function(value) {
michael@0 489 Services.prefs.setIntPref('privacy.donottrackheader.value', value);
michael@0 490 // If the user specifically disallows tracking, we set the value of
michael@0 491 // app.update.custom (update tracking ID) to an empty string.
michael@0 492 if (value == 1) {
michael@0 493 Services.prefs.setCharPref('app.update.custom', '');
michael@0 494 return;
michael@0 495 }
michael@0 496 // Otherwise, we assure that the update tracking ID exists.
michael@0 497 setUpdateTrackingId();
michael@0 498 });
michael@0 499
michael@0 500 // =================== Crash Reporting ====================
michael@0 501 SettingsListener.observe('app.reportCrashes', 'ask', function(value) {
michael@0 502 if (value == 'always') {
michael@0 503 Services.prefs.setBoolPref('app.reportCrashes', true);
michael@0 504 } else if (value == 'never') {
michael@0 505 Services.prefs.setBoolPref('app.reportCrashes', false);
michael@0 506 } else {
michael@0 507 Services.prefs.clearUserPref('app.reportCrashes');
michael@0 508 }
michael@0 509 // This preference is consulted during startup.
michael@0 510 Services.prefs.savePrefFile(null);
michael@0 511 });
michael@0 512
michael@0 513 // ================ Updates ================
michael@0 514 /**
michael@0 515 * For tracking purposes some partners require us to add an UUID to the
michael@0 516 * update URL. The update tracking ID will be an empty string if the
michael@0 517 * do-not-track feature specifically disallows tracking and it is reseted
michael@0 518 * to a different ID if the do-not-track value changes from disallow to allow.
michael@0 519 */
michael@0 520 function setUpdateTrackingId() {
michael@0 521 try {
michael@0 522 let dntEnabled = Services.prefs.getBoolPref('privacy.donottrackheader.enabled');
michael@0 523 let dntValue = Services.prefs.getIntPref('privacy.donottrackheader.value');
michael@0 524 // If the user specifically decides to disallow tracking (1), we just bail out.
michael@0 525 if (dntEnabled && (dntValue == 1)) {
michael@0 526 return;
michael@0 527 }
michael@0 528
michael@0 529 let trackingId =
michael@0 530 Services.prefs.getPrefType('app.update.custom') ==
michael@0 531 Ci.nsIPrefBranch.PREF_STRING &&
michael@0 532 Services.prefs.getCharPref('app.update.custom');
michael@0 533
michael@0 534 // If there is no previous registered tracking ID, we generate a new one.
michael@0 535 // This should only happen on first usage or after changing the
michael@0 536 // do-not-track value from disallow to allow.
michael@0 537 if (!trackingId) {
michael@0 538 trackingId = uuidgen.generateUUID().toString().replace(/[{}]/g, "");
michael@0 539 Services.prefs.setCharPref('app.update.custom', trackingId);
michael@0 540 }
michael@0 541 } catch(e) {
michael@0 542 dump('Error getting tracking ID ' + e + '\n');
michael@0 543 }
michael@0 544 }
michael@0 545 setUpdateTrackingId();
michael@0 546
michael@0 547
michael@0 548 // ================ Debug ================
michael@0 549 (function Composer2DSettingToPref() {
michael@0 550 //layers.composer.enabled can be enabled in three ways
michael@0 551 //In order of precedence they are:
michael@0 552 //
michael@0 553 //1. mozSettings "layers.composer.enabled"
michael@0 554 //2. a gecko pref "layers.composer.enabled"
michael@0 555 //3. presence of ro.display.colorfill at the Gonk level
michael@0 556
michael@0 557 var req = navigator.mozSettings.createLock().get('layers.composer2d.enabled');
michael@0 558 req.onsuccess = function() {
michael@0 559 if (typeof(req.result['layers.composer2d.enabled']) === 'undefined') {
michael@0 560 var enabled = false;
michael@0 561 if (Services.prefs.getPrefType('layers.composer2d.enabled') == Ci.nsIPrefBranch.PREF_BOOL) {
michael@0 562 enabled = Services.prefs.getBoolPref('layers.composer2d.enabled');
michael@0 563 } else {
michael@0 564 #ifdef MOZ_WIDGET_GONK
michael@0 565 enabled = (libcutils.property_get('ro.display.colorfill') === '1');
michael@0 566 #endif
michael@0 567 }
michael@0 568 navigator.mozSettings.createLock().set({'layers.composer2d.enabled': enabled });
michael@0 569 }
michael@0 570
michael@0 571 SettingsListener.observe("layers.composer2d.enabled", true, function(value) {
michael@0 572 Services.prefs.setBoolPref("layers.composer2d.enabled", value);
michael@0 573 });
michael@0 574 };
michael@0 575 req.onerror = function() {
michael@0 576 dump("Error configuring layers.composer2d.enabled setting");
michael@0 577 };
michael@0 578
michael@0 579 })();
michael@0 580
michael@0 581 // ================ Accessibility ============
michael@0 582 SettingsListener.observe("accessibility.screenreader", false, function(value) {
michael@0 583 if (value && !("AccessFu" in this)) {
michael@0 584 Cu.import('resource://gre/modules/accessibility/AccessFu.jsm');
michael@0 585 AccessFu.attach(window);
michael@0 586 }
michael@0 587 });
michael@0 588
michael@0 589 // ================ Theming ============
michael@0 590 (function themingSettingsListener() {
michael@0 591 let themingPrefs = ['ui.menu', 'ui.menutext', 'ui.infobackground', 'ui.infotext',
michael@0 592 'ui.window', 'ui.windowtext', 'ui.highlight'];
michael@0 593
michael@0 594 themingPrefs.forEach(function(pref) {
michael@0 595 SettingsListener.observe('gaia.' + pref, null, function(value) {
michael@0 596 if (value) {
michael@0 597 Services.prefs.setCharPref(pref, value);
michael@0 598 }
michael@0 599 });
michael@0 600 });
michael@0 601 })();
michael@0 602
michael@0 603 // =================== AsyncPanZoom ======================
michael@0 604 SettingsListener.observe('apz.displayport.heuristics', 'default', function(value) {
michael@0 605 // first reset everything to default
michael@0 606 Services.prefs.clearUserPref('apz.velocity_bias');
michael@0 607 Services.prefs.clearUserPref('apz.use_paint_duration');
michael@0 608 Services.prefs.clearUserPref('apz.x_skate_size_multiplier');
michael@0 609 Services.prefs.clearUserPref('apz.y_skate_size_multiplier');
michael@0 610 Services.prefs.clearUserPref('apz.allow-checkerboarding');
michael@0 611 // and then set the things that we want to change
michael@0 612 switch (value) {
michael@0 613 case 'default':
michael@0 614 break;
michael@0 615 case 'center-displayport':
michael@0 616 Services.prefs.setCharPref('apz.velocity_bias', '0.0');
michael@0 617 break;
michael@0 618 case 'perfect-paint-times':
michael@0 619 Services.prefs.setBoolPref('apz.use_paint_duration', false);
michael@0 620 Services.prefs.setCharPref('apz.velocity_bias', '0.32'); // 16/50 (assumes 16ms paint times instead of 50ms)
michael@0 621 break;
michael@0 622 case 'taller-displayport':
michael@0 623 Services.prefs.setCharPref('apz.y_skate_size_multiplier', '3.5');
michael@0 624 break;
michael@0 625 case 'faster-paint':
michael@0 626 Services.prefs.setCharPref('apz.x_skate_size_multiplier', '1.0');
michael@0 627 Services.prefs.setCharPref('apz.y_skate_size_multiplier', '1.5');
michael@0 628 break;
michael@0 629 case 'no-checkerboard':
michael@0 630 Services.prefs.setBoolPref('apz.allow-checkerboarding', false);
michael@0 631 break;
michael@0 632 }
michael@0 633 });
michael@0 634
michael@0 635 // =================== Various simple mapping ======================
michael@0 636 let settingsToObserve = {
michael@0 637 'ril.mms.retrieval_mode': {
michael@0 638 prefName: 'dom.mms.retrieval_mode',
michael@0 639 defaultValue: 'manual'
michael@0 640 },
michael@0 641 'ril.sms.strict7BitEncoding.enabled': {
michael@0 642 prefName: 'dom.sms.strict7BitEncoding',
michael@0 643 defaultValue: false
michael@0 644 },
michael@0 645 'ril.sms.requestStatusReport.enabled': {
michael@0 646 prefName: 'dom.sms.requestStatusReport',
michael@0 647 defaultValue: false
michael@0 648 },
michael@0 649 'ril.mms.requestStatusReport.enabled': {
michael@0 650 prefName: 'dom.mms.requestStatusReport',
michael@0 651 defaultValue: false
michael@0 652 },
michael@0 653 'ril.mms.requestReadReport.enabled': {
michael@0 654 prefName: 'dom.mms.requestReadReport',
michael@0 655 defaultValue: true
michael@0 656 },
michael@0 657 'ril.cellbroadcast.disabled': false,
michael@0 658 'ril.radio.disabled': false,
michael@0 659 'wap.UAProf.url': '',
michael@0 660 'wap.UAProf.tagname': 'x-wap-profile',
michael@0 661 'devtools.eventlooplag.threshold': 100,
michael@0 662 'privacy.donottrackheader.enabled': false,
michael@0 663 'apz.force-enable': {
michael@0 664 prefName: 'dom.browser_frames.useAsyncPanZoom',
michael@0 665 defaultValue: false
michael@0 666 },
michael@0 667 'layers.enable-tiles': true,
michael@0 668 'layers.simple-tiles': false,
michael@0 669 'layers.progressive-paint': false,
michael@0 670 'layers.draw-tile-borders': false,
michael@0 671 'layers.dump': false,
michael@0 672 'debug.fps.enabled': {
michael@0 673 prefName: 'layers.acceleration.draw-fps',
michael@0 674 defaultValue: false
michael@0 675 },
michael@0 676 'debug.paint-flashing.enabled': {
michael@0 677 prefName: 'nglayout.debug.paint_flashing',
michael@0 678 defaultValue: false
michael@0 679 },
michael@0 680 'layers.draw-borders': false,
michael@0 681 'app.update.interval': 86400,
michael@0 682 'app.update.url': {
michael@0 683 resetToPref: true
michael@0 684 },
michael@0 685 'app.update.channel': {
michael@0 686 resetToPref: true
michael@0 687 },
michael@0 688 'debug.log-animations.enabled': {
michael@0 689 prefName: 'layers.offmainthreadcomposition.log-animations',
michael@0 690 defaultValue: false
michael@0 691 }
michael@0 692 };
michael@0 693
michael@0 694 for (let key in settingsToObserve) {
michael@0 695 let setting = settingsToObserve[key];
michael@0 696
michael@0 697 // Allow setting to contain flags redefining prefName and defaultValue.
michael@0 698 let prefName = setting.prefName || key;
michael@0 699 let defaultValue = setting.defaultValue;
michael@0 700 if (defaultValue === undefined) {
michael@0 701 defaultValue = setting;
michael@0 702 }
michael@0 703
michael@0 704 let prefs = Services.prefs;
michael@0 705
michael@0 706 // If requested, reset setting value and defaultValue to the pref value.
michael@0 707 if (setting.resetToPref) {
michael@0 708 switch (prefs.getPrefType(prefName)) {
michael@0 709 case Ci.nsIPrefBranch.PREF_BOOL:
michael@0 710 defaultValue = prefs.getBoolPref(prefName);
michael@0 711 break;
michael@0 712
michael@0 713 case Ci.nsIPrefBranch.PREF_INT:
michael@0 714 defaultValue = prefs.getIntPref(prefName);
michael@0 715 break;
michael@0 716
michael@0 717 case Ci.nsIPrefBranch.PREF_STRING:
michael@0 718 defaultValue = prefs.getCharPref(prefName);
michael@0 719 break;
michael@0 720 }
michael@0 721
michael@0 722 let setting = {};
michael@0 723 setting[key] = defaultValue;
michael@0 724 window.navigator.mozSettings.createLock().set(setting);
michael@0 725 }
michael@0 726
michael@0 727 // Figure out the right setter function for this type of pref.
michael@0 728 let setPref;
michael@0 729 switch (typeof defaultValue) {
michael@0 730 case 'boolean':
michael@0 731 setPref = prefs.setBoolPref.bind(prefs);
michael@0 732 break;
michael@0 733
michael@0 734 case 'number':
michael@0 735 setPref = prefs.setIntPref.bind(prefs);
michael@0 736 break;
michael@0 737
michael@0 738 case 'string':
michael@0 739 setPref = prefs.setCharPref.bind(prefs);
michael@0 740 break;
michael@0 741 }
michael@0 742
michael@0 743 SettingsListener.observe(key, defaultValue, function(value) {
michael@0 744 setPref(prefName, value);
michael@0 745 });
michael@0 746 };
michael@0 747

mercurial