setupProgress.js
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 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 
38 Components.utils.import("resource://app/jsmodules/StringUtils.jsm");
39 
40 var label;
44 var n_ext;
45 var cur_ext;
47 var afailure = false;
48 var userCancel = false;
49 
52 
53 const VK_ENTER = 13;
54 const VK_ESCAPE = 27;
55 
56 const NS_BINDING_ABORTED = 0x804B0002;
57 
62 function init()
63 {
64  label = document.getElementById("setupprogress_label");
65  progressmeter = document.getElementById("setupprogress_progress");
66  cancelButton = document.getElementById("setupprogress_cancel");
67  bundle = window.arguments[0];
68  pbundle = bundle.QueryInterface(Components.interfaces.sbPIBundle);
69  pbundle.setNeedRestart(false);
70  bundle = bundle.QueryInterface(Components.interfaces.sbIBundle);
71  n_ext = bundle.bundleExtensionCount;
72  cur_ext = -1;
74 }
75 
80 function installNextXPI()
81 {
82  cur_ext++;
83  if (cur_ext + 1 > n_ext) {
84  var sbIBundle = Components.interfaces.sbIBundle;
85  pbundle.setInstallResult(afailure ? sbIBundle.BUNDLE_INSTALL_ERROR : sbIBundle.BUNDLE_INSTALL_SUCCESS);
86  for (var i = 0; i < pbundle.installListenerCount; i++)
87  pbundle.getInstallListener(i).onComplete(bundle);
88  window.close();
89  return;
90  }
91 
92 
93  if (!bundle.getExtensionInstallFlag(cur_ext)) {
95  return;
96  }
97 
98  var downloading = SBString("setupprogress.downloading", "Downloading");
99  label.setAttribute("value", downloading + " " + bundle.getExtensionAttribute(cur_ext, "name"));
100  cancelButton.removeAttribute("disabled");
101  userCancel = false;
102  progressmeter.setAttribute("value", 0);
103 
104  for (var i = 0; i < pbundle.installListenerCount; i++)
105  pbundle.getInstallListener(i).onExtensionDownloadProgress(bundle, cur_ext, 0, 1);
106 
107  destFile = downloadFile(bundle.getExtensionAttribute(cur_ext, "url"));
108 }
109 
114 function onExtensionDownloadProgress(aCurrentProgress, aMaxProgress) {
115  progressmeter.setAttribute("value", aCurrentProgress / aMaxProgress * 100);
116  for (var i=0; i < pbundle.installListenerCount; i++)
117  pbundle.getInstallListener(i).onExtensionDownloadProgress(pbundle, cur_ext, aCurrentProgress, aMaxProgress);
118 }
119 
125  for (var i = 0; i < pbundle.installListenerCount; i++)
126  pbundle.getInstallListener(i).onDownloadComplete(pbundle, cur_ext);
127  var succeeded = forceInstallXPI(destFile);
128  if (!succeeded) {
129  gPrompt.alert( window, "Error",
130  SBString( "setupprogress.couldnotinstall", "Could not install" ) + " " +
131  bundle.getExtensionAttribute(cur_ext, "name") );
132  for (var i = 0; i < pbundle.installListenerCount; i++)
133  pbundle.getInstallListener(i).onInstallError(pbundle, cur_ext);
134  } else {
135  pbundle.setNeedRestart(true);
136  }
138  for (var i = 0; i < pbundle.installListenerCount; i++)
139  pbundle.getInstallListener(i).onInstallComplete(pbundle, cur_ext);
141 }
142 
148  gPrompt.alert( window, "Error",
149  SBString( "setupprogress.couldnotdownload", "Downloading" ) + " " +
150  bundle.getExtensionAttribute(cur_ext, "name") );
151  afailure = true;
153  for (var i=0;i<pbundle.installListenerCount;i++)
154  pbundle.getInstallListener(i).onDownloadError(pbundle, cur_ext);
156 }
157 
164 {
165  if (event.keyCode == VK_ESCAPE ||
166  event.keyCode == VK_ENTER) {
167  event.preventDefault();
168  }
169 }
170 
171 // -------------------
172 
178  onLocationChange: function(aWebProgress, aRequest, aLocation)
179  {
180  },
181 
182  onProgressChange: function(aWebProgress, aRequest, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress)
183  {
184  onExtensionDownloadProgress(curSelfProgress, maxSelfProgress);
185  },
186 
187  onSecurityChange: function(aWebProgress, aRequest, aStateFlags)
188  {
189  },
190 
191  onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
192  {
193  if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
194  {
195  if ( (aStatus == NS_BINDING_ABORTED) && userCancel ) {
196  // User canceled so delete the downloaded file if any and
197  // skip this file and move on to the next one
199  // Give the user some time to notice the cancel.
200  setTimeout(installNextXPI, 2000);
201  } else {
202  try {
203  var succeeded = true;
204  if (aRequest instanceof Components.interfaces.nsIHttpChannel) {
205  if (!aRequest.requestSucceeded) {
206  succeeded = false;
207  }
208  }
209  var file = Components.classes["@mozilla.org/file/local;1"]
210  .createInstance(Components.interfaces.nsILocalFile);
211  file.initWithPath(_filename);
212  if (!file.exists()) {
213  succeeded = false;
214  }
215  if (succeeded)
217  else
219  } catch (e) {
220  dump(e + "\n");
222  }
223  }
224  }
225  },
226 
227  onStatusChange: function(aWebProgress, aRequest, aStateFlags, strStateMessage)
228  {
229  },
230 
231  QueryInterface: function(iid) {
232  if (!iid.equals(Components.interfaces.nsIWebProgressListener) &&
233  !iid.equals(Components.interfaces.nsISupportsWeakReference) &&
234  !iid.equals(Components.interfaces.nsISupports))
235  throw Components.results.NS_ERROR_NO_INTERFACE;
236  return this;
237  }
238 }
239 
240 var _url;
243 var _file;
244 
252 function downloadFile(url) {
253  _url = url;
254 
255  var destFile = getTempFilename() + ".xpi";
256  _filename = destFile;
257  _browser = (Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]).createInstance(Components.interfaces.nsIWebBrowserPersist);
258 
259  if (!_browser) return null;
260  _browser.progressListener = _downloadListener;
261 
262  var aLocalFile = (Components.classes["@mozilla.org/file/local;1"]).createInstance(Components.interfaces.nsILocalFile);
263  aLocalFile.initWithPath(destFile);
264  _file = aLocalFile;
265 
266  var aLocalURI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI(url + getRandomParameter(), null, null);
267 
268  const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
269  var flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
270  nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
271  _browser.persistFlags = flags;
272 
273  _browser.saveURI(aLocalURI, null, null, null, "", aLocalFile);
274 
275  return destFile;
276 }
277 
278 function cancelDownload() {
279 
280  if (!_browser) return;
281 
282  var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
283  .getService(Components.interfaces.nsIStringBundleService);
284  var songbirdStrings = sbs.createBundle("chrome://songbird/locale/songbird.properties");
285  var cancelling = "Cancelling" + " " + bundle.getExtensionAttribute(cur_ext, "name");
286  try {
287  var params = [ bundle.getExtensionAttribute(cur_ext, "name") ];
288  cancelling = songbirdStrings.formatStringFromName("setupprogress.cancelling",
289  params, params.length);
290  } catch (e) {}
291  label.setAttribute("value", cancelling);
292  cancelButton.disabled = true;
293  progressmeter.setAttribute("value", 0);
294  userCancel = true;
295 
296  // Cancel the save, this will cause onStageChange to fire with a status
297  // of NS_BINDING_ABORTED
298  _browser.cancelSave();
299 }
300 
306  if (_file) {
307  try {
308  _file.remove(true);
309  } catch (e) {}
310  _file = null;
311  _filename = null;
312  }
313 }
314 
319 function getTempFilename() {
320  var strTempFile = "";
321 
322  var aDirectoryService = Components.classes["@mozilla.org/file/directory_service;1"].createInstance();
323  aDirectoryService = aDirectoryService.QueryInterface(Components.interfaces.nsIProperties);
324 
325  var aUUID = generateUUID();
326 
327  var bResult = new Object;
328  var aTempFolder = aDirectoryService.get("DefProfLRt", Components.interfaces.nsIFile, bResult);
329 
330  aTempFolder.append(aUUID);
331 
332  return aTempFolder.path;
333 }
334 
340 function generateUUID() {
341  var aUUIDGenerator = (Components.classes["@mozilla.org/uuid-generator;1"]).createInstance();
342  aUUIDGenerator = aUUIDGenerator.QueryInterface(Components.interfaces.nsIUUIDGenerator);
343  return aUUIDGenerator.generateUUID();
344 }
345 
351 function getRandomParameter() {
352  return "?randomguid=" + escape(generateUUID());
353 }
354 
363 function forceInstallXPI(localFilename)
364 {
365  var file = Components.classes["@mozilla.org/file/local;1"]
366  .createInstance(Components.interfaces.nsILocalFile);
367  file.initWithPath(localFilename);
368 
369  var em = Components.classes["@mozilla.org/extensions/manager;1"]
370  .getService(Components.interfaces.nsIExtensionManager);
371  try {
372  em.installItemFromFile(file, "app-profile");
373  return true;
374  } catch (e) {}
375  return false;
376 }
const BUNDLE_ERROR_XPIINSTALLFAILED
function installNextXPI()
Install the next XPI in the list of XPIs to install.
function getTempFilename()
Get a temporary file name.
var cancelButton
var label
function succeeded(ch, cx, status, data)
sbDeviceFirmwareAutoCheckForUpdate prototype flags
function handleKeyDown(event)
Handler function used to prevent bubbling of escape and enter key events while the progressSetup dial...
var event
var _filename
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
function getRandomParameter()
Generate a random URL parameter.
function generateUUID()
Generate a UUID.
function init()
Initialize the setupProgress dialog.
function SBString(aKey, aDefault, aStringBundle)
Definition: StringUtils.jsm:93
let window
var destFile
var bundle
var pbundle
function onExtensionDownloadError()
Listener function used to recover from any errors that occur during the download of an XPI...
const VK_ESCAPE
var cur_ext
function downloadFile(url)
Download an XPI file from a URL. Downloads an XPI file from a URL to a temporary file on disk...
aWindow setTimeout(function(){_this.restoreHistory(aWindow, aTabs, aTabData, aIdMap);}, 0)
var n_ext
var _file
var afailure
return null
Definition: FeedWriter.js:1143
function deleteLastDownloadedFile()
Delete the last downloaded XPI file.
const NS_BINDING_ABORTED
function forceInstallXPI(localFilename)
Force installation of an XPI. This method will install the XPI without asking the user's permission...
function url(spec)
var gPrompt
Definition: windowUtils.js:64
const BUNDLE_ERROR_DOWNLOADFAILED
Songbird Bundle Interface This is the main bundle management interface, used to get the bundle data...
Definition: sbIBundle.idl:50
ContinuingWebProgressListener prototype onStateChange
var progressmeter
var userCancel
var _browser
function cancelDownload()
function onExtensionDownloadProgress(aCurrentProgress, aMaxProgress)
Listener function used to track progress of XPIs being downloaded.
var _downloadListener
Download listener object used to track progress of XPI downloads.
const VK_ENTER
_getSelectedPageStyle s i
function onExtensionDownloadComplete()
Listener function used to trigger installation of XPI when download is complete.
var file