Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 |