1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/b2g/chrome/content/settings.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,747 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / 1.5 +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +"use strict;" 1.11 + 1.12 +const Cc = Components.classes; 1.13 +const Ci = Components.interfaces; 1.14 +const Cu = Components.utils; 1.15 +const Cr = Components.results; 1.16 + 1.17 +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); 1.18 +Cu.import('resource://gre/modules/Services.jsm'); 1.19 + 1.20 +#ifdef MOZ_WIDGET_GONK 1.21 +XPCOMUtils.defineLazyGetter(this, "libcutils", function () { 1.22 + Cu.import("resource://gre/modules/systemlibs.js"); 1.23 + return libcutils; 1.24 +}); 1.25 +#endif 1.26 + 1.27 +XPCOMUtils.defineLazyServiceGetter(this, "uuidgen", 1.28 + "@mozilla.org/uuid-generator;1", 1.29 + "nsIUUIDGenerator"); 1.30 + 1.31 +// Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget 1.32 +// is resolved this helper could be removed. 1.33 +var SettingsListener = { 1.34 + _callbacks: {}, 1.35 + 1.36 + init: function sl_init() { 1.37 + if ('mozSettings' in navigator && navigator.mozSettings) { 1.38 + navigator.mozSettings.onsettingchange = this.onchange.bind(this); 1.39 + } 1.40 + }, 1.41 + 1.42 + onchange: function sl_onchange(evt) { 1.43 + var callback = this._callbacks[evt.settingName]; 1.44 + if (callback) { 1.45 + callback(evt.settingValue); 1.46 + } 1.47 + }, 1.48 + 1.49 + observe: function sl_observe(name, defaultValue, callback) { 1.50 + var settings = window.navigator.mozSettings; 1.51 + if (!settings) { 1.52 + window.setTimeout(function() { callback(defaultValue); }); 1.53 + return; 1.54 + } 1.55 + 1.56 + if (!callback || typeof callback !== 'function') { 1.57 + throw new Error('Callback is not a function'); 1.58 + } 1.59 + 1.60 + var req = settings.createLock().get(name); 1.61 + req.addEventListener('success', (function onsuccess() { 1.62 + callback(typeof(req.result[name]) != 'undefined' ? 1.63 + req.result[name] : defaultValue); 1.64 + })); 1.65 + 1.66 + this._callbacks[name] = callback; 1.67 + } 1.68 +}; 1.69 + 1.70 +SettingsListener.init(); 1.71 + 1.72 +// =================== Console ====================== 1.73 + 1.74 +SettingsListener.observe('debug.console.enabled', true, function(value) { 1.75 + Services.prefs.setBoolPref('consoleservice.enabled', value); 1.76 + Services.prefs.setBoolPref('layout.css.report_errors', value); 1.77 +}); 1.78 + 1.79 +// =================== Languages ==================== 1.80 +SettingsListener.observe('language.current', 'en-US', function(value) { 1.81 + Services.prefs.setCharPref('general.useragent.locale', value); 1.82 + 1.83 + let prefName = 'intl.accept_languages'; 1.84 + if (Services.prefs.prefHasUserValue(prefName)) { 1.85 + Services.prefs.clearUserPref(prefName); 1.86 + } 1.87 + 1.88 + let intl = ''; 1.89 + try { 1.90 + intl = Services.prefs.getComplexValue(prefName, 1.91 + Ci.nsIPrefLocalizedString).data; 1.92 + } catch(e) {} 1.93 + 1.94 + // Bug 830782 - Homescreen is in English instead of selected locale after 1.95 + // the first run experience. 1.96 + // In order to ensure the current intl value is reflected on the child 1.97 + // process let's always write a user value, even if this one match the 1.98 + // current localized pref value. 1.99 + if (!((new RegExp('^' + value + '[^a-z-_] *[,;]?', 'i')).test(intl))) { 1.100 + value = value + ', ' + intl; 1.101 + } else { 1.102 + value = intl; 1.103 + } 1.104 + Services.prefs.setCharPref(prefName, value); 1.105 + 1.106 + if (shell.hasStarted() == false) { 1.107 + shell.start(); 1.108 + } 1.109 +}); 1.110 + 1.111 +// =================== RIL ==================== 1.112 +(function RILSettingsToPrefs() { 1.113 + let strPrefs = ['ril.mms.mmsc', 'ril.mms.mmsproxy']; 1.114 + strPrefs.forEach(function(key) { 1.115 + SettingsListener.observe(key, "", function(value) { 1.116 + Services.prefs.setCharPref(key, value); 1.117 + }); 1.118 + }); 1.119 + 1.120 + ['ril.mms.mmsport'].forEach(function(key) { 1.121 + SettingsListener.observe(key, null, function(value) { 1.122 + if (value != null) { 1.123 + Services.prefs.setIntPref(key, value); 1.124 + } 1.125 + }); 1.126 + }); 1.127 + 1.128 + // DSDS default service IDs 1.129 + ['mms', 'sms', 'telephony', 'voicemail'].forEach(function(key) { 1.130 + SettingsListener.observe('ril.' + key + '.defaultServiceId', 0, 1.131 + function(value) { 1.132 + if (value != null) { 1.133 + Services.prefs.setIntPref('dom.' + key + '.defaultServiceId', value); 1.134 + } 1.135 + }); 1.136 + }); 1.137 +})(); 1.138 + 1.139 +//=================== DeviceInfo ==================== 1.140 +Components.utils.import('resource://gre/modules/XPCOMUtils.jsm'); 1.141 +Components.utils.import('resource://gre/modules/ctypes.jsm'); 1.142 +(function DeviceInfoToSettings() { 1.143 + // MOZ_B2G_VERSION is set in b2g/confvars.sh, and is output as a #define value 1.144 + // from configure.in, defaults to 1.0.0 if this value is not exist. 1.145 +#filter attemptSubstitution 1.146 + let os_version = '@MOZ_B2G_VERSION@'; 1.147 + let os_name = '@MOZ_B2G_OS_NAME@'; 1.148 +#unfilter attemptSubstitution 1.149 + 1.150 + let appInfo = Cc["@mozilla.org/xre/app-info;1"] 1.151 + .getService(Ci.nsIXULAppInfo); 1.152 + 1.153 + // Get the hardware info and firmware revision from device properties. 1.154 + let hardware_info = null; 1.155 + let firmware_revision = null; 1.156 + let product_model = null; 1.157 +#ifdef MOZ_WIDGET_GONK 1.158 + hardware_info = libcutils.property_get('ro.hardware'); 1.159 + firmware_revision = libcutils.property_get('ro.firmware_revision'); 1.160 + product_model = libcutils.property_get('ro.product.model'); 1.161 +#endif 1.162 + 1.163 + let software = os_name + ' ' + os_version; 1.164 + let setting = { 1.165 + 'deviceinfo.os': os_version, 1.166 + 'deviceinfo.software': software, 1.167 + 'deviceinfo.platform_version': appInfo.platformVersion, 1.168 + 'deviceinfo.platform_build_id': appInfo.platformBuildID, 1.169 + 'deviceinfo.hardware': hardware_info, 1.170 + 'deviceinfo.firmware_revision': firmware_revision, 1.171 + 'deviceinfo.product_model': product_model 1.172 + } 1.173 + window.navigator.mozSettings.createLock().set(setting); 1.174 +})(); 1.175 + 1.176 +// =================== DevTools ==================== 1.177 + 1.178 +let developerHUD; 1.179 +SettingsListener.observe('devtools.overlay', false, (value) => { 1.180 + if (value) { 1.181 + if (!developerHUD) { 1.182 + let scope = {}; 1.183 + Services.scriptloader.loadSubScript('chrome://b2g/content/devtools.js', scope); 1.184 + developerHUD = scope.developerHUD; 1.185 + } 1.186 + developerHUD.init(); 1.187 + } else { 1.188 + if (developerHUD) { 1.189 + developerHUD.uninit(); 1.190 + } 1.191 + } 1.192 +}); 1.193 + 1.194 +// =================== Debugger / ADB ==================== 1.195 + 1.196 +#ifdef MOZ_WIDGET_GONK 1.197 +let AdbController = { 1.198 + DEBUG: false, 1.199 + locked: undefined, 1.200 + remoteDebuggerEnabled: undefined, 1.201 + lockEnabled: undefined, 1.202 + disableAdbTimer: null, 1.203 + disableAdbTimeoutHours: 12, 1.204 + umsActive: false, 1.205 + 1.206 + debug: function(str) { 1.207 + dump("AdbController: " + str + "\n"); 1.208 + }, 1.209 + 1.210 + setLockscreenEnabled: function(value) { 1.211 + this.lockEnabled = value; 1.212 + if (this.DEBUG) { 1.213 + this.debug("setLockscreenEnabled = " + this.lockEnabled); 1.214 + } 1.215 + this.updateState(); 1.216 + }, 1.217 + 1.218 + setLockscreenState: function(value) { 1.219 + this.locked = value; 1.220 + if (this.DEBUG) { 1.221 + this.debug("setLockscreenState = " + this.locked); 1.222 + } 1.223 + this.updateState(); 1.224 + }, 1.225 + 1.226 + setRemoteDebuggerState: function(value) { 1.227 + this.remoteDebuggerEnabled = value; 1.228 + if (this.DEBUG) { 1.229 + this.debug("setRemoteDebuggerState = " + this.remoteDebuggerEnabled); 1.230 + } 1.231 + this.updateState(); 1.232 + }, 1.233 + 1.234 + startDisableAdbTimer: function() { 1.235 + if (this.disableAdbTimer) { 1.236 + this.disableAdbTimer.cancel(); 1.237 + } else { 1.238 + this.disableAdbTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 1.239 + try { 1.240 + this.disableAdbTimeoutHours = 1.241 + Services.prefs.getIntPref("b2g.adb.timeout-hours"); 1.242 + } catch (e) { 1.243 + // This happens if the pref doesn't exist, in which case 1.244 + // disableAdbTimeoutHours will still be set to the default. 1.245 + } 1.246 + } 1.247 + if (this.disableAdbTimeoutHours <= 0) { 1.248 + if (this.DEBUG) { 1.249 + this.debug("Timer to disable ADB not started due to zero timeout"); 1.250 + } 1.251 + return; 1.252 + } 1.253 + 1.254 + if (this.DEBUG) { 1.255 + this.debug("Starting timer to disable ADB in " + 1.256 + this.disableAdbTimeoutHours + " hours"); 1.257 + } 1.258 + let timeoutMilliseconds = this.disableAdbTimeoutHours * 60 * 60 * 1000; 1.259 + this.disableAdbTimer.initWithCallback(this, timeoutMilliseconds, 1.260 + Ci.nsITimer.TYPE_ONE_SHOT); 1.261 + }, 1.262 + 1.263 + stopDisableAdbTimer: function() { 1.264 + if (this.DEBUG) { 1.265 + this.debug("Stopping timer to disable ADB"); 1.266 + } 1.267 + if (this.disableAdbTimer) { 1.268 + this.disableAdbTimer.cancel(); 1.269 + this.disableAdbTimer = null; 1.270 + } 1.271 + }, 1.272 + 1.273 + notify: function(aTimer) { 1.274 + if (aTimer == this.disableAdbTimer) { 1.275 + this.disableAdbTimer = null; 1.276 + // The following dump will be the last thing that shows up in logcat, 1.277 + // and will at least give the user a clue about why logcat was 1.278 + // disconnected, if the user happens to be using logcat. 1.279 + dump("AdbController: ADB timer expired - disabling ADB\n"); 1.280 + navigator.mozSettings.createLock().set( 1.281 + {'devtools.debugger.remote-enabled': false}); 1.282 + } 1.283 + }, 1.284 + 1.285 + updateState: function() { 1.286 + this.umsActive = false; 1.287 + this.storages = navigator.getDeviceStorages('sdcard'); 1.288 + this.updateStorageState(0); 1.289 + }, 1.290 + 1.291 + updateStorageState: function(storageIndex) { 1.292 + if (storageIndex >= this.storages.length) { 1.293 + // We've iterated through all of the storage objects, now we can 1.294 + // really do updateStateInternal. 1.295 + this.updateStateInternal(); 1.296 + return; 1.297 + } 1.298 + let storage = this.storages[storageIndex]; 1.299 + if (this.DEBUG) { 1.300 + this.debug("Checking availability of storage: '" + 1.301 + storage.storageName); 1.302 + } 1.303 + 1.304 + let req = storage.available(); 1.305 + req.onsuccess = function(e) { 1.306 + if (this.DEBUG) { 1.307 + this.debug("Storage: '" + storage.storageName + "' is '" + 1.308 + e.target.result); 1.309 + } 1.310 + if (e.target.result == 'shared') { 1.311 + // We've found a storage area that's being shared with the PC. 1.312 + // We can stop looking now. 1.313 + this.umsActive = true; 1.314 + this.updateStateInternal(); 1.315 + return; 1.316 + } 1.317 + this.updateStorageState(storageIndex + 1); 1.318 + }.bind(this); 1.319 + req.onerror = function(e) { 1.320 + dump("AdbController: error querying storage availability for '" + 1.321 + this.storages[storageIndex].storageName + "' (ignoring)\n"); 1.322 + this.updateStorageState(storageIndex + 1); 1.323 + }.bind(this); 1.324 + }, 1.325 + 1.326 + updateStateInternal: function() { 1.327 + if (this.DEBUG) { 1.328 + this.debug("updateStateInternal: called"); 1.329 + } 1.330 + 1.331 + if (this.remoteDebuggerEnabled === undefined || 1.332 + this.lockEnabled === undefined || 1.333 + this.locked === undefined) { 1.334 + // Part of initializing the settings database will cause the observers 1.335 + // to trigger. We want to wait until both have been initialized before 1.336 + // we start changing ther adb state. Without this then we can wind up 1.337 + // toggling adb off and back on again (or on and back off again). 1.338 + // 1.339 + // For completeness, one scenario which toggles adb is using the unagi. 1.340 + // The unagi has adb enabled by default (prior to b2g starting). If you 1.341 + // have the phone lock disabled and remote debugging enabled, then we'll 1.342 + // receive an unlock event and an rde event. However at the time we 1.343 + // receive the unlock event we haven't yet received the rde event, so 1.344 + // we turn adb off momentarily, which disconnects a logcat that might 1.345 + // be running. Changing the defaults (in AdbController) just moves the 1.346 + // problem to a different phone, which has adb disabled by default and 1.347 + // we wind up turning on adb for a short period when we shouldn't. 1.348 + // 1.349 + // By waiting until both values are properly initialized, we avoid 1.350 + // turning adb on or off accidentally. 1.351 + if (this.DEBUG) { 1.352 + this.debug("updateState: Waiting for all vars to be initialized"); 1.353 + } 1.354 + return; 1.355 + } 1.356 + 1.357 + // Check if we have a remote debugging session going on. If so, we won't 1.358 + // disable adb even if the screen is locked. 1.359 + let isDebugging = RemoteDebugger.isDebugging; 1.360 + if (this.DEBUG) { 1.361 + this.debug("isDebugging=" + isDebugging); 1.362 + } 1.363 + 1.364 + // If USB Mass Storage, USB tethering, or a debug session is active, 1.365 + // then we don't want to disable adb in an automatic fashion (i.e. 1.366 + // when the screen locks or due to timeout). 1.367 + let sysUsbConfig = libcutils.property_get("sys.usb.config"); 1.368 + let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0); 1.369 + let usbFuncActive = rndisActive || this.umsActive || isDebugging; 1.370 + 1.371 + let enableAdb = this.remoteDebuggerEnabled && 1.372 + (!(this.lockEnabled && this.locked) || usbFuncActive); 1.373 + 1.374 + let useDisableAdbTimer = true; 1.375 + try { 1.376 + if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) { 1.377 + // Marionette is enabled. Marionette requires that adb be on (and also 1.378 + // requires that remote debugging be off). The fact that marionette 1.379 + // is enabled also implies that we're doing a non-production build, so 1.380 + // we want adb enabled all of the time. 1.381 + enableAdb = true; 1.382 + useDisableAdbTimer = false; 1.383 + } 1.384 + } catch (e) { 1.385 + // This means that the pref doesn't exist. Which is fine. We just leave 1.386 + // enableAdb alone. 1.387 + } 1.388 + if (this.DEBUG) { 1.389 + this.debug("updateState: enableAdb = " + enableAdb + 1.390 + " remoteDebuggerEnabled = " + this.remoteDebuggerEnabled + 1.391 + " lockEnabled = " + this.lockEnabled + 1.392 + " locked = " + this.locked + 1.393 + " usbFuncActive = " + usbFuncActive); 1.394 + } 1.395 + 1.396 + // Configure adb. 1.397 + let currentConfig = libcutils.property_get("persist.sys.usb.config"); 1.398 + let configFuncs = currentConfig.split(","); 1.399 + let adbIndex = configFuncs.indexOf("adb"); 1.400 + 1.401 + if (enableAdb) { 1.402 + // Add adb to the list of functions, if not already present 1.403 + if (adbIndex < 0) { 1.404 + configFuncs.push("adb"); 1.405 + } 1.406 + } else { 1.407 + // Remove adb from the list of functions, if present 1.408 + if (adbIndex >= 0) { 1.409 + configFuncs.splice(adbIndex, 1); 1.410 + } 1.411 + } 1.412 + let newConfig = configFuncs.join(","); 1.413 + if (newConfig != currentConfig) { 1.414 + if (this.DEBUG) { 1.415 + this.debug("updateState: currentConfig = " + currentConfig); 1.416 + this.debug("updateState: newConfig = " + newConfig); 1.417 + } 1.418 + try { 1.419 + libcutils.property_set("persist.sys.usb.config", newConfig); 1.420 + } catch(e) { 1.421 + dump("Error configuring adb: " + e); 1.422 + } 1.423 + } 1.424 + if (useDisableAdbTimer) { 1.425 + if (enableAdb && !usbFuncActive) { 1.426 + this.startDisableAdbTimer(); 1.427 + } else { 1.428 + this.stopDisableAdbTimer(); 1.429 + } 1.430 + } 1.431 + } 1.432 +}; 1.433 + 1.434 +SettingsListener.observe("lockscreen.locked", false, 1.435 + AdbController.setLockscreenState.bind(AdbController)); 1.436 +SettingsListener.observe("lockscreen.enabled", false, 1.437 + AdbController.setLockscreenEnabled.bind(AdbController)); 1.438 +#endif 1.439 + 1.440 +// Keep the old setting to not break people that won't have updated 1.441 +// gaia and gecko. 1.442 +SettingsListener.observe('devtools.debugger.remote-enabled', false, function(value) { 1.443 + Services.prefs.setBoolPref('devtools.debugger.remote-enabled', value); 1.444 + // This preference is consulted during startup 1.445 + Services.prefs.savePrefFile(null); 1.446 + try { 1.447 + value ? RemoteDebugger.start() : RemoteDebugger.stop(); 1.448 + } catch(e) { 1.449 + dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n"); 1.450 + } 1.451 + 1.452 +#ifdef MOZ_WIDGET_GONK 1.453 + AdbController.setRemoteDebuggerState(value); 1.454 +#endif 1.455 +}); 1.456 + 1.457 +SettingsListener.observe('debugger.remote-mode', false, function(value) { 1.458 + if (['disabled', 'adb-only', 'adb-devtools'].indexOf(value) == -1) { 1.459 + dump('Illegal value for debugger.remote-mode: ' + value + '\n'); 1.460 + return; 1.461 + } 1.462 + 1.463 + Services.prefs.setBoolPref('devtools.debugger.remote-enabled', 1.464 + value == 'adb-devtools'); 1.465 + // This preference is consulted during startup 1.466 + Services.prefs.savePrefFile(null); 1.467 + 1.468 + try { 1.469 + (value == 'adb-devtools') ? RemoteDebugger.start() 1.470 + : RemoteDebugger.stop(); 1.471 + } catch(e) { 1.472 + dump("Error while initializing devtools: " + e + "\n" + e.stack + "\n"); 1.473 + } 1.474 + 1.475 +#ifdef MOZ_WIDGET_GONK 1.476 + AdbController.setRemoteDebuggerState(value != 'disabled'); 1.477 +#endif 1.478 +}); 1.479 + 1.480 +// =================== Device Storage ==================== 1.481 +SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) { 1.482 + if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) { 1.483 + // We clear the pref because it used to be erroneously written as a bool 1.484 + // and we need to clear it before we can change it to have the correct type. 1.485 + Services.prefs.clearUserPref('device.storage.writable.name'); 1.486 + } 1.487 + Services.prefs.setCharPref('device.storage.writable.name', value); 1.488 +}); 1.489 + 1.490 +// =================== Privacy ==================== 1.491 +SettingsListener.observe('privacy.donottrackheader.value', 1, function(value) { 1.492 + Services.prefs.setIntPref('privacy.donottrackheader.value', value); 1.493 + // If the user specifically disallows tracking, we set the value of 1.494 + // app.update.custom (update tracking ID) to an empty string. 1.495 + if (value == 1) { 1.496 + Services.prefs.setCharPref('app.update.custom', ''); 1.497 + return; 1.498 + } 1.499 + // Otherwise, we assure that the update tracking ID exists. 1.500 + setUpdateTrackingId(); 1.501 +}); 1.502 + 1.503 +// =================== Crash Reporting ==================== 1.504 +SettingsListener.observe('app.reportCrashes', 'ask', function(value) { 1.505 + if (value == 'always') { 1.506 + Services.prefs.setBoolPref('app.reportCrashes', true); 1.507 + } else if (value == 'never') { 1.508 + Services.prefs.setBoolPref('app.reportCrashes', false); 1.509 + } else { 1.510 + Services.prefs.clearUserPref('app.reportCrashes'); 1.511 + } 1.512 + // This preference is consulted during startup. 1.513 + Services.prefs.savePrefFile(null); 1.514 +}); 1.515 + 1.516 +// ================ Updates ================ 1.517 +/** 1.518 + * For tracking purposes some partners require us to add an UUID to the 1.519 + * update URL. The update tracking ID will be an empty string if the 1.520 + * do-not-track feature specifically disallows tracking and it is reseted 1.521 + * to a different ID if the do-not-track value changes from disallow to allow. 1.522 + */ 1.523 +function setUpdateTrackingId() { 1.524 + try { 1.525 + let dntEnabled = Services.prefs.getBoolPref('privacy.donottrackheader.enabled'); 1.526 + let dntValue = Services.prefs.getIntPref('privacy.donottrackheader.value'); 1.527 + // If the user specifically decides to disallow tracking (1), we just bail out. 1.528 + if (dntEnabled && (dntValue == 1)) { 1.529 + return; 1.530 + } 1.531 + 1.532 + let trackingId = 1.533 + Services.prefs.getPrefType('app.update.custom') == 1.534 + Ci.nsIPrefBranch.PREF_STRING && 1.535 + Services.prefs.getCharPref('app.update.custom'); 1.536 + 1.537 + // If there is no previous registered tracking ID, we generate a new one. 1.538 + // This should only happen on first usage or after changing the 1.539 + // do-not-track value from disallow to allow. 1.540 + if (!trackingId) { 1.541 + trackingId = uuidgen.generateUUID().toString().replace(/[{}]/g, ""); 1.542 + Services.prefs.setCharPref('app.update.custom', trackingId); 1.543 + } 1.544 + } catch(e) { 1.545 + dump('Error getting tracking ID ' + e + '\n'); 1.546 + } 1.547 +} 1.548 +setUpdateTrackingId(); 1.549 + 1.550 + 1.551 +// ================ Debug ================ 1.552 +(function Composer2DSettingToPref() { 1.553 + //layers.composer.enabled can be enabled in three ways 1.554 + //In order of precedence they are: 1.555 + // 1.556 + //1. mozSettings "layers.composer.enabled" 1.557 + //2. a gecko pref "layers.composer.enabled" 1.558 + //3. presence of ro.display.colorfill at the Gonk level 1.559 + 1.560 + var req = navigator.mozSettings.createLock().get('layers.composer2d.enabled'); 1.561 + req.onsuccess = function() { 1.562 + if (typeof(req.result['layers.composer2d.enabled']) === 'undefined') { 1.563 + var enabled = false; 1.564 + if (Services.prefs.getPrefType('layers.composer2d.enabled') == Ci.nsIPrefBranch.PREF_BOOL) { 1.565 + enabled = Services.prefs.getBoolPref('layers.composer2d.enabled'); 1.566 + } else { 1.567 +#ifdef MOZ_WIDGET_GONK 1.568 + enabled = (libcutils.property_get('ro.display.colorfill') === '1'); 1.569 +#endif 1.570 + } 1.571 + navigator.mozSettings.createLock().set({'layers.composer2d.enabled': enabled }); 1.572 + } 1.573 + 1.574 + SettingsListener.observe("layers.composer2d.enabled", true, function(value) { 1.575 + Services.prefs.setBoolPref("layers.composer2d.enabled", value); 1.576 + }); 1.577 + }; 1.578 + req.onerror = function() { 1.579 + dump("Error configuring layers.composer2d.enabled setting"); 1.580 + }; 1.581 + 1.582 +})(); 1.583 + 1.584 +// ================ Accessibility ============ 1.585 +SettingsListener.observe("accessibility.screenreader", false, function(value) { 1.586 + if (value && !("AccessFu" in this)) { 1.587 + Cu.import('resource://gre/modules/accessibility/AccessFu.jsm'); 1.588 + AccessFu.attach(window); 1.589 + } 1.590 +}); 1.591 + 1.592 +// ================ Theming ============ 1.593 +(function themingSettingsListener() { 1.594 + let themingPrefs = ['ui.menu', 'ui.menutext', 'ui.infobackground', 'ui.infotext', 1.595 + 'ui.window', 'ui.windowtext', 'ui.highlight']; 1.596 + 1.597 + themingPrefs.forEach(function(pref) { 1.598 + SettingsListener.observe('gaia.' + pref, null, function(value) { 1.599 + if (value) { 1.600 + Services.prefs.setCharPref(pref, value); 1.601 + } 1.602 + }); 1.603 + }); 1.604 +})(); 1.605 + 1.606 +// =================== AsyncPanZoom ====================== 1.607 +SettingsListener.observe('apz.displayport.heuristics', 'default', function(value) { 1.608 + // first reset everything to default 1.609 + Services.prefs.clearUserPref('apz.velocity_bias'); 1.610 + Services.prefs.clearUserPref('apz.use_paint_duration'); 1.611 + Services.prefs.clearUserPref('apz.x_skate_size_multiplier'); 1.612 + Services.prefs.clearUserPref('apz.y_skate_size_multiplier'); 1.613 + Services.prefs.clearUserPref('apz.allow-checkerboarding'); 1.614 + // and then set the things that we want to change 1.615 + switch (value) { 1.616 + case 'default': 1.617 + break; 1.618 + case 'center-displayport': 1.619 + Services.prefs.setCharPref('apz.velocity_bias', '0.0'); 1.620 + break; 1.621 + case 'perfect-paint-times': 1.622 + Services.prefs.setBoolPref('apz.use_paint_duration', false); 1.623 + Services.prefs.setCharPref('apz.velocity_bias', '0.32'); // 16/50 (assumes 16ms paint times instead of 50ms) 1.624 + break; 1.625 + case 'taller-displayport': 1.626 + Services.prefs.setCharPref('apz.y_skate_size_multiplier', '3.5'); 1.627 + break; 1.628 + case 'faster-paint': 1.629 + Services.prefs.setCharPref('apz.x_skate_size_multiplier', '1.0'); 1.630 + Services.prefs.setCharPref('apz.y_skate_size_multiplier', '1.5'); 1.631 + break; 1.632 + case 'no-checkerboard': 1.633 + Services.prefs.setBoolPref('apz.allow-checkerboarding', false); 1.634 + break; 1.635 + } 1.636 +}); 1.637 + 1.638 +// =================== Various simple mapping ====================== 1.639 +let settingsToObserve = { 1.640 + 'ril.mms.retrieval_mode': { 1.641 + prefName: 'dom.mms.retrieval_mode', 1.642 + defaultValue: 'manual' 1.643 + }, 1.644 + 'ril.sms.strict7BitEncoding.enabled': { 1.645 + prefName: 'dom.sms.strict7BitEncoding', 1.646 + defaultValue: false 1.647 + }, 1.648 + 'ril.sms.requestStatusReport.enabled': { 1.649 + prefName: 'dom.sms.requestStatusReport', 1.650 + defaultValue: false 1.651 + }, 1.652 + 'ril.mms.requestStatusReport.enabled': { 1.653 + prefName: 'dom.mms.requestStatusReport', 1.654 + defaultValue: false 1.655 + }, 1.656 + 'ril.mms.requestReadReport.enabled': { 1.657 + prefName: 'dom.mms.requestReadReport', 1.658 + defaultValue: true 1.659 + }, 1.660 + 'ril.cellbroadcast.disabled': false, 1.661 + 'ril.radio.disabled': false, 1.662 + 'wap.UAProf.url': '', 1.663 + 'wap.UAProf.tagname': 'x-wap-profile', 1.664 + 'devtools.eventlooplag.threshold': 100, 1.665 + 'privacy.donottrackheader.enabled': false, 1.666 + 'apz.force-enable': { 1.667 + prefName: 'dom.browser_frames.useAsyncPanZoom', 1.668 + defaultValue: false 1.669 + }, 1.670 + 'layers.enable-tiles': true, 1.671 + 'layers.simple-tiles': false, 1.672 + 'layers.progressive-paint': false, 1.673 + 'layers.draw-tile-borders': false, 1.674 + 'layers.dump': false, 1.675 + 'debug.fps.enabled': { 1.676 + prefName: 'layers.acceleration.draw-fps', 1.677 + defaultValue: false 1.678 + }, 1.679 + 'debug.paint-flashing.enabled': { 1.680 + prefName: 'nglayout.debug.paint_flashing', 1.681 + defaultValue: false 1.682 + }, 1.683 + 'layers.draw-borders': false, 1.684 + 'app.update.interval': 86400, 1.685 + 'app.update.url': { 1.686 + resetToPref: true 1.687 + }, 1.688 + 'app.update.channel': { 1.689 + resetToPref: true 1.690 + }, 1.691 + 'debug.log-animations.enabled': { 1.692 + prefName: 'layers.offmainthreadcomposition.log-animations', 1.693 + defaultValue: false 1.694 + } 1.695 +}; 1.696 + 1.697 +for (let key in settingsToObserve) { 1.698 + let setting = settingsToObserve[key]; 1.699 + 1.700 + // Allow setting to contain flags redefining prefName and defaultValue. 1.701 + let prefName = setting.prefName || key; 1.702 + let defaultValue = setting.defaultValue; 1.703 + if (defaultValue === undefined) { 1.704 + defaultValue = setting; 1.705 + } 1.706 + 1.707 + let prefs = Services.prefs; 1.708 + 1.709 + // If requested, reset setting value and defaultValue to the pref value. 1.710 + if (setting.resetToPref) { 1.711 + switch (prefs.getPrefType(prefName)) { 1.712 + case Ci.nsIPrefBranch.PREF_BOOL: 1.713 + defaultValue = prefs.getBoolPref(prefName); 1.714 + break; 1.715 + 1.716 + case Ci.nsIPrefBranch.PREF_INT: 1.717 + defaultValue = prefs.getIntPref(prefName); 1.718 + break; 1.719 + 1.720 + case Ci.nsIPrefBranch.PREF_STRING: 1.721 + defaultValue = prefs.getCharPref(prefName); 1.722 + break; 1.723 + } 1.724 + 1.725 + let setting = {}; 1.726 + setting[key] = defaultValue; 1.727 + window.navigator.mozSettings.createLock().set(setting); 1.728 + } 1.729 + 1.730 + // Figure out the right setter function for this type of pref. 1.731 + let setPref; 1.732 + switch (typeof defaultValue) { 1.733 + case 'boolean': 1.734 + setPref = prefs.setBoolPref.bind(prefs); 1.735 + break; 1.736 + 1.737 + case 'number': 1.738 + setPref = prefs.setIntPref.bind(prefs); 1.739 + break; 1.740 + 1.741 + case 'string': 1.742 + setPref = prefs.setCharPref.bind(prefs); 1.743 + break; 1.744 + } 1.745 + 1.746 + SettingsListener.observe(key, defaultValue, function(value) { 1.747 + setPref(prefName, value); 1.748 + }); 1.749 +}; 1.750 +