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 >
Text File  |  2010-08-30  |  10KB  |  328 lines

  1. /*
  2. //
  3. // BEGIN SONGBIRD GPL
  4. //
  5. // This file is part of the Songbird web player.
  6. //
  7. // Copyright(c) 2005-2009 POTI, Inc.
  8. // http://songbirdnest.com
  9. //
  10. // This file may be licensed under the terms of of the
  11. // GNU General Public License Version 2 (the "GPL").
  12. //
  13. // Software distributed under the License is distributed
  14. // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
  15. // express or implied. See the GPL for the specific language
  16. // governing rights and limitations.
  17. //
  18. // You should have received a copy of the GPL along with this
  19. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  20. // or write to the Free Software Foundation, Inc.,
  21. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. //
  23. // END SONGBIRD GPL
  24. //
  25. */
  26.  
  27. const Cc = Components.classes;
  28. const Ci = Components.interfaces;
  29. const Cu = Components.utils;
  30. const Cr = Components.results;
  31.  
  32. const SB_SHUTDOWNSERVICE_CLASSNAME  = "sbShutdownService";
  33. const SB_SHUTDOWNSERVICE_DESC       = "Songbird Shutdown Service";
  34. const SB_SHUTDOWNSERVICE_CONTRACTID = "@songbirdnest.com/shutdown-service;1";
  35. const SB_SHUTDOWNSERVICE_CID        = "{594137ED-DB4A-4530-8635-2573C018B4FB}";
  36.  
  37. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  38. Cu.import("resource://app/jsmodules/WindowUtils.jsm");
  39. Cu.import("resource://app/jsmodules/StringUtils.jsm");
  40.  
  41. //------------------------------------------------------------------------------
  42. // Songbird Shutdown Job Service
  43.  
  44. var gTestListeners = [];
  45.  
  46. function sbShutdownJobService()
  47. {
  48.   var observerService = Cc["@mozilla.org/observer-service;1"]
  49.                           .getService(Ci.nsIObserverService);
  50.   observerService.addObserver(this, "quit-application-requested", false);
  51. }
  52.  
  53. sbShutdownJobService.prototype = 
  54. {
  55.   _mTasks:          [], 
  56.   _mTaskIndex:      0,
  57.   _mTotal:          0,
  58.   _mProgress:       0,
  59.   _mListeners:      [],
  60.   _mShouldShutdown: true,
  61.   _mShutdownFlags:  Ci.nsIAppStartup.eAttemptQuit,
  62.   _mStatus:         Ci.sbIJobProgress.STATUS_RUNNING,
  63.  
  64.   // nsIObserver
  65.   observe: function(aSubject, aTopic, aData) {
  66.     if (aTopic == "quit-application-requested") {
  67.  
  68.       var observerService = Cc["@mozilla.org/observer-service;1"]
  69.                               .getService(Ci.nsIObserverService);
  70.       // Only hault shutdown if there are tasks to be processed.
  71.       var listenerEnum = 
  72.         observerService.enumerateObservers("songbird-shutdown");
  73.       while (listenerEnum.hasMoreElements()) {
  74.         try { 
  75.           var curTask = 
  76.             listenerEnum.getNext().QueryInterface(Ci.sbIShutdownJob);
  77.           
  78.           if (curTask.needsToRunTask) {
  79.             this._mTasks.push(curTask);
  80.           }
  81.         }
  82.         catch (e) {
  83.           Cu.reportError(e);
  84.         }
  85.       }
  86.  
  87.       if (this._mTasks.length > 0) {
  88.         // There are tasks to run, hault shutdown for now.
  89.         var stopShutdown = aSubject.QueryInterface(Ci.nsISupportsPRBool);
  90.         stopShutdown.data = true;
  91.  
  92.         // If the |aData| flag indicates that this is going to be a restart,
  93.         // append the restart flag for when we do shutdown.
  94.         if (aData == "restart") {
  95.           this._mShutdownFlags |= Ci.nsIAppStartup.eRestart;
  96.         }
  97.  
  98.         // If this notice was made by the unit test, don't shutdown once
  99.         // all the tasks have been processed.
  100.         if (aData && aData == "is-unit-test") {
  101.           this._mShouldShutdown = false;
  102.         }
  103.       
  104.         this._startProcessingTasks();
  105.       }
  106.     }
  107.   },
  108.  
  109.   // sbIJobProgressListener
  110.   onJobProgress: function(aJobProgress) {
  111.     this._notifyListeners();
  112.  
  113.     switch (aJobProgress.status) {
  114.       case Ci.sbIJobProgress.STATUS_FAILED:
  115.         // If the job failed - report the errors and continue on to the next
  116.         // shutdown task.
  117.         Cu.reportError("sbShutdownJobService - shutdown job failed!");
  118.  
  119.       case Ci.sbIJobProgress.STATUS_SUCCEEDED:
  120.         // Clean up ourselves on the current task.
  121.         var curTask = this._mTasks[this._mTaskIndex];
  122.         curTask.removeJobProgressListener(this);
  123.  
  124.         // Update the cumulative progress count
  125.         this._mProgress += this._mTasks[this._mTaskIndex].total;
  126.  
  127.         // Process the next task.
  128.         this._mTaskIndex++;
  129.         this._processNextTask();
  130.         break;
  131.     }
  132.   },
  133.  
  134.   // sbIJobProgress
  135.   get status() {
  136.     return this._mStatus;
  137.   },
  138.  
  139.   get blocked() {
  140.     return false;
  141.   },
  142.  
  143.   get statusText() {
  144.     var statusText = this._mTasks[this._mTaskIndex].statusText;
  145.     var remainingTasks = (this._mTasks.length - this._mTaskIndex) -1;
  146.  
  147.     if (statusText == "") {
  148.       // If the shutdown task does not provide a string, use a generic one.
  149.       statusText = SBString("shutdownservice.defaultstatustext"); 
  150.     }
  151.  
  152.     if (remainingTasks == 0) {
  153.       return statusText; 
  154.     }
  155.     else {
  156.       return SBFormattedString("shutdownservice.statustext",
  157.                                [statusText, remainingTasks]);
  158.     }
  159.   },
  160.  
  161.   get titleText() {
  162.     return SBString("shutdownservice.statustitle");
  163.   },
  164.  
  165.   get progress() {
  166.     return this._mProgress + this._mTasks[this._mTaskIndex].progress;
  167.   },
  168.  
  169.   get total() {
  170.     return this._mTotal;
  171.   },
  172.  
  173.   get errorCount() {
  174.     return 0;
  175.   },
  176.  
  177.   getErrorMessages: function() {
  178.     // Don't report any error messages for now.
  179.     return null;
  180.   },
  181.  
  182.   addJobProgressListener: function(aJobListener) {
  183.     this._mListeners.push(aJobListener);
  184.   },
  185.  
  186.   removeJobProgressListener: function(aJobListener) {
  187.     var listenerIndex = this._mListeners.indexOf(aJobListener);
  188.     if (listenerIndex > -1) {
  189.       this._mListeners.splice(listenerIndex, 1);
  190.     }
  191.   },
  192.  
  193.   // sbIJobCancelable
  194.   get canCancel() {
  195.     return true;
  196.   },
  197.  
  198.   cancel: function() {
  199.     this._doShutdown();
  200.   },
  201.  
  202.   _startProcessingTasks: function() {
  203.     // Calculate the total metric for the job progress interface.
  204.     for (var i = 0; i < this._mTasks.length; i++) {
  205.       this._mTotal += this._mTasks[i].total;
  206.     }
  207.  
  208.     // The only open window during the shutdown service should be the Songbird
  209.     // window. First, close down the main Songbird window.
  210.     var winMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
  211.                         .getService(Ci.nsIWindowMediator);
  212.     var songbirdWin = winMediator.getMostRecentWindow("Songbird:Main");
  213.     if (songbirdWin) {
  214.       songbirdWin.close();
  215.     }
  216.  
  217.     var args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
  218.     args.appendElement(this, false);
  219.  
  220.     // Open the progress dialog using the hidden window since the shutdown
  221.     // progress dialog should be the only open Songbird window.
  222.     var appShellService = Cc["@mozilla.org/appshell/appShellService;1"]
  223.                             .getService(Ci.nsIAppShellService);
  224.  
  225.     var parentWindow = appShellService.hiddenDOMWindow;
  226.     parentWindow.openDialog("chrome://songbird/content/xul/jobProgress.xul",
  227.                             "job_progress_dialog",
  228.                             "chrome,centerscreen",
  229.                             args);
  230.  
  231.     this._processNextTask();
  232.   },
  233.  
  234.   _processNextTask: function() {
  235.     if (this._mTaskIndex < this._mTasks.length) {
  236.       this._notifyListeners();
  237.       
  238.       var nextTask = this._mTasks[this._mTaskIndex];
  239.       try {
  240.         nextTask.addJobProgressListener(this);
  241.         nextTask.startTask(this);
  242.       }
  243.       catch (e) {
  244.         Cu.reportError("Error processing shutdown task!");
  245.         this._mTaskIndex++;
  246.         this._processNextTask();
  247.       }
  248.     }
  249.     else {
  250.       this._doShutdown();
  251.     }
  252.   },
  253.  
  254.   _doShutdown: function() {
  255.     // Sleep for 100ms to allow the dialog to draw the complete progressbar
  256.     // and not close the dialog with a large chunk of "unfinished" progress.
  257.     this._mTaskIndex--;  // make sure to show the last task
  258.     this._notifyListeners();
  259.     this._sleep(100);
  260.     
  261.     // Notify the listener (this will close the progress dialog)
  262.     this._mStatus = Ci.sbIJobProgress.STATUS_SUCCEEDED;
  263.     this._notifyListeners();
  264.  
  265.     // drop the references to the tasks
  266.     this._mTasks.splice(0);
  267.  
  268.     // Attempt to shutdown again.
  269.     if (this._mShouldShutdown) {
  270.       var appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
  271.                          .getService(Ci.nsIAppStartup);
  272.       appStartup.quit(this._mShutdownFlags);
  273.     }
  274.   },
  275.  
  276.   _notifyListeners: function() {
  277.     // Clone the listeners, otherwise removing one in the middle can 
  278.     // cause issues.
  279.     var listeners = [].concat(this._mListeners); 
  280.     for (var i = 0; i < listeners.length; i++) {
  281.       try {
  282.         listeners[i].onJobProgress(this);
  283.       }
  284.       catch (e) {
  285.         Cu.reportError(e);
  286.       }
  287.     }
  288.   },
  289.  
  290.   _sleep: function(ms) {
  291.     var threadManager = Cc["@mozilla.org/thread-manager;1"]
  292.                           .getService(Ci.nsIThreadManager);
  293.     var mainThread = threadManager.mainThread;
  294.     var then = new Date().getTime(), now = then;
  295.     for (; now - then < ms; now = new Date().getTime()) {
  296.       mainThread.processNextEvent(true);
  297.     }
  298.   },
  299.  
  300.   // XCOM Goo
  301.   className: SB_SHUTDOWNSERVICE_CLASSNAME,
  302.   classDescription: SB_SHUTDOWNSERVICE_DESC,
  303.   classID: Components.ID(SB_SHUTDOWNSERVICE_CID),
  304.   contractID: SB_SHUTDOWNSERVICE_CONTRACTID,
  305.   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, 
  306.                                          Ci.sbIJobProgressListener,
  307.                                          Ci.sbIJobProgress,
  308.                                          Ci.sbIJobCancelable]) 
  309. };
  310.  
  311. //------------------------------------------------------------------------------
  312. // XPCOM Registration
  313.  
  314. function NSGetModule(compMgr, fileSpec)
  315. {
  316.   return XPCOMUtils.generateModule([sbShutdownJobService],
  317.     function(aCompMgr, aFileSpec, aLocation) {
  318.       XPCOMUtils.categoryManager.addCategoryEntry("app-startup",
  319.                                                   SB_SHUTDOWNSERVICE_DESC,
  320.                                                   "service," +
  321.                                                   SB_SHUTDOWNSERVICE_CONTRACTID,
  322.                                                   true,
  323.                                                   true);
  324.     }
  325.   );
  326. }
  327.  
  328.