home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 100
/
FreelogNo100-NovembreDecembre2010.iso
/
Multimedia
/
Songbird
/
Songbird_1.8.0-1800_windows-i686-msvc8.exe
/
components
/
sbShutdownService.js
< prev
next >
Wrap
Text File
|
2010-08-30
|
10KB
|
328 lines
/*
//
// BEGIN SONGBIRD GPL
//
// This file is part of the Songbird web player.
//
// Copyright(c) 2005-2009 POTI, Inc.
// http://songbirdnest.com
//
// This file may be licensed under the terms of of the
// GNU General Public License Version 2 (the "GPL").
//
// Software distributed under the License is distributed
// on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
// express or implied. See the GPL for the specific language
// governing rights and limitations.
//
// You should have received a copy of the GPL along with this
// program. If not, go to http://www.gnu.org/licenses/gpl.html
// or write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// END SONGBIRD GPL
//
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
const SB_SHUTDOWNSERVICE_CLASSNAME = "sbShutdownService";
const SB_SHUTDOWNSERVICE_DESC = "Songbird Shutdown Service";
const SB_SHUTDOWNSERVICE_CONTRACTID = "@songbirdnest.com/shutdown-service;1";
const SB_SHUTDOWNSERVICE_CID = "{594137ED-DB4A-4530-8635-2573C018B4FB}";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://app/jsmodules/WindowUtils.jsm");
Cu.import("resource://app/jsmodules/StringUtils.jsm");
//------------------------------------------------------------------------------
// Songbird Shutdown Job Service
var gTestListeners = [];
function sbShutdownJobService()
{
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(this, "quit-application-requested", false);
}
sbShutdownJobService.prototype =
{
_mTasks: [],
_mTaskIndex: 0,
_mTotal: 0,
_mProgress: 0,
_mListeners: [],
_mShouldShutdown: true,
_mShutdownFlags: Ci.nsIAppStartup.eAttemptQuit,
_mStatus: Ci.sbIJobProgress.STATUS_RUNNING,
// nsIObserver
observe: function(aSubject, aTopic, aData) {
if (aTopic == "quit-application-requested") {
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
// Only hault shutdown if there are tasks to be processed.
var listenerEnum =
observerService.enumerateObservers("songbird-shutdown");
while (listenerEnum.hasMoreElements()) {
try {
var curTask =
listenerEnum.getNext().QueryInterface(Ci.sbIShutdownJob);
if (curTask.needsToRunTask) {
this._mTasks.push(curTask);
}
}
catch (e) {
Cu.reportError(e);
}
}
if (this._mTasks.length > 0) {
// There are tasks to run, hault shutdown for now.
var stopShutdown = aSubject.QueryInterface(Ci.nsISupportsPRBool);
stopShutdown.data = true;
// If the |aData| flag indicates that this is going to be a restart,
// append the restart flag for when we do shutdown.
if (aData == "restart") {
this._mShutdownFlags |= Ci.nsIAppStartup.eRestart;
}
// If this notice was made by the unit test, don't shutdown once
// all the tasks have been processed.
if (aData && aData == "is-unit-test") {
this._mShouldShutdown = false;
}
this._startProcessingTasks();
}
}
},
// sbIJobProgressListener
onJobProgress: function(aJobProgress) {
this._notifyListeners();
switch (aJobProgress.status) {
case Ci.sbIJobProgress.STATUS_FAILED:
// If the job failed - report the errors and continue on to the next
// shutdown task.
Cu.reportError("sbShutdownJobService - shutdown job failed!");
case Ci.sbIJobProgress.STATUS_SUCCEEDED:
// Clean up ourselves on the current task.
var curTask = this._mTasks[this._mTaskIndex];
curTask.removeJobProgressListener(this);
// Update the cumulative progress count
this._mProgress += this._mTasks[this._mTaskIndex].total;
// Process the next task.
this._mTaskIndex++;
this._processNextTask();
break;
}
},
// sbIJobProgress
get status() {
return this._mStatus;
},
get blocked() {
return false;
},
get statusText() {
var statusText = this._mTasks[this._mTaskIndex].statusText;
var remainingTasks = (this._mTasks.length - this._mTaskIndex) -1;
if (statusText == "") {
// If the shutdown task does not provide a string, use a generic one.
statusText = SBString("shutdownservice.defaultstatustext");
}
if (remainingTasks == 0) {
return statusText;
}
else {
return SBFormattedString("shutdownservice.statustext",
[statusText, remainingTasks]);
}
},
get titleText() {
return SBString("shutdownservice.statustitle");
},
get progress() {
return this._mProgress + this._mTasks[this._mTaskIndex].progress;
},
get total() {
return this._mTotal;
},
get errorCount() {
return 0;
},
getErrorMessages: function() {
// Don't report any error messages for now.
return null;
},
addJobProgressListener: function(aJobListener) {
this._mListeners.push(aJobListener);
},
removeJobProgressListener: function(aJobListener) {
var listenerIndex = this._mListeners.indexOf(aJobListener);
if (listenerIndex > -1) {
this._mListeners.splice(listenerIndex, 1);
}
},
// sbIJobCancelable
get canCancel() {
return true;
},
cancel: function() {
this._doShutdown();
},
_startProcessingTasks: function() {
// Calculate the total metric for the job progress interface.
for (var i = 0; i < this._mTasks.length; i++) {
this._mTotal += this._mTasks[i].total;
}
// The only open window during the shutdown service should be the Songbird
// window. First, close down the main Songbird window.
var winMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
var songbirdWin = winMediator.getMostRecentWindow("Songbird:Main");
if (songbirdWin) {
songbirdWin.close();
}
var args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
args.appendElement(this, false);
// Open the progress dialog using the hidden window since the shutdown
// progress dialog should be the only open Songbird window.
var appShellService = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService);
var parentWindow = appShellService.hiddenDOMWindow;
parentWindow.openDialog("chrome://songbird/content/xul/jobProgress.xul",
"job_progress_dialog",
"chrome,centerscreen",
args);
this._processNextTask();
},
_processNextTask: function() {
if (this._mTaskIndex < this._mTasks.length) {
this._notifyListeners();
var nextTask = this._mTasks[this._mTaskIndex];
try {
nextTask.addJobProgressListener(this);
nextTask.startTask(this);
}
catch (e) {
Cu.reportError("Error processing shutdown task!");
this._mTaskIndex++;
this._processNextTask();
}
}
else {
this._doShutdown();
}
},
_doShutdown: function() {
// Sleep for 100ms to allow the dialog to draw the complete progressbar
// and not close the dialog with a large chunk of "unfinished" progress.
this._mTaskIndex--; // make sure to show the last task
this._notifyListeners();
this._sleep(100);
// Notify the listener (this will close the progress dialog)
this._mStatus = Ci.sbIJobProgress.STATUS_SUCCEEDED;
this._notifyListeners();
// drop the references to the tasks
this._mTasks.splice(0);
// Attempt to shutdown again.
if (this._mShouldShutdown) {
var appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
.getService(Ci.nsIAppStartup);
appStartup.quit(this._mShutdownFlags);
}
},
_notifyListeners: function() {
// Clone the listeners, otherwise removing one in the middle can
// cause issues.
var listeners = [].concat(this._mListeners);
for (var i = 0; i < listeners.length; i++) {
try {
listeners[i].onJobProgress(this);
}
catch (e) {
Cu.reportError(e);
}
}
},
_sleep: function(ms) {
var threadManager = Cc["@mozilla.org/thread-manager;1"]
.getService(Ci.nsIThreadManager);
var mainThread = threadManager.mainThread;
var then = new Date().getTime(), now = then;
for (; now - then < ms; now = new Date().getTime()) {
mainThread.processNextEvent(true);
}
},
// XCOM Goo
className: SB_SHUTDOWNSERVICE_CLASSNAME,
classDescription: SB_SHUTDOWNSERVICE_DESC,
classID: Components.ID(SB_SHUTDOWNSERVICE_CID),
contractID: SB_SHUTDOWNSERVICE_CONTRACTID,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.sbIJobProgressListener,
Ci.sbIJobProgress,
Ci.sbIJobCancelable])
};
//------------------------------------------------------------------------------
// XPCOM Registration
function NSGetModule(compMgr, fileSpec)
{
return XPCOMUtils.generateModule([sbShutdownJobService],
function(aCompMgr, aFileSpec, aLocation) {
XPCOMUtils.categoryManager.addCategoryEntry("app-startup",
SB_SHUTDOWNSERVICE_DESC,
"service," +
SB_SHUTDOWNSERVICE_CONTRACTID,
true,
true);
}
);
}