sbDeviceFirmwareDownloader.cpp
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2010 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
26 
27 #include <nsIFile.h>
28 #include <nsIHttpChannel.h>
29 #include <nsIIOService.h>
30 #include <nsILocalFile.h>
31 #include <nsIMultiPartChannel.h>
32 #include <nsIProperties.h>
33 #include <nsIPropertyBag2.h>
34 #include <nsITextToSubURI.h>
35 #include <nsIURL.h>
36 #include <nsIUTF8ConverterService.h>
37 #include <nsIVariant.h>
38 
39 #include <nsAppDirectoryServiceDefs.h>
40 #include <nsAutoLock.h>
41 #include <nsCRT.h>
42 #include <nsHashKeys.h>
43 #include <nsServiceManagerUtils.h>
44 #include <nsXPCOM.h>
45 #include <prmem.h>
46 
47 #include <sbIDevice.h>
48 #include <sbIDeviceEventTarget.h>
49 #include <sbIDeviceProperties.h>
50 
52 #include <sbStringUtils.h>
53 #include <sbVariantUtils.h>
54 
55 #include "sbDeviceFirmwareUpdate.h"
56 
57 #define FIRMWARE_FILE_PREF "firmware.cache.file"
58 #define FIRMWARE_VERSION_PREF "firmware.cache.version"
59 #define FIRMWARE_READABLE_PREF "firmware.cache.readableVersion"
60 #define FIRMWARE_CACHE_ROOT_NAME "firmware_cache"
61 #define FIRMWARE_CACHE_LAYOUT_VERSION_2_NAME "v2"
62 #define FIRMWARE_CACHE_CURRENT_VERSION_NAME FIRMWARE_CACHE_LAYOUT_VERSION_2_NAME
63 
64 static PRInt32
65 codetovalue( unsigned char c )
66 {
67  if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') ) {
68  return (PRInt32)(c - (unsigned char)'A');
69  }
70  else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') ) {
71  return ((PRInt32)(c - (unsigned char)'a') +26);
72  }
73  else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') ) {
74  return ((PRInt32)(c - (unsigned char)'0') +52);
75  }
76  else if( (unsigned char)'+' == c ) {
77  return (PRInt32)62;
78  }
79  else if( (unsigned char)'/' == c ) {
80  return (PRInt32)63;
81  }
82 
83  return -1;
84 }
85 
86 static PRStatus
87 decode4to3( const unsigned char *src,
88  unsigned char *dest )
89 {
90  PRUint32 b32 = (PRUint32)0;
91  PRInt32 bits = 0;
92  PRIntn i = 0;
93 
94  for( i = 0; i < 4; i++ ) {
95  bits = codetovalue(src[i]);
96  if( bits < 0 ) {
97  return PR_FAILURE;
98  }
99  b32 <<= 6;
100  b32 |= bits;
101  }
102 
103  dest[0] = (unsigned char)((b32 >> 16) & 0xFF);
104  dest[1] = (unsigned char)((b32 >> 8) & 0xFF);
105  dest[2] = (unsigned char)((b32 ) & 0xFF);
106 
107  return PR_SUCCESS;
108 }
109 
110 static PRStatus
111 decode3to2( const unsigned char *src,
112  unsigned char *dest )
113 {
114  PRUint32 b32 = (PRUint32)0;
115  PRInt32 bits = 0;
116  PRUint32 ubits = 0;
117 
118  bits = codetovalue(src[0]);
119  if( bits < 0 ) {
120  return PR_FAILURE;
121  }
122 
123  b32 = (PRUint32)bits;
124  b32 <<= 6;
125 
126  bits = codetovalue(src[1]);
127  if( bits < 0 ) {
128  return PR_FAILURE;
129  }
130 
131  b32 |= (PRUint32)bits;
132  b32 <<= 4;
133 
134  bits = codetovalue(src[2]);
135  if( bits < 0 ) {
136  return PR_FAILURE;
137  }
138 
139  ubits = (PRUint32)bits;
140  b32 |= (ubits >> 2);
141 
142  dest[0] = (unsigned char)((b32 >> 8) & 0xFF);
143  dest[1] = (unsigned char)((b32 ) & 0xFF);
144 
145  return PR_SUCCESS;
146 }
147 
148 static PRStatus
149 decode2to1( const unsigned char *src,
150  unsigned char *dest )
151 {
152  PRUint32 b32 = 0;
153  PRUint32 ubits = 0;
154  PRInt32 bits = 0;
155 
156  bits = codetovalue(src[0]);
157  if( bits < 0 ) {
158  return PR_FAILURE;
159  }
160 
161  ubits = (PRUint32)bits;
162  b32 = (ubits << 2);
163 
164  bits = codetovalue(src[1]);
165  if( bits < 0 ) {
166  return PR_FAILURE;
167  }
168 
169  ubits = (PRUint32)bits;
170  b32 |= (ubits >> 4);
171 
172  dest[0] = (unsigned char)b32;
173 
174  return PR_SUCCESS;
175 }
176 
177 static PRStatus
178 decode( const unsigned char *src,
179  PRUint32 srclen,
180  unsigned char *dest )
181 {
182  PRStatus rv = PR_SUCCESS;
183 
184  while( srclen >= 4 ) {
185  rv = decode4to3(src, dest);
186  if( PR_SUCCESS != rv ) {
187  return PR_FAILURE;
188  }
189 
190  src += 4;
191  dest += 3;
192  srclen -= 4;
193  }
194 
195  switch( srclen ) {
196  case 3:
197  rv = decode3to2(src, dest);
198  break;
199  case 2:
200  rv = decode2to1(src, dest);
201  break;
202  case 1:
203  rv = PR_FAILURE;
204  break;
205  case 0:
206  rv = PR_SUCCESS;
207  break;
208  default:
209  PR_NOT_REACHED("coding error");
210  }
211 
212  return rv;
213 }
214 
215 static char *
216 SB_Base64Decode( const char *src,
217  PRUint32 srclen,
218  char *dest )
219 {
220  PRStatus status;
221  PRBool allocated = PR_FALSE;
222 
223  if( (char *)0 == src ) {
224  return (char *)0;
225  }
226 
227  if( 0 == srclen ) {
228  srclen = strlen(src);
229  }
230 
231  if( srclen && (0 == (srclen & 3)) ) {
232  if( (char)'=' == src[ srclen-1 ] ) {
233  if( (char)'=' == src[ srclen-2 ] ) {
234  srclen -= 2;
235  }
236  else {
237  srclen -= 1;
238  }
239  }
240  }
241 
242  if( (char *)0 == dest ) {
243  PRUint32 destlen = ((srclen * 3) / 4);
244  dest = (char *)PR_MALLOC(destlen + 1);
245  if( (char *)0 == dest ) {
246  return (char *)0;
247  }
248  dest[ destlen ] = (char)0; /* null terminate */
249  allocated = PR_TRUE;
250  }
251 
252  status = decode((const unsigned char *)src, srclen, (unsigned char *)dest);
253  if( PR_SUCCESS != status ) {
254  if( PR_TRUE == allocated ) {
255  PR_DELETE(dest);
256  }
257  return (char *)0;
258  }
259 
260  return dest;
261 }
262 
263 static nsCString
264 GetContentDispositionFilename(const nsACString &contentDisposition)
265 {
266  NS_NAMED_LITERAL_CSTRING(DISPOSITION_ATTACHEMENT, "attachment");
267  NS_NAMED_LITERAL_CSTRING(DISPOSITION_FILENAME, "filename=");
268 
269  nsCAutoString unicodeDisposition(contentDisposition);
270  unicodeDisposition.StripWhitespace();
271 
272  PRInt32 pos = unicodeDisposition.Find(DISPOSITION_ATTACHEMENT,
273  CaseInsensitiveCompare);
274  if(pos == -1 )
275  return EmptyCString();
276 
277  pos = unicodeDisposition.Find(DISPOSITION_FILENAME,
278  CaseInsensitiveCompare);
279  if(pos == -1)
280  return EmptyCString();
281 
282  pos += DISPOSITION_FILENAME.Length();
283 
284  // if the string is quoted, we look for the next quote to know when the
285  // filename ends.
286  PRInt32 endPos = -1;
287  if(unicodeDisposition.CharAt(pos) == '"') {
288 
289  pos++;
290  endPos = unicodeDisposition.FindChar('\"', pos);
291 
292  if(endPos == -1)
293  return EmptyCString();
294  }
295  // if not, we find the next ';' or we take the rest.
296  else {
297  endPos = unicodeDisposition.FindChar(';', pos);
298 
299  if(endPos == -1) {
300  endPos = unicodeDisposition.Length();
301  }
302  }
303 
304  nsCString filename(Substring(unicodeDisposition, pos, endPos - pos));
305 
306  // string is encoded in a different character set.
307  if(StringBeginsWith(filename, NS_LITERAL_CSTRING("=?")) &&
308  StringEndsWith(filename, NS_LITERAL_CSTRING("?="))) {
309 
310  nsresult rv;
311  nsCOMPtr<nsIUTF8ConverterService> convServ =
312  do_GetService("@mozilla.org/intl/utf8converterservice;1", &rv);
313  NS_ENSURE_SUCCESS(rv, EmptyCString());
314 
315  pos = 2;
316  endPos = filename.FindChar('?', pos);
317 
318  if(endPos == -1)
319  return EmptyCString();
320 
321  // found the charset
322  nsCAutoString charset(Substring(filename, pos, endPos - pos));
323  pos = endPos + 1;
324 
325  // find what encoding for the character set is used.
326  endPos = filename.FindChar('?', pos);
327 
328  if(endPos == -1)
329  return EmptyCString();
330 
331  nsCAutoString encoding(Substring(filename, pos, endPos - pos));
332  pos = endPos + 1;
333 
334  ToLowerCase(encoding);
335 
336  // bad encoding.
337  if(!encoding.EqualsLiteral("b") &&
338  !encoding.EqualsLiteral("q")) {
339  return EmptyCString();
340  }
341 
342  // end of actual string to decode marked by ?=
343  endPos = filename.FindChar('?', pos);
344  // didn't find end, bad string
345  if(endPos == -1 ||
346  filename.CharAt(endPos + 1) != '=')
347  return EmptyCString();
348 
349  nsCAutoString convertedFilename;
350  nsCAutoString filenameToDecode(Substring(filename, pos, endPos - pos));
351 
352  if(encoding.EqualsLiteral("b")) {
353  char *str = SB_Base64Decode(filenameToDecode.get(), filenameToDecode.Length(), nsnull);
354 
355  nsDependentCString strToConvert(str);
356  rv = convServ->ConvertStringToUTF8(strToConvert, charset.get(), PR_TRUE, convertedFilename);
357 
358  PR_Free(str);
359  }
360  else if(encoding.EqualsLiteral("q")) {
361  NS_WARNING("XXX: No support for Q encoded strings!");
362  }
363 
364  if(NS_SUCCEEDED(rv)) {
365  filename = convertedFilename;
366  }
367  }
368 
369  nsCString_ReplaceChars(filename,
370  nsDependentCString(FILE_ILLEGAL_CHARACTERS),
371  '_');
372 
373  return filename;
374 }
375 
376 static nsresult UnescapeFragment(const nsACString& aFragment, nsIURI* aURI,
377  nsAString& aResult)
378 {
379  // First, we need a charset
380  nsCAutoString originCharset;
381  nsresult rv = aURI->GetOriginCharset(originCharset);
382  NS_ENSURE_SUCCESS(rv, rv);
383 
384  // Now, we need the unescaper
385  nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
386  NS_ENSURE_SUCCESS(rv, rv);
387 
388  return textToSubURI->UnEscapeURIForUI(originCharset, aFragment, aResult);
389 }
390 
391 static nsresult UnescapeFragment(const nsACString& aFragment, nsIURI* aURI,
392  nsACString& aResult)
393 {
394  nsAutoString result;
395  nsresult rv = UnescapeFragment(aFragment, aURI, result);
396  if (NS_SUCCEEDED(rv)) {
397  aResult = NS_ConvertUTF16toUTF8(result);
398  }
399  return rv;
400 }
401 
404 
406 : mIsBusy(PR_FALSE)
407 {
408 }
409 
411 {
412 }
413 
414 nsresult
416  sbIDeviceEventListener *aListener,
417  sbIDeviceFirmwareHandler *aHandler)
418 {
419  NS_ENSURE_ARG_POINTER(aDevice);
420  NS_ENSURE_ARG_POINTER(aHandler);
421 
422  NS_ENSURE_FALSE(mDevice, NS_ERROR_ALREADY_INITIALIZED);
423  NS_ENSURE_FALSE(mHandler, NS_ERROR_ALREADY_INITIALIZED);
424 
425  mDevice = aDevice;
426  mListener = aListener;
427  mHandler = aHandler;
428 
429  nsresult rv = NS_ERROR_UNEXPECTED;
430 
431  mDownloader = do_CreateInstance(SB_FILEDOWNLOADER_CONTRACTID, &rv);
432  NS_ENSURE_SUCCESS(rv, rv);
433 
434  rv = mDownloader->SetListener(this);
435  NS_ENSURE_SUCCESS(rv, rv);
436 
437  rv = CreateCacheRoot(getter_AddRefs(mCacheDir));
438  NS_ENSURE_SUCCESS(rv, rv);
439 
440  rv = CreateCacheDirForDevice(mDevice,
441  mCacheDir,
442  getter_AddRefs(mDeviceCacheDir));
443  NS_ENSURE_SUCCESS(rv, rv);
444 
445  return NS_OK;
446 }
447 
448 nsresult
450  const nsAString &aCacheDirName,
451  sbIDeviceEventListener *aListener,
452  sbIDeviceFirmwareHandler *aHandler)
453 {
454  NS_ENSURE_ARG_POINTER(aDevice);
455  NS_ENSURE_ARG_POINTER(aHandler);
456 
457  NS_ENSURE_FALSE(mDevice, NS_ERROR_ALREADY_INITIALIZED);
458  NS_ENSURE_FALSE(mHandler, NS_ERROR_ALREADY_INITIALIZED);
459 
460  mDevice = aDevice;
461  mListener = aListener;
462  mHandler = aHandler;
463 
464  nsresult rv = NS_ERROR_UNEXPECTED;
465 
466  mDownloader = do_CreateInstance(SB_FILEDOWNLOADER_CONTRACTID, &rv);
467  NS_ENSURE_SUCCESS(rv, rv);
468 
469  rv = mDownloader->SetListener(this);
470  NS_ENSURE_SUCCESS(rv, rv);
471 
472  rv = CreateCacheRoot(getter_AddRefs(mCacheDir));
473  NS_ENSURE_SUCCESS(rv, rv);
474 
475  rv = CreateCacheDirForDevice(aCacheDirName,
476  mCacheDir,
477  getter_AddRefs(mDeviceCacheDir));
478  NS_ENSURE_SUCCESS(rv, rv);
479 
480  return NS_OK;
481 }
482 
483 /*static*/ nsresult
485 {
486  // Initialize the cache
487  nsresult rv = NS_ERROR_UNEXPECTED;
488  nsCOMPtr<nsIProperties> directoryService =
489  do_GetService("@mozilla.org/file/directory_service;1", &rv);
490  NS_ENSURE_SUCCESS(rv, rv);
491 
492  nsCOMPtr<nsIFile> localDataDir;
493  rv = directoryService->Get(NS_APP_USER_PROFILE_LOCAL_50_DIR,
494  NS_GET_IID(nsIFile),
495  getter_AddRefs(localDataDir));
496  NS_ENSURE_SUCCESS(rv, rv);
497 
498  if(!localDataDir) {
499  rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
500  NS_GET_IID(nsIFile),
501  getter_AddRefs(localDataDir));
502  NS_ENSURE_SUCCESS(rv, rv);
503  }
504 
505  NS_ENSURE_TRUE(localDataDir, NS_ERROR_UNEXPECTED);
506 
507  nsCOMPtr<nsIFile> cacheDir;
508  rv = localDataDir->Clone(getter_AddRefs(cacheDir));
509  NS_ENSURE_SUCCESS(rv, rv);
510 
511  NS_NAMED_LITERAL_STRING(firmwareCacheName, FIRMWARE_CACHE_ROOT_NAME);
512  rv = cacheDir->Append(firmwareCacheName);
513  NS_ENSURE_SUCCESS(rv, rv);
514 
515  // The cache root directory should contain a subdirectory whose
516  // name is the current cache version. If the subdirectory exists,
517  // then the cache is arranged in the structure that this code
518  // recognizes. Otherwise, the cache either does not exist or it
519  // uses an unknown structure.
520  nsCOMPtr<nsIFile> cacheVersionDir;
521  rv = cacheDir->Clone(getter_AddRefs(cacheVersionDir));
522  NS_ENSURE_SUCCESS(rv, rv);
523 
524  NS_NAMED_LITERAL_STRING(versionName, FIRMWARE_CACHE_CURRENT_VERSION_NAME);
525  rv = cacheVersionDir->Append(versionName);
526  NS_ENSURE_SUCCESS(rv, rv);
527 
528  // Check whether the desired cache version directory exists:
529  PRBool exists = PR_FALSE;
530  PRBool isDirectory = PR_FALSE;
531 
532  rv = cacheVersionDir->Exists(&exists);
533  NS_ENSURE_SUCCESS(rv, rv);
534 
535  if(exists) {
536  rv = cacheVersionDir->IsDirectory(&isDirectory);
537  NS_ENSURE_SUCCESS(rv, rv);
538  }
539 
540  // If the desired version directory does not exist, delete the entire
541  // firmware cache root directory to expel any unknown versions, and
542  // then create the desired version directory. Another approach would
543  // be to migrate data from older cache versions to the current version,
544  // but any unrecognized cache content should normally be deleted to
545  // reclaim its space.
546  if(!isDirectory) {
547  rv = cacheDir->Exists(&exists);
548  NS_ENSURE_SUCCESS(rv, rv);
549  if (exists) {
550  rv = cacheDir->Remove(PR_TRUE); // PR_TRUE = recursive
551  NS_ENSURE_SUCCESS(rv, rv);
552  }
553 
554  rv = cacheVersionDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
555  NS_ENSURE_SUCCESS(rv, rv);
556  }
557 
558  PRBool isReadable = PR_FALSE;
559  PRBool isWritable = PR_FALSE;
560 
561  rv = cacheVersionDir->IsReadable(&isReadable);
562  NS_ENSURE_SUCCESS(rv, rv);
563 
564  rv = cacheVersionDir->IsWritable(&isWritable);
565  NS_ENSURE_SUCCESS(rv, rv);
566 
567  NS_ENSURE_TRUE(isReadable, NS_ERROR_FAILURE);
568  NS_ENSURE_TRUE(isWritable, NS_ERROR_FAILURE);
569 
570  cacheVersionDir.forget(aCacheRoot);
571 
572  return NS_OK;
573 }
574 
575 /*static*/ nsresult
577  nsIFile *aCacheRoot,
578  nsIFile **aCacheDir)
579 {
580  NS_ENSURE_ARG_POINTER(aDevice);
581  NS_ENSURE_ARG_POINTER(aCacheRoot);
582  NS_ENSURE_ARG_POINTER(aCacheDir);
583 
584  nsCOMPtr<sbIDeviceProperties> properties;
585  nsresult rv = aDevice->GetProperties(getter_AddRefs(properties));
586  NS_ENSURE_SUCCESS(rv, rv);
587 
588  nsString deviceDirStr;
589  rv = properties->GetVendorName(deviceDirStr);
590  NS_ENSURE_SUCCESS(rv, rv);
591 
592  nsCOMPtr<nsIVariant> modelNumber;
593  rv = properties->GetModelNumber(getter_AddRefs(modelNumber));
594  NS_ENSURE_SUCCESS(rv, rv);
595 
596  nsString modelNumberStr;
597  rv = modelNumber->GetAsAString(modelNumberStr);
598  NS_ENSURE_SUCCESS(rv, rv);
599 
600  deviceDirStr.AppendLiteral(" ");
601  deviceDirStr.Append(modelNumberStr);
602 
603  rv = CreateCacheDirForDevice(deviceDirStr, aCacheRoot, aCacheDir);
604  NS_ENSURE_SUCCESS(rv, rv);
605 
606  return NS_OK;
607 }
608 
609 /*static*/ nsresult
611  const nsAString &aCacheDirName,
612  nsIFile *aCacheRoot,
613  nsIFile **aCacheDir)
614 {
615  NS_ENSURE_ARG_POINTER(aCacheRoot);
616  NS_ENSURE_ARG_POINTER(aCacheDir);
617 
618  nsCOMPtr<nsIFile> deviceCacheDir;
619  nsresult rv = aCacheRoot->Clone(getter_AddRefs(deviceCacheDir));
620  NS_ENSURE_SUCCESS(rv, rv);
621 
622  rv = deviceCacheDir->Append(aCacheDirName);
623  NS_ENSURE_SUCCESS(rv, rv);
624 
625  PRBool exists = PR_FALSE;
626  PRBool isDirectory = PR_FALSE;
627 
628  rv = deviceCacheDir->Exists(&exists);
629  NS_ENSURE_SUCCESS(rv, rv);
630 
631  if(!exists) {
632  rv = deviceCacheDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
633  NS_ENSURE_SUCCESS(rv, rv);
634  }
635 
636  rv = deviceCacheDir->IsDirectory(&isDirectory);
637  NS_ENSURE_SUCCESS(rv, rv);
638 
639  if(!isDirectory) {
640  rv = deviceCacheDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
641  NS_ENSURE_SUCCESS(rv, rv);
642  }
643 
644  PRBool isReadable = PR_FALSE;
645  PRBool isWritable = PR_FALSE;
646 
647  rv = deviceCacheDir->IsReadable(&isReadable);
648  NS_ENSURE_SUCCESS(rv, rv);
649 
650  rv = deviceCacheDir->IsWritable(&isWritable);
651  NS_ENSURE_SUCCESS(rv, rv);
652 
653  NS_ENSURE_TRUE(isReadable, NS_ERROR_FAILURE);
654  NS_ENSURE_TRUE(isWritable, NS_ERROR_FAILURE);
655 
656  deviceCacheDir.forget(aCacheDir);
657 
658  return NS_OK;
659 }
660 
661 /*static*/ nsresult
663  sbIDeviceFirmwareUpdate *aFirmwareUpdate,
664  sbIDeviceFirmwareUpdate **aCachedFirmwareUpdate)
665 {
666  nsString cacheDirName;
667  cacheDirName.SetIsVoid(PR_TRUE);
668 
669  nsresult rv = CacheFirmwareUpdate(aDevice,
670  cacheDirName,
671  aFirmwareUpdate,
672  aCachedFirmwareUpdate);
673  NS_ENSURE_SUCCESS(rv, rv);
674 
675  return NS_OK;
676 }
677 
678 /*static*/ nsresult
680  sbIDevice *aDevice,
681  const nsAString &aCacheDirName,
682  sbIDeviceFirmwareUpdate *aFirmwareUpdate,
683  sbIDeviceFirmwareUpdate **aCachedFirmwareUpdate)
684 {
685  NS_ENSURE_ARG_POINTER(aDevice);
686  NS_ENSURE_ARG_POINTER(aFirmwareUpdate);
687 
688  nsCOMPtr<nsIFile> cacheRoot;
689  nsresult rv = CreateCacheRoot(getter_AddRefs(cacheRoot));
690  NS_ENSURE_SUCCESS(rv, rv);
691 
692  nsCOMPtr<nsIFile> deviceCache;
693  if(aCacheDirName.IsVoid() || aCacheDirName.IsEmpty()) {
694  rv = CreateCacheDirForDevice(aDevice,
695  cacheRoot,
696  getter_AddRefs(deviceCache));
697  NS_ENSURE_SUCCESS(rv, rv);
698  }
699  else {
700  rv = CreateCacheDirForDevice(aCacheDirName,
701  cacheRoot,
702  getter_AddRefs(deviceCache));
703  NS_ENSURE_SUCCESS(rv, rv);
704  }
705 
706  nsCOMPtr<nsIFile> firmwareFile;
707  rv = aFirmwareUpdate->GetFirmwareImageFile(getter_AddRefs(firmwareFile));
708  NS_ENSURE_SUCCESS(rv, rv);
709 
710  nsString firmwareReadableVersion;
711  rv = aFirmwareUpdate->GetFirmwareReadableVersion(firmwareReadableVersion);
712  NS_ENSURE_SUCCESS(rv, rv);
713 
714  PRUint32 firmwareVersion = 0;
715  rv = aFirmwareUpdate->GetFirmwareVersion(&firmwareVersion);
716  NS_ENSURE_SUCCESS(rv, rv);
717 
718  nsString leafName;
719  rv = firmwareFile->GetLeafName(leafName);
720  NS_ENSURE_SUCCESS(rv, rv);
721 
722  nsCOMPtr<nsIFile> finalDestFile;
723  rv = deviceCache->Clone(getter_AddRefs(finalDestFile));
724  NS_ENSURE_SUCCESS(rv, rv);
725 
726  rv = finalDestFile->Append(leafName);
727  NS_ENSURE_SUCCESS(rv, rv);
728 
729  PRBool exists = PR_FALSE;
730  rv = finalDestFile->Exists(&exists);
731  NS_ENSURE_SUCCESS(rv, rv);
732 
733  if(exists) {
734  rv = finalDestFile->Remove(PR_FALSE);
735  NS_ENSURE_SUCCESS(rv, rv);
736  }
737 
738  rv = firmwareFile->CopyTo(deviceCache, leafName);
739  NS_ENSURE_SUCCESS(rv, rv);
740 
741  nsString firmwarePath;
742  rv = deviceCache->GetPath(firmwarePath);
743  NS_ENSURE_SUCCESS(rv, rv);
744 
745  nsCOMPtr<nsILocalFile> newFirmwareFile;
746  rv = NS_NewLocalFile(firmwarePath, PR_FALSE, getter_AddRefs(newFirmwareFile));
747  NS_ENSURE_SUCCESS(rv, rv);
748 
749  rv = newFirmwareFile->Append(leafName);
750  NS_ENSURE_SUCCESS(rv, rv);
751 
752  nsCOMPtr<nsIVariant> firmwareVersionVariant =
753  sbNewVariant(firmwareVersion).get();
754  rv = aDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_VERSION_PREF),
755  firmwareVersionVariant);
756  NS_ENSURE_SUCCESS(rv, rv);
757 
758  nsCOMPtr<nsIVariant> firmwareReadableVariant =
759  sbNewVariant(firmwareReadableVersion).get();
760  rv = aDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_READABLE_PREF),
761  firmwareReadableVariant);
762  NS_ENSURE_SUCCESS(rv, rv);
763 
764  nsString newFirmwareFilePath;
765  rv = newFirmwareFile->GetPath(newFirmwareFilePath);
766  NS_ENSURE_SUCCESS(rv, rv);
767 
768  nsCOMPtr<nsIVariant> firmwareFileVariant =
769  sbNewVariant(newFirmwareFilePath).get();
770  rv = aDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_FILE_PREF),
771  firmwareFileVariant);
772  NS_ENSURE_SUCCESS(rv, rv);
773 
774  nsCOMPtr<sbIDeviceFirmwareUpdate> firmwareUpdate =
775  do_CreateInstance(SB_DEVICEFIRMWAREUPDATE_CONTRACTID, &rv);
776  NS_ENSURE_SUCCESS(rv, rv);
777 
778  rv = firmwareUpdate->Init(newFirmwareFile,
779  firmwareReadableVersion,
780  firmwareVersion);
781  NS_ENSURE_SUCCESS(rv, rv);
782 
783  firmwareUpdate.forget(aCachedFirmwareUpdate);
784 
785  return NS_OK;
786 }
787 
788 /*static*/ nsresult
790  nsIFile **aNewDir)
791 {
792  NS_ENSURE_ARG_POINTER(aNewDir);
793 
794  NS_ENSURE_TRUE(!aDirName.IsEmpty(), NS_ERROR_INVALID_ARG);
795 
796  nsCOMPtr<nsIFile> cacheRoot;
797  nsresult rv =
798  sbDeviceFirmwareDownloader::CreateCacheRoot(getter_AddRefs(cacheRoot));
799  NS_ENSURE_SUCCESS(rv, rv);
800 
801  nsCOMPtr<nsIFile> cacheDir;
802  rv = cacheRoot->Clone(getter_AddRefs(cacheDir));
803  NS_ENSURE_SUCCESS(rv, rv);
804 
805  rv = cacheDir->Append(aDirName);
806  NS_ENSURE_SUCCESS(rv, rv);
807 
808  PRBool exists = PR_FALSE;
809  PRBool isDirectory = PR_FALSE;
810 
811  rv = cacheDir->Exists(&exists);
812  NS_ENSURE_SUCCESS(rv, rv);
813 
814  if(!exists) {
815  rv = cacheDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
816  NS_ENSURE_SUCCESS(rv, rv);
817  }
818 
819  rv = cacheDir->IsDirectory(&isDirectory);
820  NS_ENSURE_SUCCESS(rv, rv);
821 
822  if(!isDirectory) {
823  rv = cacheDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
824  NS_ENSURE_SUCCESS(rv, rv);
825  }
826 
827  PRBool isReadable = PR_FALSE;
828  PRBool isWritable = PR_FALSE;
829 
830  rv = cacheDir->IsReadable(&isReadable);
831  NS_ENSURE_SUCCESS(rv, rv);
832 
833  rv = cacheDir->IsWritable(&isWritable);
834  NS_ENSURE_SUCCESS(rv, rv);
835 
836  NS_ENSURE_TRUE(isReadable, NS_ERROR_FAILURE);
837  NS_ENSURE_TRUE(isWritable, NS_ERROR_FAILURE);
838 
839  cacheDir.forget(aNewDir);
840 
841  return NS_OK;
842 }
843 
844 PRBool
846 {
847  NS_ENSURE_STATE(mDevice);
848  NS_ENSURE_STATE(mDeviceCacheDir);
849  NS_ENSURE_STATE(mHandler);
850 
851  nsCOMPtr<nsIVariant> firmwareVersion;
852  nsresult rv =
853  mDevice->GetPreference(NS_LITERAL_STRING(FIRMWARE_VERSION_PREF),
854  getter_AddRefs(firmwareVersion));
855  NS_ENSURE_SUCCESS(rv, PR_FALSE);
856 
857  PRInt32 unsignedVersion = 0;
858  rv = firmwareVersion->GetAsInt32(&unsignedVersion);
859  NS_ENSURE_SUCCESS(rv, PR_FALSE);
860 
861  PRUint32 prefVersion = static_cast<PRUint32>(unsignedVersion);
862 
863  PRUint32 handlerVersion = 0;
864  rv = mHandler->GetLatestFirmwareVersion(&handlerVersion);
865  NS_ENSURE_SUCCESS(rv, PR_FALSE);
866 
867  if(prefVersion < handlerVersion) {
868  return PR_FALSE;
869  }
870 
871  nsCOMPtr<nsIVariant> firmwareFilePath;
872  rv = mDevice->GetPreference(NS_LITERAL_STRING(FIRMWARE_FILE_PREF),
873  getter_AddRefs(firmwareFilePath));
874  NS_ENSURE_SUCCESS(rv, rv);
875 
876  nsString filePath;
877  rv = firmwareFilePath->GetAsAString(filePath);
878  NS_ENSURE_SUCCESS(rv, rv);
879 
880  nsCOMPtr<nsILocalFile> localFile;
881  rv = NS_NewLocalFile(filePath, PR_FALSE, getter_AddRefs(localFile));
882 
883  PRBool exists = PR_FALSE;
884  rv = localFile->Exists(&exists);
885  NS_ENSURE_SUCCESS(rv, rv);
886 
887  if(!exists) {
888  return PR_FALSE;
889  }
890 
891  nsCOMPtr<nsIURI> firmwareURI;
892  rv = mHandler->GetLatestFirmwareLocation(getter_AddRefs(firmwareURI));
893  NS_ENSURE_TRUE(firmwareURI, NS_ERROR_UNEXPECTED);
894 
895  nsCOMPtr<nsIURL> firmwareURL = do_QueryInterface(firmwareURI, &rv);
896  NS_ENSURE_SUCCESS(rv, rv);
897 
898  nsCString newFileName;
899  rv = firmwareURL->GetFileName(newFileName);
900  NS_ENSURE_SUCCESS(rv, rv);
901 
902  nsString localFileName;
903  rv = localFile->GetLeafName(localFileName);
904  NS_ENSURE_SUCCESS(rv, rv);
905 
906  if(!localFileName.EqualsLiteral(newFileName.BeginReading())) {
907  return PR_FALSE;
908  }
909 
910  return PR_TRUE;
911 }
912 
913 nsresult
915 {
916  NS_ENSURE_ARG_POINTER(aFile);
917 
918  nsCOMPtr<nsIVariant> firmwareFilePath;
919  nsresult rv = mDevice->GetPreference(NS_LITERAL_STRING(FIRMWARE_FILE_PREF),
920  getter_AddRefs(firmwareFilePath));
921  NS_ENSURE_SUCCESS(rv, rv);
922 
923  nsString filePath;
924  rv = firmwareFilePath->GetAsAString(filePath);
925  NS_ENSURE_SUCCESS(rv, rv);
926 
927  nsCOMPtr<nsILocalFile> localFile;
928  rv = NS_NewLocalFile(filePath, PR_FALSE, getter_AddRefs(localFile));
929 
930  PRBool exists = PR_FALSE;
931  rv = localFile->Exists(&exists);
932  NS_ENSURE_SUCCESS(rv, rv);
933 
934  if(!exists) {
935  return NS_ERROR_FAILURE;
936  }
937 
938  NS_ADDREF(*aFile = localFile);
939 
940  return NS_OK;
941 }
942 
943 nsresult
945 {
946  NS_ENSURE_STATE(mDownloader);
947  NS_ENSURE_STATE(mDevice);
948  NS_ENSURE_STATE(mHandler);
949  NS_ENSURE_STATE(mDeviceCacheDir);
950  NS_ENSURE_FALSE(mIsBusy, NS_ERROR_FAILURE);
951 
952  mIsBusy = PR_TRUE;
953 
954  nsresult rv = NS_ERROR_UNEXPECTED;
955  PRBool inCache = IsAlreadyInCache();
956 
957  if(!inCache) {
958  // Not in cache, clean out cache dir first.
959  rv = mDeviceCacheDir->Remove(PR_TRUE);
960  NS_ENSURE_SUCCESS(rv, rv);
961 
962  rv = mDeviceCacheDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
963  NS_ENSURE_SUCCESS(rv, rv);
964 
965  nsCOMPtr<nsIURI> firmwareURI;
966  rv = mHandler->GetLatestFirmwareLocation(getter_AddRefs(firmwareURI));
967  NS_ENSURE_TRUE(firmwareURI, NS_ERROR_UNEXPECTED);
968 
969  rv = mDownloader->SetSourceURI(firmwareURI);
970  NS_ENSURE_SUCCESS(rv, rv);
971 
972  rv = mDownloader->Start();
973  NS_ENSURE_SUCCESS(rv, rv);
974  }
975 
977  nsnull,
978  PR_FALSE);
979  NS_ENSURE_SUCCESS(rv, rv);
980 
981  if(inCache) {
982  nsCOMPtr<nsIFile> file;
983  rv = GetCachedFile(getter_AddRefs(file));
984  NS_ENSURE_SUCCESS(rv, rv);
985 
986  nsCOMPtr<sbIDeviceFirmwareUpdate> firmwareUpdate =
987  do_CreateInstance(SB_DEVICEFIRMWAREUPDATE_CONTRACTID, &rv);
988  NS_ENSURE_SUCCESS(rv, rv);
989 
990  PRUint32 firmwareVersion = 0;
991  nsString firmwareReadableVersion;
992 
993  rv = mHandler->GetLatestFirmwareVersion(&firmwareVersion);
994  NS_ENSURE_SUCCESS(rv, rv);
995 
996  rv = mHandler->GetLatestFirmwareReadableVersion(firmwareReadableVersion);
997  NS_ENSURE_SUCCESS(rv, rv);
998 
999  rv = firmwareUpdate->Init(file,
1000  firmwareReadableVersion,
1001  firmwareVersion);
1002  NS_ENSURE_SUCCESS(rv, rv);
1003 
1004  nsCOMPtr<nsIVariant> progress = sbNewVariant((PRUint32) 100).get();
1006  progress,
1007  PR_FALSE);
1008  NS_ENSURE_SUCCESS(rv, rv);
1009 
1010  nsCOMPtr<nsIVariant> firmwareUpdateVariant =
1011  sbNewVariant(firmwareUpdate).get();
1013  firmwareUpdateVariant,
1014  PR_FALSE);
1015  NS_ENSURE_SUCCESS(rv, rv);
1016 
1017  mIsBusy = PR_FALSE;
1018  }
1019 
1020  return NS_OK;
1021 }
1022 
1023 nsresult
1025 {
1026  NS_ENSURE_STATE(mDownloader);
1027 
1028  nsresult rv = NS_ERROR_UNEXPECTED;
1029 
1030  if(mIsBusy) {
1031  rv = mDownloader->Cancel();
1032  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Couldn't cancel download");
1033 
1034  mIsBusy = PR_FALSE;
1035  }
1036 
1037  nsCOMPtr<sbIFileDownloaderListener> grip(this);
1038  rv = mDownloader->SetListener(nsnull);
1039  NS_ENSURE_SUCCESS(rv, rv);
1040 
1041  return NS_OK;
1042 }
1043 
1044 nsresult
1046 {
1047  NS_ENSURE_STATE(mDownloader);
1048  NS_ENSURE_STATE(mDevice);
1049 
1050  PRUint32 percentComplete = 0;
1051  nsresult rv = mDownloader->GetPercentComplete(&percentComplete);
1052  NS_ENSURE_SUCCESS(rv, rv);
1053 
1054  nsCOMPtr<nsIVariant> data =
1055  sbNewVariant(percentComplete).get();
1056 
1058  data,
1059  PR_FALSE);
1060  NS_ENSURE_SUCCESS(rv, rv);
1061 
1062  return NS_OK;
1063 }
1064 
1065 nsresult
1067 {
1068  NS_ENSURE_STATE(mDownloader);
1069  NS_ENSURE_STATE(mDevice);
1070 
1071  PRBool success = PR_FALSE;
1072  nsresult rv = mDownloader->GetSucceeded(&success);
1073  NS_ENSURE_SUCCESS(rv, rv);
1074 
1075  // Oops, looks like we didn't succeed downloading the firmware update.
1076  // Signal the error and exit early (no need to actually return an error,
1077  // the event indicates the operation was aborted).
1078  if(!success) {
1080  nsnull,
1081  PR_FALSE);
1082  NS_ENSURE_SUCCESS(rv, rv);
1083 
1084  nsCOMPtr<sbIFileDownloaderListener> grip(this);
1085  rv = mDownloader->SetListener(nsnull);
1086  NS_ENSURE_SUCCESS(rv, rv);
1087 
1088  mIsBusy = PR_FALSE;
1089 
1090  return NS_OK;
1091  }
1092 
1093  nsCOMPtr<nsIRequest> request;
1094  rv = mDownloader->GetRequest(getter_AddRefs(request));
1095  NS_ENSURE_TRUE(request, NS_ERROR_UNEXPECTED);
1096 
1097  nsCString contentDisposition;
1098  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
1099  if(httpChannel) {
1100  httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"),
1101  contentDisposition);
1102  }
1103 
1104  // Still Empty? Try with multipartChannel.
1105  if(contentDisposition.IsEmpty()) {
1106  nsCOMPtr<nsIMultiPartChannel> multipartChannel(do_QueryInterface(request));
1107  if(multipartChannel) {
1108  multipartChannel->GetContentDisposition(contentDisposition);
1109  }
1110  }
1111 
1112  nsCString filename;
1113  if(!contentDisposition.IsEmpty()) {
1114  filename = GetContentDispositionFilename(contentDisposition);
1115  }
1116  else {
1117  nsCOMPtr<nsIURI> firmwareURI;
1118  nsresult rv =
1119  mHandler->GetLatestFirmwareLocation(getter_AddRefs(firmwareURI));
1120  NS_ENSURE_TRUE(firmwareURI, NS_ERROR_UNEXPECTED);
1121 
1122  nsCOMPtr<nsIURL> url(do_QueryInterface(firmwareURI));
1123  if(url) {
1124  nsCString extension;
1125  url->GetFileExtension(extension);
1126 
1127  rv = UnescapeFragment(extension, url, extension);
1128  extension.Trim(".", PR_FALSE);
1129 
1130  nsCAutoString leafName;
1131  url->GetFileBaseName(leafName);
1132 
1133  if(!leafName.IsEmpty()) {
1134  rv = UnescapeFragment(leafName, url, filename);
1135  if(NS_FAILED(rv)) {
1136  filename = leafName;
1137  }
1138  }
1139 
1140  if(!extension.IsEmpty()) {
1141  filename.AppendLiteral(".");
1142  filename.Append(extension);
1143  }
1144  }
1145  }
1146 
1147  // Move the file to its resting place.
1148  nsCOMPtr<nsIFile> file;
1149  rv = mDownloader->GetDestinationFile(getter_AddRefs(file));
1150  NS_ENSURE_SUCCESS(rv, rv);
1151 
1152  NS_ConvertUTF8toUTF16 filename16(filename);
1153  rv = file->MoveTo(mDeviceCacheDir, filename16);
1154  NS_ENSURE_SUCCESS(rv, rv);
1155 
1156  nsString firmwarePath;
1157  rv = mDeviceCacheDir->GetPath(firmwarePath);
1158  NS_ENSURE_SUCCESS(rv, rv);
1159 
1160  nsCOMPtr<nsILocalFile> firmwareFile;
1161  rv = NS_NewLocalFile(firmwarePath, PR_FALSE, getter_AddRefs(firmwareFile));
1162  NS_ENSURE_SUCCESS(rv, rv);
1163 
1164  rv = firmwareFile->Append(filename16);
1165  NS_ENSURE_SUCCESS(rv, rv);
1166 
1167  nsCOMPtr<sbIDeviceFirmwareUpdate> firmwareUpdate =
1168  do_CreateInstance(SB_DEVICEFIRMWAREUPDATE_CONTRACTID, &rv);
1169  NS_ENSURE_SUCCESS(rv, rv);
1170 
1171  PRUint32 firmwareVersion = 0;
1172  nsString firmwareReadableVersion;
1173 
1174  rv = mHandler->GetLatestFirmwareVersion(&firmwareVersion);
1175  NS_ENSURE_SUCCESS(rv, rv);
1176 
1177  rv = mHandler->GetLatestFirmwareReadableVersion(firmwareReadableVersion);
1178  NS_ENSURE_SUCCESS(rv, rv);
1179 
1180  rv = firmwareUpdate->Init(firmwareFile,
1181  firmwareReadableVersion,
1182  firmwareVersion);
1183  NS_ENSURE_SUCCESS(rv, rv);
1184 
1185  nsCOMPtr<nsIVariant> firmwareVersionVariant =
1186  sbNewVariant(firmwareVersion).get();
1187  rv = mDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_VERSION_PREF),
1188  firmwareVersionVariant);
1189  NS_ENSURE_SUCCESS(rv, rv);
1190 
1191  nsCOMPtr<nsIVariant> firmwareReadableVariant =
1192  sbNewVariant(firmwareReadableVersion).get();
1193  rv = mDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_READABLE_PREF),
1194  firmwareReadableVariant);
1195  NS_ENSURE_SUCCESS(rv, rv);
1196 
1197  nsString firmwareFilePath;
1198  rv = firmwareFile->GetPath(firmwareFilePath);
1199  NS_ENSURE_SUCCESS(rv, rv);
1200 
1201  nsCOMPtr<nsIVariant> firmwareFileVariant =
1202  sbNewVariant(firmwareFilePath).get();
1203  rv = mDevice->SetPreference(NS_LITERAL_STRING(FIRMWARE_FILE_PREF),
1204  firmwareFileVariant);
1205  NS_ENSURE_SUCCESS(rv, rv);
1206 
1207  nsCOMPtr<sbIFileDownloaderListener> grip(this);
1208  rv = mDownloader->SetListener(nsnull);
1209  NS_ENSURE_SUCCESS(rv, rv);
1210 
1211  mIsBusy = PR_FALSE;
1212 
1213  nsCOMPtr<nsIVariant> data = sbNewVariant(firmwareUpdate).get();
1214 
1216  data,
1217  PR_FALSE);
1218  NS_ENSURE_SUCCESS(rv, rv);
1219 
1220  return NS_OK;
1221 }
1222 
1223 nsresult
1225  nsIVariant *aData,
1226  sbIDeviceEvent **aEvent)
1227 {
1228  NS_ENSURE_STATE(mDevice);
1229  NS_ENSURE_ARG_POINTER(aEvent);
1230 
1231  nsresult rv = NS_ERROR_UNEXPECTED;
1232  nsCOMPtr<sbIDeviceManager2> deviceManager =
1233  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
1234  NS_ENSURE_SUCCESS(rv, rv);
1235 
1236  rv = deviceManager->CreateEvent(aType,
1237  aData,
1238  mDevice,
1241  aEvent);
1242  NS_ENSURE_SUCCESS(rv, rv);
1243 
1244  return NS_OK;
1245 }
1246 
1247 nsresult
1249  PRBool aAsync /*= PR_TRUE*/)
1250 {
1251  NS_ENSURE_STATE(mDevice);
1252  NS_ENSURE_ARG_POINTER(aEvent);
1253 
1254  nsresult rv = NS_ERROR_UNEXPECTED;
1255  nsCOMPtr<sbIDeviceEventListener> listener = mListener;
1256 
1257  NS_ENSURE_STATE(mDevice);
1258  nsCOMPtr<sbIDeviceEventTarget> target = do_QueryInterface(mDevice, &rv);
1259  NS_ENSURE_SUCCESS(rv, rv);
1260 
1261  PRBool dispatched = PR_FALSE;
1262  rv = target->DispatchEvent(aEvent, aAsync, &dispatched);
1263  NS_ENSURE_SUCCESS(rv, rv);
1264 
1265  NS_WARN_IF_FALSE(dispatched, "Event not dispatched");
1266 
1267  if(listener) {
1268  rv = listener->OnDeviceEvent(aEvent);
1269  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Error while calling listener.");
1270  }
1271 
1272  return NS_OK;
1273 }
1274 
1275 nsresult
1277  nsIVariant *aData,
1278  PRBool aAsync /*= PR_TRUE*/)
1279 {
1280  nsCOMPtr<sbIDeviceEvent> deviceEvent;
1281  nsresult rv = CreateDeviceEvent(aType, aData, getter_AddRefs(deviceEvent));
1282  NS_ENSURE_SUCCESS(rv, rv);
1283 
1284  rv = SendDeviceEvent(deviceEvent, aAsync);
1285  NS_ENSURE_SUCCESS(rv, rv);
1286 
1287  return NS_OK;
1288 }
1289 
1290 // ----------------------------------------------------------------------------
1291 // sbIFileDownloaderListener
1292 // ----------------------------------------------------------------------------
1293 
1294 NS_IMETHODIMP
1295 sbDeviceFirmwareDownloader::OnProgress()
1296 {
1297  nsresult rv = HandleProgress();
1298  NS_ENSURE_SUCCESS(rv, rv);
1299 
1300  return NS_OK;
1301 }
1302 
1303 NS_IMETHODIMP
1304 sbDeviceFirmwareDownloader::OnComplete()
1305 {
1306  nsresult rv = HandleComplete();
1307  NS_ENSURE_SUCCESS(rv, rv);
1308 
1309  return NS_OK;
1310 }
const unsigned long EVENT_FIRMWARE_DOWNLOAD_ERROR
Firmware download error.
#define FIRMWARE_CACHE_CURRENT_VERSION_NAME
const NS_APP_USER_PROFILE_50_DIR
#define FIRMWARE_FILE_PREF
const unsigned long EVENT_FIRMWARE_DOWNLOAD_END
Firmware download end.
return NS_OK
static nsresult CacheFirmwareUpdate(sbIDevice *aDevice, sbIDeviceFirmwareUpdate *aFirmwareUpdate, sbIDeviceFirmwareUpdate **aCachedFirmwareUpdate)
static PRStatus decode(const unsigned char *src, PRUint32 srclen, unsigned char *dest)
void nsCString_ReplaceChars(nsACString &aOldString, const nsACString &aOldChars, const char aNewChar)
#define FIRMWARE_VERSION_PREF
_dialogDatepicker pos
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceFirmwareDownloader, sbIFileDownloaderListener) sbDeviceFirmwareDownloader
nsIVariant * get() const
#define SB_DEVICEFIRMWAREUPDATE_CONTRACTID
nsresult SendDeviceEvent(sbIDeviceEvent *aEvent, PRBool aAsync=PR_TRUE)
static PRInt32 codetovalue(unsigned char c)
static PRStatus decode3to2(const unsigned char *src, unsigned char *dest)
Songbird Variant Utility Definitions.
#define SB_FILEDOWNLOADER_CONTRACTID
static nsresult CreateCacheDirForDevice(sbIDevice *aDevice, nsIFile *aCacheRoot, nsIFile **aCacheDir)
static char * SB_Base64Decode(const char *src, PRUint32 srclen, char *dest)
#define FIRMWARE_READABLE_PREF
static nsresult CreateDirInCacheRoot(const nsAString &aDirName, nsIFile **aNewDir)
nsresult Init(sbIDevice *aDevice, sbIDeviceEventListener *aListener, sbIDeviceFirmwareHandler *aHandler)
const unsigned long STATE_IDLE
Definition: sbIDevice.idl:220
static nsresult CreateCacheRoot(nsIFile **aCacheRoot)
static PRStatus decode4to3(const unsigned char *src, unsigned char *dest)
nsresult GetCachedFile(nsIFile **aFile)
function url(spec)
const unsigned long EVENT_FIRMWARE_DOWNLOAD_PROGRESS
Firmware download progress.
nsresult CreateDeviceEvent(PRUint32 aType, nsIVariant *aData, sbIDeviceEvent **aEvent)
#define FIRMWARE_CACHE_ROOT_NAME
static PRStatus decode2to1(const unsigned char *src, unsigned char *dest)
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
static nsresult UnescapeFragment(const nsACString &aFragment, nsIURI *aURI, nsAString &aResult)
_updateTextAndScrollDataForFrame aData
const unsigned long EVENT_FIRMWARE_DOWNLOAD_START
Firmware download start.
var file
converter charset
static nsCString GetContentDispositionFilename(const nsACString &contentDisposition)