nsSessionStartup.js
Go to the documentation of this file.
1 /*
2 # ***** BEGIN LICENSE BLOCK *****
3 # * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 # *
5 # * The contents of this file are subject to the Mozilla Public License Version
6 # * 1.1 (the "License"); you may not use this file except in compliance with
7 # * the License. You may obtain a copy of the License at
8 # * http://www.mozilla.org/MPL/
9 # *
10 # * Software distributed under the License is distributed on an "AS IS" basis,
11 # * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # * for the specific language governing rights and limitations under the
13 # * License.
14 # *
15 # * The Original Code is the nsSessionStore component.
16 # *
17 # * The Initial Developer of the Original Code is
18 # * Simon Bünzli <zeniko@gmail.com>
19 # * Portions created by the Initial Developer are Copyright (C) 2006
20 # * the Initial Developer. All Rights Reserved.
21 # *
22 # * Contributor(s):
23 # * Dietrich Ayala <autonome@gmail.com>
24 # *
25 # * Alternatively, the contents of this file may be used under the terms of
26 # * either the GNU General Public License Version 2 or later (the "GPL"), or
27 # * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 # * in which case the provisions of the GPL or the LGPL are applicable instead
29 # * of those above. If you wish to allow use of your version of this file only
30 # * under the terms of either the GPL or the LGPL, and not to allow others to
31 # * use your version of this file under the terms of the MPL, indicate your
32 # * decision by deleting the provisions above and replace them with the notice
33 # * and other provisions required by the GPL or the LGPL. If you do not delete
34 # * the provisions above, a recipient may use your version of this file under
35 # * the terms of any one of the MPL, the GPL or the LGPL.
36 # *
37 # * ***** END LICENSE BLOCK *****
38 */
39 
67 /* :::::::: Constants and Helpers ::::::::::::::: */
68 
69 const Cc = Components.classes;
70 const Ci = Components.interfaces;
71 const Cr = Components.results;
72 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
73 
74 const STATE_RUNNING_STR = "running";
75 
76 function debug(aMsg) {
77  aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n");
78  Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
79  .logStringMessage(aMsg);
80 }
81 
82 /* :::::::: The Service ::::::::::::::: */
83 
84 function SessionStartup() {
85 }
86 
87 SessionStartup.prototype = {
88 
89  // the state to restore at startup
90  _iniString: null,
91  _sessionType: Ci.nsISessionStartup.NO_SESSION,
92 
93 /* ........ Global Event Handlers .............. */
94 
98  init: function sss_init() {
99  // do not need to initialize anything in auto-started private browsing sessions
100  let pbs = Cc["@mozilla.org/privatebrowsing;1"].
101  getService(Ci.nsIPrivateBrowsingService);
102  if (pbs.autoStarted)
103  return;
104 
105  let prefBranch = Cc["@mozilla.org/preferences-service;1"].
106  getService(Ci.nsIPrefService).getBranch("browser.");
107 
108  // get file references
109  var dirService = Cc["@mozilla.org/file/directory_service;1"].
110  getService(Ci.nsIProperties);
111  let sessionFile = dirService.get("ProfD", Ci.nsILocalFile);
112  sessionFile.append("sessionstore.js");
113 
114  let doResumeSession = prefBranch.getBoolPref("sessionstore.resume_session_once") ||
115  prefBranch.getIntPref("startup.page") == 3;
116 
117  // only read the session file if config allows possibility of restoring
118  var resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash");
119  if (!resumeFromCrash && !doResumeSession || !sessionFile.exists())
120  return;
121 
122  // get string containing session state
123  this._iniString = this._readStateFile(sessionFile);
124  if (!this._iniString)
125  return;
126 
127  try {
128  // parse the session state into JS objects
129  var s = new Components.utils.Sandbox("about:blank");
130  var initialState = Components.utils.evalInSandbox("(" + this._iniString + ")", s);
131  }
132  catch (ex) { debug("The session file is invalid: " + ex); }
133 
134  let lastSessionCrashed =
135  initialState && initialState.session && initialState.session.state &&
136  initialState.session.state == STATE_RUNNING_STR;
137 
138  // set the startup type
139  if (lastSessionCrashed && resumeFromCrash)
140  this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
141  else if (!lastSessionCrashed && doResumeSession)
142  this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
143  else
144  this._iniString = null; // reset the state string
145 
146  if (this._sessionType != Ci.nsISessionStartup.NO_SESSION) {
147  // wait for the first browser window to open
148  var observerService = Cc["@mozilla.org/observer-service;1"].
149  getService(Ci.nsIObserverService);
150  observerService.addObserver(this, "domwindowopened", true);
151  observerService.addObserver(this, "browser:purge-session-history", true);
152  }
153  },
154 
158  observe: function sss_observe(aSubject, aTopic, aData) {
159  var observerService = Cc["@mozilla.org/observer-service;1"].
160  getService(Ci.nsIObserverService);
161 
162  switch (aTopic) {
163  case "app-startup":
164  observerService.addObserver(this, "final-ui-startup", true);
165  observerService.addObserver(this, "quit-application", true);
166  break;
167  case "final-ui-startup":
168  observerService.removeObserver(this, "final-ui-startup");
169  observerService.removeObserver(this, "quit-application");
170  this.init();
171  break;
172  case "quit-application":
173  // no reason for initializing at this point (cf. bug 409115)
174  observerService.removeObserver(this, "final-ui-startup");
175  observerService.removeObserver(this, "quit-application");
176  break;
177  case "domwindowopened":
178  var window = aSubject;
179  var self = this;
180  window.addEventListener("load", function() {
181  self._onWindowOpened(window);
182  window.removeEventListener("load", arguments.callee, false);
183  }, false);
184  break;
185  case "browser:purge-session-history":
186  // reset all state on sanitization
187  this._iniString = null;
188  this._sessionType = Ci.nsISessionStartup.NO_SESSION;
189  // no need in repeating this, since startup state won't change
190  observerService.removeObserver(this, "browser:purge-session-history");
191  break;
192  }
193  },
194 
199  _onWindowOpened: function sss_onWindowOpened(aWindow) {
200  var wType = aWindow.document.documentElement.getAttribute("windowtype");
201  if (wType != "navigator:browser")
202  return;
203 
218  var defaultArgs = Cc["@mozilla.org/browser/clh;1"].
219  getService(Ci.nsIBrowserHandler).defaultArgs;
220  if (aWindow.arguments && aWindow.arguments[0] &&
221  aWindow.arguments[0] == defaultArgs)
222  aWindow.arguments[0] = null;
223 
224  var observerService = Cc["@mozilla.org/observer-service;1"].
225  getService(Ci.nsIObserverService);
226  observerService.removeObserver(this, "domwindowopened");
227  },
228 
229 /* ........ Public API ................*/
230 
234  get state() {
235  return this._iniString;
236  },
237 
242  doRestore: function sss_doRestore() {
243  return this._sessionType != Ci.nsISessionStartup.NO_SESSION;
244  },
245 
249  get sessionType() {
250  return this._sessionType;
251  },
252 
253 /* ........ Storage API .............. */
254 
262  _readStateFile: function sss_readStateFile(aFile) {
263  var stateString = Cc["@mozilla.org/supports-string;1"].
264  createInstance(Ci.nsISupportsString);
265  stateString.data = this._readFile(aFile) || "";
266 
267  var observerService = Cc["@mozilla.org/observer-service;1"].
268  getService(Ci.nsIObserverService);
269  observerService.notifyObservers(stateString, "sessionstore-state-read", "");
270 
271  return stateString.data;
272  },
273 
280  _readFile: function sss_readFile(aFile) {
281  try {
282  var stream = Cc["@mozilla.org/network/file-input-stream;1"].
283  createInstance(Ci.nsIFileInputStream);
284  stream.init(aFile, 0x01, 0, 0);
285  var cvstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
286  createInstance(Ci.nsIConverterInputStream);
287  cvstream.init(stream, "UTF-8", 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
288 
289  var content = "";
290  var data = {};
291  while (cvstream.readString(4096, data)) {
292  content += data.value;
293  }
294  cvstream.close();
295 
296  return content.replace(/\r\n?/g, "\n");
297  }
298  catch (ex) { Components.utils.reportError(ex); }
299 
300  return null;
301  },
302 
303  /* ........ QueryInterface .............. */
304  QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
305  Ci.nsISupportsWeakReference,
306  Ci.nsISessionStartup]),
307  classDescription: "Browser Session Startup Service",
308  classID: Components.ID("{ec7a6c20-e081-11da-8ad9-0800200c9a66}"),
309  contractID: "@mozilla.org/browser/sessionstartup;1",
310 
311  // get this contractID registered for certain categories via XPCOMUtils
313  // make ourselves a startup observer
314  { category: "app-startup", service: true }
315  ]
316 
317 };
318 
319 function NSGetModule(aCompMgr, aFileSpec)
320  XPCOMUtils.generateModule([SessionStartup]);
static nsCOMPtr< nsIObserverService > observerService
Definition: UnityProxy.cpp:6
id service()
const STATE_RUNNING_STR
function NSGetModule(aCompMgr, aFileSpec) XPCOMUtils.generateModule([SessionStartup])
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
getService(Ci.sbIFaceplateManager)
let window
_window init
Definition: FeedWriter.js:1144
const Cr
return null
Definition: FeedWriter.js:1143
return!aWindow arguments!aWindow arguments[0]
function debug(aMsg)
function SessionStartup()
sbDeviceFirmwareAutoCheckForUpdate prototype classID
sbWindowsAutoPlayServiceCfg _xpcom_categories
observe data
Definition: FeedWriter.js:1329
const Ci
_updateTextAndScrollDataForFrame aData
sbDeviceFirmwareAutoCheckForUpdate prototype observe
const Cc