michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: 'use strict'; michael@0: michael@0: module.metadata = { michael@0: "stability": "unstable" michael@0: }; michael@0: michael@0: const { Cc, Ci, Cu } = require('chrome'); michael@0: const { defer } = require('../lang/functional'); michael@0: const { emit, on, once, off } = require('../event/core'); michael@0: const { when: unload } = require('../system/unload'); michael@0: const events = require('../system/events'); michael@0: const { deprecateFunction } = require('../util/deprecate'); michael@0: const { isOneOf, is, satisfiesVersion, version } = require('../system/xul-app'); michael@0: const { isWindowPrivate } = require('../window/utils'); michael@0: const { isPrivateBrowsingSupported } = require('../self'); michael@0: michael@0: let deferredEmit = defer(emit); michael@0: let pbService; michael@0: let PrivateBrowsingUtils; michael@0: michael@0: // Private browsing is only supported in Fx michael@0: if (isOneOf(['Firefox', 'Fennec'])) { michael@0: // get the nsIPrivateBrowsingService if it exists michael@0: try { michael@0: pbService = Cc["@mozilla.org/privatebrowsing;1"]. michael@0: getService(Ci.nsIPrivateBrowsingService); michael@0: michael@0: // a dummy service exists for the moment (Fx20 atleast), but will be removed eventually michael@0: // ie: the service will exist, but it won't do anything and the global private browing michael@0: // feature is not really active. See Bug 818800 and Bug 826037 michael@0: if (!('privateBrowsingEnabled' in pbService)) michael@0: pbService = undefined; michael@0: } michael@0: catch(e) { /* Private Browsing Service has been removed (Bug 818800) */ } michael@0: michael@0: try { michael@0: PrivateBrowsingUtils = Cu.import('resource://gre/modules/PrivateBrowsingUtils.jsm', {}).PrivateBrowsingUtils; michael@0: } michael@0: catch(e) { /* if this file DNE then an error will be thrown */ } michael@0: } michael@0: michael@0: // checks that global private browsing is implemented michael@0: let isGlobalPBSupported = exports.isGlobalPBSupported = !!pbService && is('Firefox'); michael@0: michael@0: // checks that per-window private browsing is implemented michael@0: let isWindowPBSupported = exports.isWindowPBSupported = michael@0: !pbService && !!PrivateBrowsingUtils && is('Firefox'); michael@0: michael@0: // checks that per-tab private browsing is implemented michael@0: let isTabPBSupported = exports.isTabPBSupported = michael@0: !pbService && !!PrivateBrowsingUtils && is('Fennec') && satisfiesVersion(version, '>=20.0*'); michael@0: michael@0: exports.isPermanentPrivateBrowsing = function() { michael@0: return !!(PrivateBrowsingUtils && PrivateBrowsingUtils.permanentPrivateBrowsing); michael@0: } michael@0: michael@0: function ignoreWindow(window) { michael@0: return !isPrivateBrowsingSupported && isWindowPrivate(window) && !isGlobalPBSupported; michael@0: } michael@0: exports.ignoreWindow = ignoreWindow; michael@0: michael@0: function onChange() { michael@0: // Emit event with in next turn of event loop. michael@0: deferredEmit(exports, pbService.privateBrowsingEnabled ? 'start' : 'stop'); michael@0: } michael@0: michael@0: // Currently, only Firefox implements the private browsing service. michael@0: if (isGlobalPBSupported) { michael@0: // set up an observer for private browsing switches. michael@0: events.on('private-browsing-transition-complete', onChange); michael@0: } michael@0: michael@0: // We toggle private browsing mode asynchronously in order to work around michael@0: // bug 659629. Since private browsing transitions are asynchronous michael@0: // anyway, this doesn't significantly change the behavior of the API. michael@0: let setMode = defer(function setMode(value) { michael@0: value = !!value; // Cast to boolean. michael@0: michael@0: // default michael@0: return pbService && (pbService.privateBrowsingEnabled = value); michael@0: }); michael@0: exports.setMode = deprecateFunction( michael@0: setMode, michael@0: 'require("sdk/private-browsing").activate and ' + michael@0: 'require("sdk/private-browsing").deactivate ' + michael@0: 'are deprecated.' michael@0: ); michael@0: michael@0: let getMode = function getMode(chromeWin) { michael@0: if (isWindowPrivate(chromeWin)) michael@0: return true; michael@0: michael@0: // default michael@0: return pbService ? pbService.privateBrowsingEnabled : false; michael@0: }; michael@0: exports.getMode = getMode; michael@0: michael@0: exports.on = on.bind(null, exports); michael@0: michael@0: // Make sure listeners are cleaned up. michael@0: unload(function() off(exports));