Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 'use strict';
6 // Fennec support tracked in bug #809412
7 module.metadata = {
8 'engines': {
9 'Firefox': '*'
10 }
11 };
13 const windowUtils = require('sdk/deprecated/window-utils');
14 const { Cc, Ci } = require('chrome');
15 const { isWindowPBSupported } = require('sdk/private-browsing/utils');
16 const { getFrames, getWindowTitle, onFocus, isWindowPrivate } = require('sdk/window/utils');
17 const { open, close, focus } = require('sdk/window/helpers');
18 const WM = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
19 const { isPrivate } = require('sdk/private-browsing');
20 const { fromIterator: toArray } = require('sdk/util/array');
21 const { defer } = require('sdk/core/promise');
22 const { setTimeout } = require('sdk/timers');
24 function tick() {
25 let deferred = defer();
26 setTimeout(deferred.resolve);
27 return deferred.promise;
28 }
30 function makeEmptyBrowserWindow(options) {
31 options = options || {};
32 return open('chrome://browser/content/browser.xul', {
33 features: {
34 chrome: true,
35 private: !!options.private
36 }
37 });
38 }
40 exports.testWindowTrackerIgnoresPrivateWindows = function(assert, done) {
41 var myNonPrivateWindow, myPrivateWindow;
42 var finished = false;
43 var privateWindow;
44 var privateWindowClosed = false;
46 let wt = windowUtils.WindowTracker({
47 onTrack: function(window) {
48 assert.ok(!isWindowPrivate(window), 'private window was not tracked!');
49 },
50 onUntrack: function(window) {
51 assert.ok(!isWindowPrivate(window), 'private window was not tracked!');
52 // PWPB case
53 if (window === myPrivateWindow && isWindowPBSupported) {
54 privateWindowClosed = true;
55 }
56 if (window === myNonPrivateWindow) {
57 assert.ok(!privateWindowClosed);
58 wt.unload();
59 done();
60 }
61 }
62 });
64 // make a new private window
65 makeEmptyBrowserWindow({
66 private: true
67 }).then(function(window) {
68 myPrivateWindow = window;
70 assert.equal(isWindowPrivate(window), isWindowPBSupported);
71 assert.ok(getFrames(window).length > 1, 'there are frames for private window');
72 assert.equal(getWindowTitle(window), window.document.title,
73 'getWindowTitle works');
75 return close(window).then(function() {
76 return makeEmptyBrowserWindow().then(function(window) {
77 myNonPrivateWindow = window;
78 assert.pass('opened new window');
79 return close(window);
80 });
81 });
82 }).then(null, assert.fail);
83 };
85 // Test setting activeWIndow and onFocus for private windows
86 exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
87 let browserWindow = WM.getMostRecentWindow("navigator:browser");
89 assert.equal(windowUtils.activeBrowserWindow, browserWindow,
90 "Browser window is the active browser window.");
91 assert.ok(!isPrivate(browserWindow), "Browser window is not private.");
93 // make a new private window
94 makeEmptyBrowserWindow({ private: true }).then(focus).then(window => {
95 // PWPB case
96 if (isWindowPBSupported) {
97 assert.ok(isPrivate(window), "window is private");
98 assert.notDeepEqual(windowUtils.activeBrowserWindow, browserWindow);
99 }
100 // Global case
101 else {
102 assert.ok(!isPrivate(window), "window is not private");
103 }
105 assert.strictEqual(windowUtils.activeBrowserWindow, window,
106 "Correct active browser window pb supported");
107 assert.notStrictEqual(browserWindow, window,
108 "The window is not the old browser window");
111 return onFocus(windowUtils.activeWindow = browserWindow).then(_ => {
112 assert.strictEqual(windowUtils.activeWindow, browserWindow,
113 "Correct active window [1]");
114 assert.strictEqual(windowUtils.activeBrowserWindow, browserWindow,
115 "Correct active browser window [1]");
117 // test focus(window)
118 return focus(window).then(w => {
119 assert.strictEqual(w, window, 'require("sdk/window/helpers").focus on window works');
120 }).then(tick);
121 }).then(_ => {
122 assert.strictEqual(windowUtils.activeBrowserWindow, window,
123 "Correct active browser window [2]");
124 assert.strictEqual(windowUtils.activeWindow, window,
125 "Correct active window [2]");
127 // test setting a private window
128 return onFocus(windowUtils.activeWindow = window);
129 }).then(function() {
130 assert.deepEqual(windowUtils.activeBrowserWindow, window,
131 "Correct active browser window [3]");
132 assert.deepEqual(windowUtils.activeWindow, window,
133 "Correct active window [3]");
135 // just to get back to original state
136 return onFocus(windowUtils.activeWindow = browserWindow);
137 }).then(_ => {
138 assert.deepEqual(windowUtils.activeBrowserWindow, browserWindow,
139 "Correct active browser window when pb mode is supported [4]");
140 assert.deepEqual(windowUtils.activeWindow, browserWindow,
141 "Correct active window when pb mode is supported [4]");
143 return close(window);
144 })
145 }).then(done).then(null, assert.fail);
146 };
148 exports.testActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
149 // make a new private window
150 makeEmptyBrowserWindow({
151 private: true
152 }).then(function(window) {
153 // PWPB case
154 if (isWindowPBSupported) {
155 assert.equal(isPrivate(windowUtils.activeWindow), true,
156 "active window is private");
157 assert.equal(isPrivate(windowUtils.activeBrowserWindow), true,
158 "active browser window is private");
159 assert.ok(isWindowPrivate(window), "window is private");
160 assert.ok(isPrivate(window), "window is private");
162 // pb mode is supported
163 assert.ok(
164 isWindowPrivate(windowUtils.activeWindow),
165 "active window is private when pb mode is supported");
166 assert.ok(
167 isWindowPrivate(windowUtils.activeBrowserWindow),
168 "active browser window is private when pb mode is supported");
169 assert.ok(isPrivate(windowUtils.activeWindow),
170 "active window is private when pb mode is supported");
171 assert.ok(isPrivate(windowUtils.activeBrowserWindow),
172 "active browser window is private when pb mode is supported");
173 }
174 // Global case
175 else {
176 assert.equal(isPrivate(windowUtils.activeWindow), false,
177 "active window is not private");
178 assert.equal(isPrivate(windowUtils.activeBrowserWindow), false,
179 "active browser window is not private");
180 assert.equal(isWindowPrivate(window), false, "window is not private");
181 assert.equal(isPrivate(window), false, "window is not private");
182 }
184 return close(window);
185 }).then(done).then(null, assert.fail);
186 }
188 exports.testWindowIteratorIgnoresPrivateWindows = function(assert, done) {
189 // make a new private window
190 makeEmptyBrowserWindow({
191 private: true
192 }).then(function(window) {
193 // PWPB case
194 if (isWindowPBSupported) {
195 assert.ok(isWindowPrivate(window), "window is private");
196 assert.equal(toArray(windowUtils.windowIterator()).indexOf(window), -1,
197 "window is not in windowIterator()");
198 }
199 // Global case
200 else {
201 assert.equal(isWindowPrivate(window), false, "window is not private");
202 assert.ok(toArray(windowUtils.windowIterator()).indexOf(window) > -1,
203 "window is in windowIterator()");
204 }
206 return close(window);
207 }).then(done).then(null, assert.fail);
208 };
210 require("sdk/test").run(exports);