33 #include <nsComponentManagerUtils.h>
34 #include <nsServiceManagerUtils.h>
35 #include <nsIObserverService.h>
36 #include <nsArrayUtils.h>
37 #include <nsIPrefBranch.h>
38 #include <nsIPromptService.h>
39 #include <nsIWindowMediator.h>
40 #include <nsIDOMWindow.h>
41 #include <nsIDOMWindowInternal.h>
42 #include <nsThreadUtils.h>
45 #include <sbILibraryManager.h>
46 #include <sbIMediacoreSequencer.h>
47 #include <sbIMediacoreStatus.h>
48 #include <sbIMediaItem.h>
51 #include <sbIDataRemote.h>
63 extern PRLogModuleInfo* gMetadataLog;
64 #define TRACE(args) PR_LOG(gMetadataLog, PR_LOG_DEBUG, args)
65 #define LOG(args) PR_LOG(gMetadataLog, PR_LOG_WARN, args)
67 #define __FUNCTION__ __PRETTY_FUNCTION__
75 #define TIMER_PERIOD 33
86 mMainThreadProcessor(nsnull),
89 mNotificationTimer(nsnull),
94 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
100 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
109 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
117 "sbFileMetadataService job items lock");
118 NS_ENSURE_TRUE(
mJobLock, NS_ERROR_OUT_OF_MEMORY);
122 NS_ENSURE_SUCCESS(rv, rv);
126 nsCOMPtr<nsIObserverService> obsSvc;
127 if (NS_IsMainThread()) {
128 obsSvc = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
133 NS_ENSURE_SUCCESS(rv, rv);
135 do_QueryInterface(NS_ISUPPORTS_CAST(
nsIObserver*,
this), &rv);
136 NS_ENSURE_SUCCESS(rv, rv);
138 NS_ENSURE_SUCCESS(rv, rv);
147 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
148 NS_ASSERTION(NS_IsMainThread(),
149 "\n\n\nsbFileMetadataService::Shutdown IS MAIN THREAD ONLY!!!!111\n\n\n");
154 NS_ASSERTION(NS_SUCCEEDED(rv),
155 "Failed to stop main thread metadata processor");
164 NS_ASSERTION(NS_SUCCEEDED(rv),
165 "Failed to stop background thread metadata processor");
173 NS_ASSERTION(NS_SUCCEEDED(rv),
"Failed to cancel a notification timer");
183 NS_ASSERTION(NS_SUCCEEDED(rv),
"Failed to cancel a metadata job");
187 "Metadata jobs remaining after stopping the manager");
195 NS_ASSERTION(NS_SUCCEEDED(rv),
196 "sbFileMetadataService::Shutdown failed to stop crash tracker");
204 sbFileMetadataService::Read(nsIArray* aMediaItemsArray,
207 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
215 sbFileMetadataService::Write(nsIArray* aMediaItemsArray,
219 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
227 sbFileMetadataService::RestartProcessors(PRUint16 aProcessorsToRestart)
229 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
232 NS_ENSURE_SUCCESS(rv, rv);
240 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
243 if (!NS_IsMainThread()) {
244 LOG((
"%s[%.8x] proxying main thread RestartProcessors()", __FUNCTION__,
this));
245 nsCOMPtr<nsIThread>
target;
246 rv = NS_GetMainThread(getter_AddRefs(target));
247 NS_ENSURE_SUCCESS(rv, rv);
249 nsCOMPtr<sbIFileMetadataService> proxy;
252 static_cast<sbIFileMetadataService*>(
this),
253 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
254 getter_AddRefs(proxy));
255 NS_ENSURE_SUCCESS(rv, rv);
258 rv = proxy->RestartProcessors(aProcessorsToRestart);
259 NS_ENSURE_SUCCESS(rv, rv);
267 NS_ENSURE_SUCCESS(rv, rv);
271 nsCOMPtr<nsIRunnable>
event =
275 NS_DispatchToCurrentThread(
event);
288 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
292 if (!NS_IsMainThread()) {
293 LOG((
"%s[%.8x] proxying main thread StartJob()", __FUNCTION__,
this));
294 nsCOMPtr<nsIThread>
target;
295 rv = NS_GetMainThread(getter_AddRefs(target));
296 NS_ENSURE_SUCCESS(rv, rv);
298 nsCOMPtr<sbIFileMetadataService> proxy;
301 static_cast<sbIFileMetadataService*>(
this),
302 NS_PROXY_SYNC | NS_PROXY_ALWAYS,
303 getter_AddRefs(proxy));
304 NS_ENSURE_SUCCESS(rv, rv);
308 rv = proxy->Write(aMediaItemsArray, aRequiredProperties, _retval);
310 rv = proxy->Read(aMediaItemsArray, _retval);
313 rv =
StartJob(aMediaItemsArray, aRequiredProperties, aJobType, _retval);
325 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
326 NS_ENSURE_ARG_POINTER(aMediaItemsArray);
327 NS_ENSURE_ARG_POINTER(_retval);
330 NS_ASSERTION(NS_IsMainThread(),
331 "\n\n\nsbFileMetadataService::StartJob IS MAIN THREAD ONLY!!!!!!!\n\n\n");
339 NS_ENSURE_SUCCESS(rv, rv);
343 NS_ENSURE_TRUE(job, NS_ERROR_OUT_OF_MEMORY);
345 rv = job->Init(aMediaItemsArray, aRequiredProperties, aJobType);
346 NS_ENSURE_SUCCESS(rv, rv);
356 rv =
mJobArray[jobCount-1]->GetBlocked(&blocked);
357 NS_ENSURE_SUCCESS(rv, rv);
359 rv = job->SetBlocked(PR_TRUE);
360 NS_ENSURE_SUCCESS(rv, rv);
374 NS_ENSURE_SUCCESS(rv, rv);
378 nsITimer::TYPE_REPEATING_SLACK);
379 NS_ENSURE_SUCCESS(rv, rv);
386 NS_ERROR(
"sbFileMetadataService::StartJob failed to "
387 "start crash tracker");
403 NS_ENSURE_SUCCESS(rv, rv);
412 NS_ENSURE_SUCCESS(rv, rv);
414 rv = CallQueryInterface(job.get(), _retval);
415 NS_ENSURE_SUCCESS(rv, rv);
424 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
425 NS_ENSURE_ARG_POINTER(aJobItem);
431 nsRefPtr<sbMetadataJobItem> item;
436 PRBool isURLBlacklisted;
438 isURLBlacklisted = PR_FALSE;
450 getter_AddRefs(item));
451 if (rv != NS_ERROR_NOT_AVAILABLE) {
460 rv = item->GetURL(url);
461 NS_ENSURE_SUCCESS(rv, rv);
465 if (isURLBlacklisted) {
467 LOG((
"sbFileMetadataService ignored blacklisted file %s.",
468 url.BeginReading()));
472 TRACE((
"sbFileMetadataService[9x%.8x] GetQueuedJobItem starting %s",
473 this, url.BeginReading()));
476 NS_ERROR(
"sbFileMetadataService::GetQueuedJobItem couldn't log URL");
480 }
while (isURLBlacklisted);
483 if (rv == NS_ERROR_NOT_AVAILABLE) {
484 TRACE((
"sbFileMetadataService[0x%.8x] GetQueuedJobItem NOT_AVAILABLE",
488 NS_ENSURE_SUCCESS(rv, rv);
490 item.forget(aJobItem);
494 return NS_ERROR_NOT_AVAILABLE;
500 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
501 NS_ENSURE_ARG_POINTER(aJobItem);
505 nsRefPtr<sbMetadataJob> job;
507 NS_ENSURE_SUCCESS(rv, rv);
512 rv = aJobItem->
GetURL(url);
513 NS_ENSURE_SUCCESS(rv, rv);
516 NS_ERROR(
"sbFileMetadataService::PutProcessedJobItem couldn't log URL");
520 return job->PutProcessedItem(aJobItem);
525 PRBool* aJobItemIsBlocked)
527 NS_ENSURE_ARG_POINTER(aJobItem);
528 NS_ENSURE_ARG_POINTER(aJobItemIsBlocked);
535 NS_ENSURE_SUCCESS(rv, rv);
539 *aJobItemIsBlocked = PR_FALSE;
544 nsCOMPtr<sbIMediacoreStatus> status;
547 NS_ENSURE_SUCCESS(rv, rv);
548 rv = status->GetState(&state);
549 NS_ENSURE_SUCCESS(rv, rv);
551 *aJobItemIsBlocked = PR_FALSE;
556 nsCOMPtr<sbIMediacoreSequencer> sequencer;
557 nsCOMPtr<sbIMediaItem> sequencerCurrentItem;
559 NS_ENSURE_SUCCESS(rv, rv);
560 rv = sequencer->GetCurrentItem(getter_AddRefs(sequencerCurrentItem));
561 NS_ENSURE_SUCCESS(rv, rv);
564 nsCOMPtr<sbIMediaItem> jobItem;
566 NS_ENSURE_SUCCESS(rv, rv);
570 rv = jobItem->Equals(sequencerCurrentItem, &equals);
571 NS_ENSURE_SUCCESS(rv, rv);
573 *aJobItemIsBlocked = PR_FALSE;
578 *aJobItemIsBlocked = PR_TRUE;
586 sbFileMetadataService::Observe(
nsISupports *aSubject,
588 const PRUnichar *
aData)
590 TRACE((
"%s[%.8x] (%s)", __FUNCTION__,
this, aTopic));
599 NS_ENSURE_SUCCESS(rv, rv);
602 nsCOMPtr<nsIObserverService> obsSvc =
603 do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
604 NS_ENSURE_SUCCESS(rv, rv);
606 do_QueryInterface(NS_ISUPPORTS_CAST(
nsIObserver*,
this), &rv);
607 NS_ENSURE_SUCCESS(rv, rv);
609 NS_ENSURE_SUCCESS(rv, rv);
615 TRACE((
"%s[%.8x] - Notification Timer Callback", __FUNCTION__,
this));
620 nsTArray<nsRefPtr<sbMetadataJob> > jobs;
627 PRBool blocked = PR_FALSE;
628 PRUint32 jobCount = jobs.Length();
629 for (PRUint32
i=0;
i < jobCount;
i++) {
633 rv = jobs[
i]->GetBlocked(&blocked);
635 rv = jobs[
i]->SetBlocked(PR_TRUE);
640 for (PRUint32
i=0;
i < jobs.Length();
i++) {
641 jobs[
i]->OnJobProgress();
647 PRBool allComplete = PR_TRUE;
652 allComplete = PR_FALSE;
659 TRACE((
"%s[%.8x] - Notification - All Complete", __FUNCTION__,
this));
661 NS_ASSERTION(NS_SUCCEEDED(rv),
"Failed to cancel a notification timer");
675 NS_ERROR(
"sbFileMetadataService::Shutdown failed to stop crash tracker");
692 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
695 PRBool enableWriting = PR_FALSE;
696 nsCOMPtr<nsIPrefBranch> prefService =
697 do_GetService(
"@mozilla.org/preferences-service;1", &rv );
698 NS_ENSURE_SUCCESS( rv, rv);
699 prefService->GetBoolPref(
"songbird.metadata.enableWriting", &enableWriting );
701 if (!enableWriting) {
706 PRBool promptOnWrite = PR_TRUE;
707 prefService->GetBoolPref(
"songbird.metadata.promptOnWrite", &promptOnWrite );
712 nsCOMPtr<nsIWindowMediator> windowMediator =
713 do_GetService(
"@mozilla.org/appshell/window-mediator;1", &rv);
714 NS_ENSURE_SUCCESS( rv, rv);
715 nsCOMPtr<nsIDOMWindowInternal> mainWindow;
716 windowMediator->GetMostRecentWindow(nsnull,
717 getter_AddRefs(mainWindow));
720 do_GetService(
"@mozilla.org/embedcomp/prompt-service;1", &rv);
721 NS_ENSURE_SUCCESS( rv, rv);
723 PRBool promptResult = PR_FALSE;
724 PRBool checkState = PR_FALSE;
727 rv = promptService->ConfirmCheck(mainWindow,
728 NS_LITERAL_STRING(
"WARNING! TAG WRITING IS EXPERIMENTAL!").
get(),
729 NS_MULTILINE_LITERAL_STRING(
730 NS_LL(
"Are you sure you want to write metadata changes")
731 NS_LL(
" back to your media files?\n\nTag writing has not been tested yet,")
732 NS_LL(
" and may damage your media files. If you'd like to help us test")
733 NS_LL(
" this functionality, great, but we advise you to back up your media first.")
735 NS_LITERAL_STRING(
"Don't show this dialog again").
get(),
738 NS_ENSURE_SUCCESS( rv, rv);
741 prefService->SetBoolPref(
"songbird.metadata.promptOnWrite", PR_FALSE );
745 prefService->SetBoolPref(
"songbird.metadata.enableWriting", PR_TRUE );
746 enableWriting = PR_TRUE;
752 return (enableWriting) ?
NS_OK : NS_ERROR_NOT_AVAILABLE;
757 TRACE((
"%s[%.8x]", __FUNCTION__,
this));
758 NS_ASSERTION(NS_IsMainThread(),
759 "sbFileMetadataService::UpdateDataRemotes is main thread only!");
765 do_CreateInstance(
"@songbirdnest.com/Songbird/DataRemote;1", &rv);
766 NS_ENSURE_SUCCESS(rv, rv);
769 NS_ENSURE_SUCCESS(rv, rv);
779 LOG((
"%s[%.8x] Adding blacklist url \"%s\"",
782 aURL.BeginReading()));
789 NS_ENSURE_SUCCESS(rv, rv);
792 NS_ENSURE_SUCCESS(rv, rv);
Generic interface for exposing long running jobs to the UI.
nsresult do_GetProxyForObject(nsIEventTarget *aTarget, REFNSIID aIID, nsISupports *aObj, PRInt32 aProxyType, void **aProxyObject)
const unsigned short STATUS_RUNNING
Constant indicating that the job is active.
const sbCreateProxiedComponent do_ProxiedGetService(const nsCID &aCID, nsresult *error=0)
const NS_TIMER_CALLBACK_TOPIC
Runs sbIMetadataHandlers with a timer on the main thread.
_getSelectedPageStyle s i
const SB_LIBRARY_MANAGER_BEFORE_SHUTDOWN_TOPIC
_updateTextAndScrollDataForFrame aData