home *** CD-ROM | disk | FTP | other *** search
/ Freelog 112 / FreelogNo112-NovembreDecembre2012.iso / Multimedia / Songbird / Songbird_2.0.0-2311_windows-i686-msvc8.exe / components / sbAddOnBundleUpdateService.js < prev    next >
Text File  |  2012-06-08  |  19KB  |  593 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim: set sw=2 :miv */
  3. /*
  4. //
  5. // BEGIN SONGBIRD GPL
  6. //
  7. // This file is part of the Songbird web player.
  8. //
  9. // Copyright(c) 2005-2008 POTI, Inc.
  10. // http://songbirdnest.com
  11. //
  12. // This file may be licensed under the terms of of the
  13. // GNU General Public License Version 2 (the "GPL").
  14. //
  15. // Software distributed under the License is distributed
  16. // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
  17. // express or implied. See the GPL for the specific language
  18. // governing rights and limitations.
  19. //
  20. // You should have received a copy of the GPL along with this
  21. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  22. // or write to the Free Software Foundation, Inc.,
  23. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. //
  25. // END SONGBIRD GPL
  26. //
  27. */
  28.  
  29. /**
  30.  * \file  sbUpdateAddOnBundleService.js
  31.  * \brief Javascript source for the add-on bundle update service component.
  32.  */
  33.  
  34. //------------------------------------------------------------------------------
  35. //------------------------------------------------------------------------------
  36. //
  37. // Add-on bundle update service component.
  38. //
  39. //   This component periodically checks for updates to the add-on bundle and
  40. // presents new add-ons for installation to the user.
  41. //
  42. //------------------------------------------------------------------------------
  43. //------------------------------------------------------------------------------
  44.  
  45. //------------------------------------------------------------------------------
  46. //
  47. // Add-on bundle update service imported services.
  48. //
  49. //------------------------------------------------------------------------------
  50.  
  51. // Songbird services.
  52. Components.utils.import("resource://app/jsmodules/AddOnUtils.jsm");
  53. Components.utils.import("resource://app/jsmodules/ObserverUtils.jsm");
  54. Components.utils.import("resource://app/jsmodules/SBUtils.jsm");
  55. Components.utils.import("resource://app/jsmodules/WindowUtils.jsm");
  56. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  57.  
  58.  
  59. //------------------------------------------------------------------------------
  60. //
  61. // Add-on bundle update service defs.
  62. //
  63. //------------------------------------------------------------------------------
  64.  
  65. if (typeof(Cc) == "undefined")
  66.   var Cc = Components.classes;
  67. if (typeof(Ci) == "undefined")
  68.   var Ci = Components.interfaces;
  69. if (typeof(Cr) == "undefined")
  70.   var Cr = Components.results;
  71. if (typeof(Cu) == "undefined")
  72.   var Cu = Components.utils;
  73.  
  74.  
  75. //------------------------------------------------------------------------------
  76. //
  77. // Add-on bundle update service configuration.
  78. //
  79. //------------------------------------------------------------------------------
  80.  
  81. //
  82. // className                    Name of component class.
  83. // cid                          Component CID.
  84. // contractID                   Component contract ID.
  85. // ifList                       List of external component interfaces.
  86. // categoryList                 List of component categories.
  87. //
  88. // updateEnabledPref            Preference for enabling add-on bundle updates.
  89. // updateIntervalPref           Preference for setting interval between add-on
  90. //                              bundle update checks.
  91. // updatePrevAppVersionPref     Preference containing the version of the
  92. //                              Application when the add-on bundle update
  93. //                              service previously checked for updates.
  94. // defaultUpdateEnabled         Default update enabled preference value.
  95. // defaultUpdateInterval        Default add-on bundle update interval in
  96. //                              seconds.
  97. //
  98.  
  99. var sbAddOnBundleUpdateServiceCfg = {
  100.   className: "Songbird Add-on Bundle Update Service",
  101.   cid: Components.ID("{927d9849-8565-4bc4-805a-f3a6ad1b25ec}"),
  102.   contractID: "@songbirdnest.com/AddOnBundleUpdateService;1",
  103.   ifList: [ Ci.sbIAddOnBundleUpdateService, Ci.nsIObserver ],
  104.  
  105.   updateEnabledPref: "songbird.recommended_addons.update.enabled",
  106.   updateIntervalPref: "songbird.recommended_addons.update.interval",
  107.   updatePrevAppVersionPref:
  108.     "songbird.recommended_addons.update.prev_app_version",
  109.   defaultUpdateEnabled: false,
  110.   defaultUpdateInterval: 86400
  111. };
  112.  
  113. sbAddOnBundleUpdateServiceCfg.categoryList = [
  114.   {
  115.     category: "app-startup",
  116.     entry:    sbAddOnBundleUpdateServiceCfg.className,
  117.     value:    "service," + sbAddOnBundleUpdateServiceCfg.contractID
  118.   }
  119. ];
  120.  
  121.  
  122. //------------------------------------------------------------------------------
  123. //
  124. // Add-on bundle update service.
  125. //
  126. //------------------------------------------------------------------------------
  127.  
  128. /**
  129.  * Construct an add-on bundle update service object.
  130.  */
  131.  
  132. function sbAddOnBundleUpdateService() {
  133. }
  134.  
  135. // Define the object.
  136. sbAddOnBundleUpdateService.prototype = {
  137.   // Set the constructor.
  138.   constructor: sbAddOnBundleUpdateService,
  139.  
  140.   //
  141.   // Add-on bundle update service fields.
  142.   //
  143.   //   classDescription         Description of component class.
  144.   //   classID                  Component class ID.
  145.   //   contractID               Component contract ID.
  146.   //   _xpcom_categories        List of component categories.
  147.   //
  148.   //   _cfg                     Configuration settings.
  149.   //   _isInitialized           True if the add-on bundle update service has
  150.   //                            been initialized.
  151.   //   _observerSet             Set of observers.
  152.   //   _prefsAvailable          True if preferences are available.
  153.   //   _networkAvailable        True if the network is available.
  154.   //   _updateEnabled           True if add-on bundle update is enabled.
  155.   //   _checkedFirstRunHasCompleted
  156.   //                            True if a check has been made for first-run
  157.   //                            completion.
  158.   //   _firstRunHasCompleted    True if the first-run has been completed.
  159.   //   _addOnBundleLoader       Add-on bundle loader object.
  160.   //
  161.  
  162.   classDescription: sbAddOnBundleUpdateServiceCfg.className,
  163.   classID: sbAddOnBundleUpdateServiceCfg.cid,
  164.   contractID: sbAddOnBundleUpdateServiceCfg.contractID,
  165.   _xpcom_categories: sbAddOnBundleUpdateServiceCfg.categoryList,
  166.  
  167.   _cfg: sbAddOnBundleUpdateServiceCfg,
  168.   _isInitialized: false,
  169.   _observerSet: null,
  170.   _prefsAvailable: false,
  171.   _networkAvailable: false,
  172.   _updateEnabled: false,
  173.   _checkedFirstRunHasCompleted: false,
  174.   _firstRunHasCompleted: false,
  175.   _addOnBundleLoader: null,
  176.  
  177.  
  178.   //----------------------------------------------------------------------------
  179.   //
  180.   // Add-on bundle update service sbIAddOnBundleUpdateService services.
  181.   //
  182.   //----------------------------------------------------------------------------
  183.  
  184.   /**
  185.    * \brief True if a restart is required.
  186.    */
  187.  
  188.   restartRequired: false,
  189.  
  190.  
  191.   /**
  192.    * \brief Check for updates to the add-on bundle and present any to user.
  193.    */
  194.  
  195.   checkForUpdates: function sbAddOnBundleUpdateService_checkForUpdates() {
  196.     // Ensure the services are initialized.
  197.     this._initialize();
  198.  
  199.     // Present any new add-ons if update is enabled.
  200.     if (this._updateEnabled) {
  201.       // Update the add-on bundle cache synchronously if the application was
  202.       // updated.
  203.       if (this._getApplicationWasUpdated())
  204.         this._updateAddOnBundleCache(true);
  205.  
  206.       // Present any new add-ons.
  207.       this._presentNewAddOns();
  208.     }
  209.   },
  210.  
  211.  
  212.   //----------------------------------------------------------------------------
  213.   //
  214.   // Add-on bundle update service nsIObserver services.
  215.   //
  216.   //----------------------------------------------------------------------------
  217.  
  218.   /**
  219.    * Handle the observed event specified by aSubject, aTopic, and aData.
  220.    *
  221.    * \param aSubject            Event subject.
  222.    * \param aTopic              Event topic.
  223.    * \param aData               Event data.
  224.    */
  225.  
  226.   observe: function sbAddOnBundleUpdateService_observe(aSubject,
  227.                                                        aTopic,
  228.                                                        aData) {
  229.     // Dispatch processing of the event.
  230.     switch (aTopic) {
  231.       case "app-startup" :
  232.         this._handleAppStartup();
  233.         break;
  234.  
  235.       case "profile-after-change" :
  236.         this._handleProfileAfterChange();
  237.         break;
  238.  
  239.       case "final-ui-startup" :
  240.         this._handleFinalUIStartup();
  241.         break;
  242.  
  243.       case "quit-application" :
  244.         this._handleAppQuit();
  245.         break;
  246.  
  247.       default :
  248.         break;
  249.     }
  250.   },
  251.  
  252.  
  253.   //----------------------------------------------------------------------------
  254.   //
  255.   // Add-on bundle update service nsISupports services.
  256.   //
  257.   //----------------------------------------------------------------------------
  258.  
  259.   QueryInterface: XPCOMUtils.generateQI(sbAddOnBundleUpdateServiceCfg.ifList),
  260.  
  261.  
  262.   //----------------------------------------------------------------------------
  263.   //
  264.   // Add-on bundle update service event handler services.
  265.   //
  266.   //----------------------------------------------------------------------------
  267.  
  268.   /**
  269.    * Handle application startup events.
  270.    */
  271.  
  272.   _handleAppStartup: function sbAddOnBundleUpdateService__handleAppStartup() {
  273.     // Initialize the services.
  274.     this._initialize();
  275.   },
  276.  
  277.  
  278.   /**
  279.    * Handle profile after change events.
  280.    */
  281.  
  282.   _handleProfileAfterChange:
  283.     function sbAddOnBundleUpdateService__handleProfileAfterChange() {
  284.     // Preferences are now available.
  285.     this._prefsAvailable = true;
  286.  
  287.     // Initialize the services.
  288.     this._initialize();
  289.   },
  290.  
  291.  
  292.   /**
  293.    * Handle final UI startup events.
  294.    */
  295.  
  296.   _handleFinalUIStartup:
  297.     function sbAddOnBundleUpdateService__handleFinalUIStartup() {
  298.     // The network is now available.
  299.     //XXXeps trying to load the add-on bundle too early will result in a hang
  300.     //XXXeps during EM restart.  Not sure how to fix this better.
  301.     this._networkAvailable = true;
  302.  
  303.     // Initialize the services.
  304.     this._initialize();
  305.   },
  306.  
  307.  
  308.   /**
  309.    * Handle application quit events.
  310.    */
  311.  
  312.   _handleAppQuit: function sbAddOnBundleUpdateService__handleAppQuit() {
  313.     // Finalize the services.
  314.     this._finalize();
  315.   },
  316.  
  317.  
  318.   /**
  319.    * Handle add-on update timer events.
  320.    */
  321.  
  322.   _handleAddOnUpdateTimer:
  323.     function sbAddOnBundleUpdateService__handleAddOnUpdateTimer(aTimer) {
  324.     // Update the add-on bundle cache.
  325.     this._updateAddOnBundleCache(false);
  326.   },
  327.  
  328.  
  329.   //----------------------------------------------------------------------------
  330.   //
  331.   // Internal add-on bundle update services.
  332.   //
  333.   //----------------------------------------------------------------------------
  334.  
  335.   /**
  336.    * Initialize the services.
  337.    */
  338.  
  339.   _initialize: function sbAddOnBundleUpdateService__initialize() {
  340.     // Do nothing if already initialized.
  341.     if (this._isInitialized)
  342.       return;
  343.  
  344.     // Set up observers.
  345.     if (!this._observerSet) {
  346.       this._observerSet = new ObserverSet();
  347.       this._observerSet.add(this, "quit-application", false, false);
  348.       this._observerSet.add(this, "profile-after-change", false, true);
  349.       this._observerSet.add(this, "final-ui-startup", false, true);
  350.     }
  351.  
  352.     // Wait until preferences are available.
  353.     if (!this._prefsAvailable)
  354.       return;
  355.  
  356.     // Initialize the previous application version if first-run has not
  357.     // completed.  This needs to be done as soon as possible so it occurs before
  358.     // the first-run.
  359.     if (!this._checkedFirstRunHasCompleted) {
  360.       this._firstRunHasCompleted = SBUtils.hasFirstRunCompleted();
  361.       if (!this._firstRunHasCompleted)
  362.         this._updatePrevAppVersion();
  363.       this._checkedFirstRunHasCompleted = true;
  364.     }
  365.  
  366.     // Wait until the network is available.
  367.     if (!this._networkAvailable)
  368.       return;
  369.  
  370.     // Initialization is now complete.
  371.     this._isInitialized = true;
  372.  
  373.     // Don't check for add-on bundle updates if the first-run has not completed.
  374.     if (!this._firstRunHasCompleted)
  375.       return;
  376.  
  377.     // Get the application services.
  378.     var Application = Cc["@mozilla.org/fuel/application;1"]
  379.                         .getService(Ci.fuelIApplication);
  380.  
  381.     // Check if add-on bundle update is enabled.  Do nothing more if not.
  382.     this._updateEnabled =
  383.            Application.prefs.getValue(this._cfg.updateEnabledPref,
  384.                                       this._cfg.defaultUpdateEnabled);
  385.     if (!this._updateEnabled)
  386.       return;
  387.  
  388.     // Get the add-on bundle update period.
  389.     var updateInterval =
  390.           Application.prefs.getValue(this._cfg.updateIntervalPref,
  391.                                      this._cfg.defaultUpdateInterval);
  392.  
  393.     // Register an add-on bundle update timer.
  394.     /*XXXeps no way to unregister. */
  395.     var updateTimerMgr = Cc["@mozilla.org/updates/timer-manager;1"]
  396.                            .createInstance(Ci.nsIUpdateTimerManager);
  397.     var _this = this;
  398.     var func = function(aTimer) { _this._handleAddOnUpdateTimer(aTimer); };
  399.     updateTimerMgr.registerTimer("add-on-bundle-update-timer",
  400.                                  func,
  401.                                  updateInterval);
  402.   },
  403.  
  404.  
  405.   /**
  406.    * Finalize the services.
  407.    */
  408.  
  409.   _finalize: function sbAddOnBundleUpdateService__finalize() {
  410.     // Cancel the add-on bundle loader.
  411.     if (this._addOnBundleLoader) {
  412.       this._addOnBundleLoader.cancel();
  413.       this._addOnBundleLoader = null;
  414.     }
  415.  
  416.     // Remove observers.
  417.     if (this._observerSet) {
  418.       this._observerSet.removeAll();
  419.       this._observerSet = null;
  420.     }
  421.   },
  422.  
  423.  
  424.   /**
  425.    * Present the new add-ons to the user.
  426.    */
  427.  
  428.   _presentNewAddOns:
  429.     function sbAddOnBundleUpdateService__presentNewAddOns() {
  430.     // Load the add-on bundle.
  431.     var addOnBundle = this._loadNewAddOns();
  432.  
  433.     // Do nothing if no add-ons.
  434.     if (!addOnBundle || (addOnBundle.bundleExtensionCount == 0))
  435.       return;
  436.  
  437.     // Present the new add-ons.
  438.     var restartRequired = {};
  439.     WindowUtils.openModalDialog
  440.                   (null,
  441.                    "chrome://songbird/content/xul/recommendedAddOnsWizard.xul",
  442.                    "",
  443.                    "chrome,modal=yes,centerscreen",
  444.                    [ addOnBundle ],
  445.                    [ restartRequired ]);
  446.     this.restartRequired = (restartRequired.value == "true");
  447.   },
  448.  
  449.  
  450.   /**
  451.    * Load the new add-on bundle.
  452.    *
  453.    * \return                    New add-on bundle.
  454.    */
  455.  
  456.   _loadNewAddOns: function sbAddOnBundleUpdateService__loadNewAddOns() {
  457.     // Create an add-on bundle loader.
  458.     var addOnBundleLoader = new AddOnBundleLoader();
  459.  
  460.     // Add all installed add-ons to the blacklist.  This prevents an add-on
  461.     // from being presented if it was previously installed and then uninstalled.
  462.     AddOnBundleLoader.addInstalledAddOnsToBlacklist();
  463.  
  464.     // Load the add-on bundle from cache.
  465.     addOnBundleLoader.filterInstalledAddOns = true;
  466.     addOnBundleLoader.filterBlacklistedAddOns = true;
  467.     addOnBundleLoader.readFromCache = true;
  468.     addOnBundleLoader.start(null);
  469.  
  470.     // Check for add-on bundle loading errors.
  471.     if (!addOnBundleLoader.complete ||
  472.         !Components.isSuccessCode(addOnBundleLoader.result))
  473.       return null;
  474.  
  475.     return addOnBundleLoader.addOnBundle;
  476.   },
  477.  
  478.  
  479.   /**
  480.    * Update the add-on bundle cache.  If aSync is true, wait until the cache has
  481.    * been updated.
  482.    *
  483.    * \param aSync               If true, operate synchronously.
  484.    */
  485.  
  486.   _updateAddOnBundleCache:
  487.     function sbAddOnBundleUpdateService__updateAddOnBundleCache(aSync) {
  488.     // Start loading the add-on bundle into the cache.
  489.     if (!this._addOnBundleLoader) {
  490.       // Create an add-on bundle loader.
  491.       this._addOnBundleLoader = new AddOnBundleLoader();
  492.  
  493.       // Start loading the add-on bundle into the cache.
  494.       var _this = this;
  495.       var func = function() { _this._updateAddOnBundleCacheContinue(); }
  496.       this._addOnBundleLoader.start(func);
  497.     }
  498.  
  499.     // Wait for update to complete if operating synchronously.
  500.     if (aSync) {
  501.       // Get the current thread.
  502.       var threadManager = Cc["@mozilla.org/thread-manager;1"]
  503.                             .getService(Ci.nsIThreadManager);
  504.       currentThread = threadManager.currentThread;
  505.  
  506.       // Process events until update completes.
  507.       while (this._addOnBundleLoader && !this._addOnBundleLoader.complete) {
  508.         currentThread.processNextEvent(true);
  509.       }
  510.     }
  511.   },
  512.  
  513.  
  514.   /**
  515.    * Continue the add-on bundle cache update operation.
  516.    */
  517.  
  518.   _updateAddOnBundleCacheContinue:
  519.     function sbAddOnBundleUpdateService__updateAddOnBundleCacheContinue() {
  520.     // Clear the add-on bundle loader upon completion.
  521.     if (this._addOnBundleLoader.complete)
  522.       this._addOnBundleLoader = null;
  523.   },
  524.  
  525.  
  526.   /**
  527.    * Return true if the application was updated.
  528.    *
  529.    * \return                    True if application was updated.
  530.    */
  531.  
  532.   _getApplicationWasUpdated:
  533.     function sbAddOnBundleUpdateService__getApplicationWasUpdated() {
  534.     var updated = false;
  535.  
  536.     // Get the application services.
  537.     var Application = Cc["@mozilla.org/fuel/application;1"]
  538.                         .getService(Ci.fuelIApplication);
  539.  
  540.     // Get the current application version.
  541.     var appInfo = Cc["@mozilla.org/xre/app-info;1"]
  542.                     .getService(Ci.nsIXULAppInfo);
  543.     var appVersion = appInfo.version;
  544.  
  545.     // Get the previous application version.
  546.     var prevAppVersion =
  547.           Application.prefs.getValue(this._cfg.updatePrevAppVersionPref, "");
  548.  
  549.     // Check for application update.  If the previous application version
  550.     // preference has not been set, the application must have been updated from
  551.     // a version of the application before the add-on bundle update support was
  552.     // added.
  553.     if (!prevAppVersion || (prevAppVersion != appVersion))
  554.       updated = true;
  555.  
  556.     // Update the previous application version.
  557.     Application.prefs.setValue(this._cfg.updatePrevAppVersionPref, appVersion);
  558.  
  559.     return updated;
  560.   },
  561.  
  562.  
  563.   /**
  564.    * Update the previous application version preference with the current
  565.    * application version.
  566.    */
  567.  
  568.   _updatePrevAppVersion:
  569.     function sbAddOnBundleUpdateService__updatePrevAppVersion() {
  570.     // Get the current application version.
  571.     var appInfo = Cc["@mozilla.org/xre/app-info;1"]
  572.                     .getService(Ci.nsIXULAppInfo);
  573.     var appVersion = appInfo.version;
  574.  
  575.     // Update the previous application version.
  576.     var Application = Cc["@mozilla.org/fuel/application;1"]
  577.                         .getService(Ci.fuelIApplication);
  578.     Application.prefs.setValue(this._cfg.updatePrevAppVersionPref, appVersion);
  579.   }
  580. };
  581.  
  582.  
  583. //------------------------------------------------------------------------------
  584. //
  585. // Add-on bundle update service component services.
  586. //
  587. //------------------------------------------------------------------------------
  588.  
  589. function NSGetModule(compMgr, fileSpec) {
  590.   return XPCOMUtils.generateModule([sbAddOnBundleUpdateService]);
  591. }
  592.  
  593.