52 #include <sbILibrary.h>
53 #include <sbILibraryManager.h>
54 #include <sbIAlbumArtFetcherSet.h>
55 #include <sbIPropertyArray.h>
60 #include <nsComponentManagerUtils.h>
61 #include <nsIBinaryOutputStream.h>
62 #include <nsICategoryManager.h>
63 #include <nsIConverterInputStream.h>
64 #include <nsIConverterOutputStream.h>
65 #include <nsICryptoHash.h>
66 #include <nsIFileURL.h>
67 #include <nsIMutableArray.h>
68 #include <nsIProperties.h>
69 #include <nsIProtocolHandler.h>
70 #include <nsIProxyObjectManager.h>
71 #include <nsIResProtocolHandler.h>
72 #include <nsISupportsPrimitives.h>
73 #include <nsIUnicharLineInputStream.h>
74 #include <nsIUnicharOutputStream.h>
75 #include <nsServiceManagerUtils.h>
86 #define TEMPORARY_CACHE_SIZE 1000
89 #define TEMPORARY_CACHE_CLEAR_TIME 60000
92 #define SB_RES_PROTO_PREFIX "sb-artwork"
96 #define ALBUM_ART_CACHE_CLEANUP_INTERVAL 10000
118 static PRLogModuleInfo* gAlbumArtServiceLog = nsnull;
119 #define TRACE(args) PR_LOG(gAlbumArtServiceLog, PR_LOG_DEBUG, args)
120 #define LOG(args) PR_LOG(gAlbumArtServiceLog, PR_LOG_WARN, args)
154 PRBool aIncludeDisabled,
157 TRACE((
"sbAlbumArtService[0x%8.x] - GetFetcherList",
this));
159 NS_ENSURE_ARG_POINTER(_retval);
165 rv = UpdateAlbumArtFetcherInfo();
166 NS_ENSURE_SUCCESS(rv, rv);
169 nsCOMPtr<nsIMutableArray>
170 fetcherList = do_CreateInstance
171 (
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
172 NS_ENSURE_SUCCESS(rv, rv);
175 PRUint32 fetcherCount = mFetcherInfoList.Length();
176 for (PRUint32
i = 0;
i < fetcherCount;
i++) {
179 if (!mFetcherInfoList[
i].enabled && !aIncludeDisabled) {
186 if (!mFetcherInfoList[
i].local) {
191 if (mFetcherInfoList[
i].local) {
200 NS_ENSURE_TRUE(contractID, NS_ERROR_OUT_OF_MEMORY);
202 rv = fetcherList->AppendElement(contractID, PR_FALSE);
203 NS_ENSURE_SUCCESS(rv, rv);
207 NS_ADDREF(*_retval = fetcherList);
226 sbAlbumArtService::ImageIsValidAlbumArt(
const nsACString& aMimeType,
227 const PRUint8*
aData,
231 TRACE((
"sbAlbumArtService[0x%8.x] - ImageIsValidAlbumArt",
this));
233 NS_ENSURE_ARG_POINTER(_retval);
239 if (!aData || !aDataLen) {
245 nsCAutoString fileExtension;
246 rv = GetAlbumArtFileExtension(aMimeType, fileExtension);
271 #define NS_FILE_OUTPUT_STREAM_OPEN_DEFAULT -1
274 sbAlbumArtService::CacheImage(
const nsACString& aMimeType,
275 const PRUint8* aData,
279 TRACE((
"sbAlbumArtService[0x%8.x] - CacheImage",
this));
281 NS_ENSURE_ARG_POINTER(aData);
282 NS_ENSURE_ARG_POINTER(_retval);
284 NS_ENSURE_TRUE(mAlbumArtCacheDir, NS_ERROR_NOT_INITIALIZED);
290 nsCAutoString fileBaseName;
291 rv = GetCacheFileBaseName(aData, aDataLen, fileBaseName);
292 NS_ENSURE_SUCCESS(rv, rv);
295 nsCAutoString fileExtension;
296 rv = GetAlbumArtFileExtension(aMimeType, fileExtension);
297 NS_ENSURE_SUCCESS(rv, rv);
301 fileName.Assign(fileBaseName);
302 fileName.AppendLiteral(
".");
303 fileName.Append(fileExtension);
306 nsCOMPtr<nsIURI> cacheFileURI;
307 rv = mIOService->NewURI(cacheDummySpec, nsnull, nsnull, getter_AddRefs(cacheFileURI));
308 NS_ENSURE_SUCCESS(rv, rv);
311 nsCOMPtr<nsIFileURL> cacheFileURL = do_QueryInterface(cacheFileURI, &rv);
312 NS_ENSURE_SUCCESS(rv, rv);
313 rv = cacheFileURL->SetFileName(fileName);
314 NS_ENSURE_SUCCESS(rv, rv);
316 nsCOMPtr<nsIFile> cacheFile;
317 rv = cacheFileURL->GetFile(getter_AddRefs(cacheFile));
318 NS_ENSURE_SUCCESS(rv, rv);
322 rv = cacheFile->Exists(&exists);
323 NS_ENSURE_SUCCESS(rv, rv);
325 cacheFileURI.forget(_retval);
330 nsCOMPtr<nsIFileOutputStream> fileOutputStream =
331 do_CreateInstance(
"@mozilla.org/network/file-output-stream;1", &rv);
332 NS_ENSURE_SUCCESS(rv, rv);
333 rv = fileOutputStream->Init(cacheFile,
337 NS_ENSURE_SUCCESS(rv, rv);
338 sbAutoFileOutputStream autoFileOutputStream(fileOutputStream);
341 nsCOMPtr<nsIBinaryOutputStream> binaryOutputStream =
342 do_CreateInstance(
"@mozilla.org/binaryoutputstream;1", &rv);
343 NS_ENSURE_SUCCESS(rv, rv);
344 rv = binaryOutputStream->SetOutputStream(fileOutputStream);
345 NS_ENSURE_SUCCESS(rv, rv);
346 rv = binaryOutputStream->WriteByteArray((PRUint8*) aData, aDataLen);
347 NS_ENSURE_SUCCESS(rv, rv);
350 cacheFileURI.forget(_retval);
371 sbAlbumArtService::CacheTemporaryData(
const nsAString& aKey,
374 TRACE((
"sbAlbumArtService[0x%8.x] - CacheTemporaryData",
this));
375 NS_ENSURE_ARG_POINTER(aData);
376 NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
378 PRBool
succeeded = mTemporaryCache.Put(aKey, aData);
379 NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE);
382 if (!mCacheFlushTimer) {
384 mCacheFlushTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
385 NS_ENSURE_SUCCESS(rv, rv);
387 rv = mCacheFlushTimer->Init(
this,
389 nsITimer::TYPE_ONE_SHOT);
390 NS_ENSURE_SUCCESS(rv, rv);
407 sbAlbumArtService::RetrieveTemporaryData(
const nsAString& aKey,
410 TRACE((
"sbAlbumArtService[0x%8.x] - RetrieveTemporaryData",
this));
411 NS_ENSURE_ARG_POINTER(_retval);
412 NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
414 PRBool succeeded = mTemporaryCache.Get(aKey, _retval);
415 return succeeded ?
NS_OK : NS_ERROR_NOT_AVAILABLE;
445 const PRUnichar* aData)
447 TRACE((
"sbAlbumArtService[0x%8.x] - Observe",
this));
451 if (!strcmp(aTopic,
"app-startup")) {
453 nsCOMPtr<nsIObserverService> obsSvc = do_GetService(
454 "@mozilla.org/observer-service;1", &rv);
455 NS_ENSURE_SUCCESS(rv, rv);
458 rv = obsSvc->AddObserver(
this,
459 "profile-after-change",
461 NS_ENSURE_SUCCESS(rv, rv);
462 rv = obsSvc->AddObserver(
this,
465 NS_ENSURE_SUCCESS(rv, rv);
466 }
else if (!strcmp(aTopic,
"profile-after-change")) {
469 NS_ENSURE_SUCCESS(rv, rv);
474 nsCOMPtr<nsITimer> aObserveTimer = do_QueryInterface(aSubject, &rv);
475 NS_ENSURE_SUCCESS(rv, rv);
476 if (aObserveTimer == mCacheFlushTimer) {
478 rv = mCacheFlushTimer->Cancel();
479 NS_ASSERTION(NS_SUCCEEDED(rv),
"Failed to cancel the cache timer");
480 mCacheFlushTimer = nsnull;
483 mTemporaryCache.Clear();
502 mCacheFlushTimer(nsnull)
505 if (!gAlbumArtServiceLog) {
506 gAlbumArtServiceLog = PR_NewLogModule(
"sbAlbumArtService");
529 TRACE((
"sbAlbumArtService[0x%8.x] - Initialize",
this));
537 mIOService = do_GetService(
"@mozilla.org/network/io-service;1", &rv);
538 NS_ENSURE_SUCCESS(rv, rv);
541 mMIMEService = do_GetService(
"@mozilla.org/mime;1", &rv);
542 NS_ENSURE_SUCCESS(rv, rv);
552 rv = GetAlbumArtFetcherInfo();
553 NS_ENSURE_SUCCESS(rv, rv);
556 rv = GetAlbumArtCacheDir();
557 NS_ENSURE_SUCCESS(rv, rv);
560 nsCOMPtr<nsIIOService> ioservice =
561 do_GetService(
"@mozilla.org/network/io-service;1", &rv);
562 NS_ENSURE_SUCCESS(rv, rv);
563 nsCOMPtr<nsIProtocolHandler> protoHandler;
564 rv = ioservice->GetProtocolHandler(
"resource", getter_AddRefs(protoHandler));
565 NS_ENSURE_SUCCESS(rv, rv);
566 nsCOMPtr<nsIResProtocolHandler> resProtoHandler =
567 do_QueryInterface(protoHandler, &rv);
568 NS_ENSURE_SUCCESS(rv, rv);
569 PRBool hasSubstitution;
572 NS_ENSURE_SUCCESS(rv, rv);
573 if (!hasSubstitution) {
574 nsCOMPtr<nsIURI> cacheURI;
575 rv = ioservice->NewFileURI(mAlbumArtCacheDir, getter_AddRefs(cacheURI));
576 NS_ENSURE_SUCCESS(rv, rv);
579 NS_ENSURE_SUCCESS(rv, rv);
584 NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE);
587 mInitialized = PR_TRUE;
604 sbAlbumArtService::Finalize()
606 TRACE((
"sbAlbumArtService[0x%8.x] - Finalize",
this));
617 mInitialized = PR_FALSE;
620 mFetcherInfoList.Clear();
623 mTemporaryCache.Clear();
626 nsCOMPtr<nsIObserverService> obsSvc = do_GetService(
627 "@mozilla.org/observer-service;1", &rv);
628 obsSvc->RemoveObserver(
this,
"profile-after-change");
631 if (mCacheFlushTimer) {
632 rv = mCacheFlushTimer->Cancel();
633 NS_ASSERTION(NS_SUCCEEDED(rv),
"Failed to cancel a cache timer");
634 mCacheFlushTimer = nsnull;
644 sbAlbumArtService::GetAlbumArtCacheDir()
646 TRACE((
"sbAlbumArtService[0x%8.x] - GetAlbumArtCacheDir",
this));
650 nsCOMPtr<nsIProperties>
651 directoryService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
652 NS_ENSURE_SUCCESS(rv, rv);
653 rv = directoryService->Get(
"ProfLD",
655 getter_AddRefs(mAlbumArtCacheDir));
656 NS_ENSURE_SUCCESS(rv, rv);
657 rv = mAlbumArtCacheDir->Append(NS_LITERAL_STRING(
"artwork"));
658 NS_ENSURE_SUCCESS(rv, rv);
662 rv = mAlbumArtCacheDir->Exists(&exists);
663 NS_ENSURE_SUCCESS(rv, rv);
665 nsCOMPtr<nsIFile> parent;
666 rv = mAlbumArtCacheDir->GetParent(getter_AddRefs(parent));
667 NS_ENSURE_SUCCESS(rv, rv);
668 PRUint32 permissions;
669 rv = parent->GetPermissions(&permissions);
670 NS_ENSURE_SUCCESS(rv, rv);
671 rv = mAlbumArtCacheDir->Create(nsIFile::DIRECTORY_TYPE, permissions);
672 NS_ENSURE_SUCCESS(rv, rv);
684 sbAlbumArtService::GetAlbumArtFetcherInfo()
686 TRACE((
"sbAlbumArtService[0x%8.x] - GetAlbumArtFetcherInfo",
this));
690 nsCOMPtr<nsICategoryManager>
691 categoryManager = do_GetService(
"@mozilla.org/categorymanager;1", &rv);
692 NS_ENSURE_SUCCESS(rv, rv);
695 nsCOMPtr<nsISimpleEnumerator> albumArtFetcherEnum;
697 getter_AddRefs(albumArtFetcherEnum));
698 NS_ENSURE_SUCCESS(rv, rv);
704 rv = albumArtFetcherEnum->HasMoreElements(&hasMoreElements);
705 NS_ENSURE_SUCCESS(rv, rv);
706 if (!hasMoreElements) {
711 nsCOMPtr<nsISupports> entryNameSupports;
712 nsCOMPtr<nsISupportsCString> entryNameSupportsCString;
713 nsCAutoString entryName;
714 rv = albumArtFetcherEnum->GetNext(getter_AddRefs(entryNameSupports));
715 NS_ENSURE_SUCCESS(rv, rv);
716 entryNameSupportsCString = do_QueryInterface(entryNameSupports, &rv);
717 NS_ENSURE_SUCCESS(rv, rv);
718 rv = entryNameSupportsCString->GetData(entryName);
719 NS_ENSURE_SUCCESS(rv, rv);
726 NS_ENSURE_SUCCESS(rv, rv);
727 TRACE((
"sbAlbumArtService::GetAlbumArtFetcherInfo - Found fetcher [%s]", contractID));
729 nsCOMPtr<sbIAlbumArtFetcher> albumArtFetcher = do_CreateInstance(contractID,
731 NS_ENSURE_SUCCESS(rv, rv);
733 PRInt32 priority = 0;
734 albumArtFetcher->GetPriority(&priority);
736 PRBool isEnabled = PR_FALSE;
737 albumArtFetcher->GetIsEnabled(&isEnabled);
739 PRBool isLocal = PR_FALSE;
740 albumArtFetcher->GetIsLocal(&isLocal);
743 FetcherInfo fetcherInfo;
744 fetcherInfo.contractID.Assign(contractID);
745 fetcherInfo.priority = priority;
746 fetcherInfo.enabled = isEnabled;
747 fetcherInfo.local = isLocal;
749 NS_ENSURE_TRUE(mFetcherInfoList.AppendElement(fetcherInfo),
750 NS_ERROR_OUT_OF_MEMORY);
754 mFetcherInfoList.Sort();
764 sbAlbumArtService::UpdateAlbumArtFetcherInfo()
766 TRACE((
"sbAlbumArtService[0x%8.x] - UpdateAlbumArtFetcherInfo",
this));
770 for (PRUint32
i = 0;
i < mFetcherInfoList.Length();
i++) {
771 nsCOMPtr<sbIAlbumArtFetcher> albumArtFetcher =
772 do_CreateInstance(mFetcherInfoList[
i].contractID.get(), &rv);
773 NS_ENSURE_SUCCESS(rv, rv);
775 PRInt32 priority = 0;
776 albumArtFetcher->GetPriority(&priority);
778 PRBool isEnabled = PR_FALSE;
779 albumArtFetcher->GetIsEnabled(&isEnabled);
781 mFetcherInfoList[
i].priority = priority;
782 mFetcherInfoList[
i].enabled = isEnabled;
785 mFetcherInfoList.Sort();
801 sbAlbumArtService::GetCacheFileBaseName(
const PRUint8* aData,
803 nsACString& aFileBaseName)
805 TRACE((
"sbAlbumArtService[0x%8.x] - GetCacheFileBaseName",
this));
807 NS_ASSERTION(aData,
"aData is null");
813 aFileBaseName.Truncate();
816 nsCAutoString hashValue;
817 nsCOMPtr<nsICryptoHash>
818 cryptoHash = do_CreateInstance(
"@mozilla.org/security/hash;1", &rv);
819 NS_ENSURE_SUCCESS(rv, rv);
820 rv = cryptoHash->Init(nsICryptoHash::MD5);
821 NS_ENSURE_SUCCESS(rv, rv);
822 rv = cryptoHash->Update(aData, aDataLen);
823 NS_ENSURE_SUCCESS(rv, rv);
824 rv = cryptoHash->Finish(PR_FALSE, hashValue);
825 NS_ENSURE_SUCCESS(rv, rv);
828 PRUint32 hashLength = hashValue.Length();
829 PRUint8* hashData = (PRUint8*) hashValue.get();
830 for (PRUint32
i = 0;
i < hashLength;
i++) {
832 PR_snprintf(hexValue, 3,
"%02x", hashData[
i]);
833 aFileBaseName.AppendLiteral(hexValue);
849 sbAlbumArtService::GetAlbumArtFileExtension(
const nsACString& aMimeType,
850 nsACString& aFileExtension)
852 TRACE((
"sbAlbumArtService[0x%8.x] - GetAlbumArtFileExtension",
this));
856 rv = mMIMEService->GetPrimaryExtension(aMimeType,
857 NS_LITERAL_CSTRING(
""),
860 aFileExtension.Truncate();
863 if (aFileExtension.IsEmpty()) {
864 PRInt32 mimeSubTypeIndex = aMimeType.RFind(
"/");
865 if (mimeSubTypeIndex >= 0) {
866 aFileExtension.Assign(nsDependentCSubstring(aMimeType,
867 mimeSubTypeIndex + 1));
869 aFileExtension.Assign(aMimeType);
874 ToLowerCase(aFileExtension);
877 if (!mValidExtensionList.Contains(aFileExtension))
878 return NS_ERROR_FAILURE;
NS_DECL_ISUPPORTS NS_DECL_SBIALBUMARTSERVICE NS_DECL_NSIOBSERVER sbAlbumArtService()
virtual ~sbAlbumArtService()
function succeeded(ch, cx, status, data)
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
#define SB_RES_PROTO_PREFIX
Songbird Variant Utility Definitions.
NS_IMPL_ISUPPORTS2(sbAlbumArtService, sbIAlbumArtService, nsIObserver) NS_IMETHODIMP sbAlbumArtService
#define TEMPORARY_CACHE_SIZE
#define TEMPORARY_CACHE_CLEAR_TIME
const unsigned long TYPE_LOCAL
Interface for the album art service. Instantiate as a component service.
static const char * sbAlbumArtServiceValidExtensionList[]
const NS_TIMER_CALLBACK_TOPIC
#define SB_ALBUM_ART_FETCHER_CATEGORY
#define NS_FILE_OUTPUT_STREAM_OPEN_DEFAULT
Write the album art image specified by aData and aDataLen of type specified by aMimeType to a cache f...
SimpleArrayEnumerator prototype hasMoreElements
Songbird Album Art Service Definitions.
_getSelectedPageStyle s i
const unsigned long TYPE_REMOTE
const SB_LIBRARY_MANAGER_BEFORE_SHUTDOWN_TOPIC
_updateTextAndScrollDataForFrame aData