30 #include <sbIWFMoveRenameHelper9000.h>
31 #include <sbIWFRemoveHelper9001.h>
34 #include <sbIApplicationController.h>
35 #include <sbIDirectoryImportService.h>
36 #include <sbIFileMetadataService.h>
37 #include <sbIJobProgress.h>
38 #include <sbIJobProgressService.h>
39 #include <sbILibraryManager.h>
40 #include <sbIPropertyArray.h>
42 #include <sbIPrompter.h>
43 #include <sbIDirectoryImportService.h>
44 #include <nsComponentManagerUtils.h>
45 #include <nsServiceManagerUtils.h>
46 #include <nsICategoryManager.h>
47 #include <nsILocalFile.h>
48 #include <nsIPrefBranch2.h>
49 #include <nsIObserverService.h>
52 #include <sbIMediacoreTypeSniffer.h>
53 #include <nsThreadUtils.h>
54 #include <nsXPCOMCIDInternal.h>
55 #include <nsIXULRuntime.h>
60 PRLogModuleInfo* gWatchFoldersLog = nsnull;
72 mHasWatcherStarted = PR_FALSE;
73 mShouldReinitWatcher = PR_FALSE;
74 mEventPumpTimerIsSet = PR_FALSE;
75 mChangeDelayTimerIsSet = PR_FALSE;
76 mShouldProcessEvents = PR_FALSE;
77 mCurrentProcessType =
eNone;
80 if (!gWatchFoldersLog) {
81 gWatchFoldersLog = PR_NewLogModule(
"sbWatchFoldersComponent");
99 nsCOMPtr<sbIFileSystemWatcher> fileSystemWatcher =
100 do_CreateInstance(
"@songbirdnest.com/filesystem/watcher;1", &rv);
104 PRBool isWatcherSupported = PR_FALSE;
105 rv = fileSystemWatcher->GetIsSupported(&isWatcherSupported);
106 NS_ENSURE_SUCCESS(rv, rv);
109 if (isWatcherSupported) {
110 nsCOMPtr<nsIXULRuntime> appInfo =
111 do_GetService(XULRUNTIME_SERVICE_CONTRACTID, &rv);
113 if (NS_SUCCEEDED(rv)) {
114 PRBool isInSafeMode = PR_FALSE;
115 rv = appInfo->GetInSafeMode(&isInSafeMode);
117 isWatcherSupported = NS_FAILED(rv) || !isInSafeMode;
121 if (!isWatcherSupported) {
132 NS_ENSURE_TRUE(mPrefMgr, NS_ERROR_OUT_OF_MEMORY);
134 rv = mPrefMgr->Init(
this);
135 NS_ENSURE_SUCCESS(rv, rv);
144 nsCOMPtr<nsIPrefBranch2> prefBranch =
145 do_GetService(
"@mozilla.org/preferences-service;1", &rv);
146 NS_ENSURE_SUCCESS(rv, rv);
149 PRBool shouldEnable = PR_FALSE;
152 shouldEnable = PR_FALSE;
165 nsCOMPtr<nsISupportsString> supportsString;
168 getter_AddRefs(supportsString));
171 if (NS_FAILED(rv) || !supportsString) {
172 return NS_ERROR_UNEXPECTED;
175 rv = supportsString->GetData(mWatchPath);
176 NS_ENSURE_SUCCESS(rv, rv);
179 if (mWatchPath.Equals(EmptyString())) {
180 return NS_ERROR_UNEXPECTED;
188 getter_Copies(mFileSystemWatcherGUID));
191 do_GetService(
"@songbirdnest.com/Songbird/library/Manager;1", &rv);
192 NS_ENSURE_SUCCESS(rv, rv);
195 nsCOMPtr<sbILibraryManager> libraryMgr =
196 do_QueryInterface(mLibraryUtils, &rv);
197 NS_ENSURE_SUCCESS(rv, rv);
199 rv = libraryMgr->GetMainLibrary(getter_AddRefs(mMainLibrary));
200 NS_ENSURE_SUCCESS(rv, rv);
207 NS_ENSURE_SUCCESS(rv, rv);
209 TRACE((
"%s: started watching [%s]",
211 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
221 if (mWatchPath.IsEmpty() || mServiceState !=
eStarted) {
227 do_CreateInstance(
"@songbirdnest.com/filesystem/watcher;1", &rv);
228 NS_ENSURE_SUCCESS(rv, rv);
230 if (mFileSystemWatcherGUID.Equals(EmptyCString())) {
233 TRACE((
"%s: initiating new FS watcher for [%s]",
235 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
236 rv = mFileSystemWatcher->Init(
this, mWatchPath, PR_TRUE);
237 NS_ENSURE_SUCCESS(rv, rv);
240 TRACE((
"%s: initiating saved session %s",
241 __FUNCTION__, mFileSystemWatcherGUID.get()));
242 rv = mFileSystemWatcher->InitWithSession(mFileSystemWatcherGUID,
this);
243 NS_ENSURE_SUCCESS(rv, rv);
246 rv = mFileSystemWatcher->StartWatching();
247 NS_ENSURE_SUCCESS(rv, rv);
261 NS_ENSURE_STATE(mFileSystemWatcher);
265 mRemovedPaths.clear();
266 mChangedPaths.clear();
267 mDelayedChangedPaths.clear();
270 if (mFileSystemWatcherGUID.Equals(EmptyCString())) {
273 nsCOMPtr<nsIPrefBranch2> prefBranch =
274 do_GetService(
"@mozilla.org/preferences-service;1", &rv);
275 NS_ENSURE_SUCCESS(rv, rv);
277 rv = mFileSystemWatcher->GetSessionGuid(mFileSystemWatcherGUID);
278 NS_ENSURE_SUCCESS(rv, rv);
281 mFileSystemWatcherGUID.get());
282 NS_ENSURE_SUCCESS(rv, rv);
286 rv = mFileSystemWatcher->StopWatching(PR_TRUE);
287 NS_ENSURE_SUCCESS(rv, rv);
298 if (!mStartupDelayTimer) {
299 LOG((
"%s: creating new startup delay timer", __FUNCTION__));
300 mStartupDelayTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
301 NS_ENSURE_SUCCESS(rv, rv);
304 LOG((
"%s: arming up startup delay timer [%08x]",
305 __FUNCTION__, mStartupDelayTimer.get()));
306 return mStartupDelayTimer->InitWithCallback(
this,
308 nsITimer::TYPE_ONE_SHOT);
314 if (mHasWatcherStarted) {
315 if (mEventPumpTimerIsSet) {
319 mShouldProcessEvents = PR_FALSE;
322 LOG((
"%s: arming event pump timer [%08x]",
323 __FUNCTION__, mEventPumpTimer.get()));
326 mEventPumpTimer->InitWithCallback(
this,
328 nsITimer::TYPE_ONE_SHOT);
329 NS_ENSURE_SUCCESS(rv, rv);
331 mEventPumpTimerIsSet = PR_TRUE;
332 mShouldProcessEvents = PR_TRUE;
342 TRACE((
"%s: Processing the observed event paths", __FUNCTION__));
343 TRACE((
"%s: mRemovedPaths.size() == %i", __FUNCTION__, mRemovedPaths.size()));
344 TRACE((
"%s: mAddedPaths.size() == %i", __FUNCTION__, mAddedPaths.size()));
345 TRACE((
"%s: mChangedPaths.size() == %i", __FUNCTION__, mChangedPaths.size()));
352 if (mRemovedPaths.size() > 0 && mAddedPaths.size() > 0) {
353 LOG((
"sbWatchFolderService: possible move/rename detected"));
355 NS_ENSURE_SUCCESS(rv, rv);
359 NS_ENSURE_SUCCESS(rv, rv);
362 NS_ENSURE_SUCCESS(rv, rv);
366 NS_ENSURE_SUCCESS(rv, rv);
375 LOG((
"%s: Processing event path list [aEventPathSet.size == %i]",
376 __FUNCTION__, aEventPathSet.size()));
378 if (aEventPathSet.empty()) {
382 mCurrentProcessType = aProcessType;
385 NS_ENSURE_SUCCESS(rv, rv);
387 aEventPathSet.clear();
394 LOG((
"%s: Processing the added file paths... [mAddedPaths.size == %i]",
395 __FUNCTION__, mAddedPaths.size()));
397 if (mAddedPaths.empty()) {
402 nsCOMPtr<nsIArray> uriArray;
404 NS_ENSURE_SUCCESS(rv, rv);
408 PRUint32 uriArrayLength = 0;
409 rv = uriArray->GetLength(&uriArrayLength);
410 NS_ENSURE_SUCCESS(rv, rv);
412 if (uriArrayLength > 0) {
413 nsCOMPtr<sbIDirectoryImportService> importService =
414 do_GetService(
"@songbirdnest.com/Songbird/DirectoryImportService;1", &rv);
415 NS_ENSURE_SUCCESS(rv, rv);
421 nsCOMPtr<sbIDirectoryImportJob> job;
422 rv = importService->Import(uriArray, mMainLibrary, -1, getter_AddRefs(job));
423 NS_ENSURE_SUCCESS(rv, rv);
425 nsCOMPtr<sbIJobProgressService> progressService =
426 do_GetService(
"@songbirdnest.com/Songbird/JobProgressService;1", &rv);
427 if (NS_SUCCEEDED(rv) && progressService) {
428 nsCOMPtr<sbIJobProgress> jobProgress = do_QueryInterface(job, &rv);
429 NS_ENSURE_SUCCESS(rv, rv);
431 rv = progressService->ShowProgressDialog(jobProgress, nsnull, 1);
432 NS_ENSURE_SUCCESS(rv, rv);
443 NS_ENSURE_ARG_POINTER(aURIs);
446 nsCOMPtr<nsIMutableArray> uriArray =
447 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
448 NS_ENSURE_SUCCESS(rv, rv);
450 nsCOMPtr<sbIMediacoreTypeSniffer> typeSniffer =
451 do_CreateInstance(
"@songbirdnest.com/Songbird/Mediacore/TypeSniffer;1", &rv);
452 NS_ENSURE_SUCCESS(rv, rv);
457 for (next = begin; next != end; ++
next) {
458 nsCOMPtr<nsIURI> fileURI;
461 NS_WARNING(
"Could not get a URI for a file!");
467 PRBool isValid = PR_FALSE;
468 rv = typeSniffer->IsValidMediaURL(fileURI, &isValid);
469 if (NS_SUCCEEDED(rv) && isValid) {
470 rv = uriArray->AppendElement(fileURI, PR_FALSE);
472 NS_WARNING(
"Could not append the URI to the mutable array!");
477 nsCOMPtr<nsIArray>
array = do_QueryInterface(uriArray, &rv);
478 NS_ENSURE_SUCCESS(rv, rv);
487 NS_ENSURE_ARG_POINTER(aURIRetVal);
491 nsCOMPtr<nsILocalFile> pathFile =
492 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
493 NS_ENSURE_SUCCESS(rv, rv);
495 rv = pathFile->InitWithPath(aFilePath);
496 NS_ENSURE_SUCCESS(rv, rv);
498 return mLibraryUtils->GetFileContentURI(pathFile, aURIRetVal);
505 nsCOMPtr<sbIMutablePropertyArray> properties =
507 NS_ENSURE_SUCCESS(rv, rv);
514 for (next = begin; next != end; ++
next) {
516 nsCOMPtr<nsIURI> fileURI;
519 NS_WARNING(
"Could not get the file path URI!");
524 rv = fileURI->GetSpec(pathSpec);
526 NS_WARNING(
"Could not get the URI spec!");
530 rv = properties->AppendProperty(propName, NS_ConvertUTF8toUTF16(pathSpec));
532 NS_WARNING(
"Could not append a property!");
537 rv = mMainLibrary->EnumerateItemsByProperties(properties,
this, enumType);
538 NS_ENSURE_SUCCESS(rv, rv);
546 NS_ENSURE_ARG_POINTER(aSongbirdWindow);
549 nsCOMPtr<sbIApplicationController> appController =
550 do_GetService(
"@songbirdnest.com/Songbird/ApplicationController;1", &rv);
551 NS_ENSURE_SUCCESS(rv, rv);
553 return appController->GetActiveMainWindow(aSongbirdWindow);
559 NS_ASSERTION(NS_IsMainThread(),
560 "HandleSessionLoadError() not called on main thread!");
561 NS_ENSURE_STATE(mFileSystemWatcher);
566 PRBool isUnitTestsRunning = PR_FALSE;
567 mPrefMgr->GetIsUnitTestsRunning(&isUnitTestsRunning);
568 if (isUnitTestsRunning) {
575 if (!mFileSystemWatcherGUID.IsEmpty()) {
578 rv = mFileSystemWatcher->DeleteSession(mFileSystemWatcherGUID);
580 NS_WARNING(
"Could not delete the bad session data file!");
583 mFileSystemWatcherGUID.Truncate();
586 nsCOMPtr<nsIPrefBranch2> prefBranch =
587 do_GetService(
"@mozilla.org/preferences-service;1", &rv);
588 NS_ENSURE_SUCCESS(rv, rv);
591 NS_ENSURE_SUCCESS(rv, rv);
594 rv = mFileSystemWatcher->Init(
this, mWatchPath, PR_TRUE);
595 NS_ENSURE_SUCCESS(rv, rv);
597 rv = mFileSystemWatcher->StartWatching();
598 NS_ENSURE_SUCCESS(rv, rv);
601 nsString dialogTitle =
602 bundle.
Get(
"watch_folder.session_load_error.rescan_title");
604 nsTArray<nsString> params;
605 params.AppendElement(mWatchPath);
606 nsString dialogText =
607 bundle.
Format(
"watch_folder.session_load_error.rescan_text", params);
609 nsCOMPtr<nsIDOMWindow> songbirdWindow;
611 NS_ENSURE_SUCCESS(rv, rv);
613 nsCOMPtr<sbIPrompter> prompter =
614 do_CreateInstance(
"@songbirdnest.com/Songbird/Prompter;1", &rv);
615 NS_ENSURE_SUCCESS(rv, rv);
617 rv = prompter->SetWaitForWindow(PR_TRUE);
618 NS_ENSURE_SUCCESS(rv, rv);
620 PRBool shouldRescan = PR_FALSE;
621 prompter->Confirm(songbirdWindow,
622 dialogTitle.BeginReading(),
623 dialogText.BeginReading(),
630 nsCOMPtr<sbIDirectoryImportService> dirImportService =
631 do_GetService(
"@songbirdnest.com/Songbird/DirectoryImportService;1", &rv);
632 NS_ENSURE_SUCCESS(rv, rv);
635 nsCOMPtr<nsILocalFile> watchPathFile =
636 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
637 NS_ENSURE_SUCCESS(rv, rv);
639 rv = watchPathFile->InitWithPath(mWatchPath);
640 NS_ENSURE_SUCCESS(rv, rv);
642 nsCOMPtr<nsIMutableArray> dirArray =
643 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
645 rv = dirArray->AppendElement(watchPathFile, PR_FALSE);
646 NS_ENSURE_SUCCESS(rv, rv);
648 nsCOMPtr<sbIDirectoryImportJob> importJob;
649 rv = dirImportService->Import(dirArray,
652 getter_AddRefs(importJob));
653 NS_ENSURE_SUCCESS(rv, rv);
655 nsCOMPtr<sbIJobProgressService> progressService =
656 do_GetService(
"@songbirdnest.com/Songbird/JobProgressService;1", &rv);
657 if (NS_SUCCEEDED(rv) && progressService) {
658 nsCOMPtr<sbIJobProgress> job = do_QueryInterface(importJob, &rv);
659 NS_ENSURE_SUCCESS(rv, rv);
661 rv = progressService->ShowProgressDialog(job, nsnull, 1);
662 NS_ENSURE_SUCCESS(rv, rv);
675 PRBool isUnitTestsRunning = PR_FALSE;
676 mPrefMgr->GetIsUnitTestsRunning(&isUnitTestsRunning);
677 if (isUnitTestsRunning) {
682 nsString dialogTitle = bundle.
Get(
"watch_folder.root_path_missing.title");
684 nsTArray<nsString> params;
685 params.AppendElement(mWatchPath);
686 nsString dialogText =
687 bundle.
Format(
"watch_folder.root_path_missing.text", params);
689 nsCOMPtr<nsIDOMWindow> songbirdWindow;
691 NS_ENSURE_SUCCESS(rv, rv);
693 nsCOMPtr<sbIPrompter> prompter =
694 do_CreateInstance(
"@songbirdnest.com/Songbird/Prompter;1", &rv);
695 NS_ENSURE_SUCCESS(rv, rv);
697 rv = prompter->SetWaitForWindow(PR_TRUE);
698 NS_ENSURE_SUCCESS(rv, rv);
700 rv = prompter->Alert(songbirdWindow,
701 dialogTitle.BeginReading(),
702 dialogText.BeginReading());
703 NS_ENSURE_SUCCESS(rv, rv);
710 PRBool *aIsIgnoredPath)
712 NS_ENSURE_ARG_POINTER(aIsIgnoredPath);
714 sbStringMap::iterator foundIter = mIgnorePaths.find(nsString(aFilePath));
715 if (foundIter == mIgnorePaths.end()) {
716 *aIsIgnoredPath = PR_FALSE;
718 *aIsIgnoredPath = PR_TRUE;
719 if (foundIter->second.count > 0) {
720 --foundIter->second.count;
721 if ((foundIter->second.count < 1) && (foundIter->second.depth < 1)) {
723 mIgnorePaths.erase(foundIter);
734 NS_ENSURE_SUCCESS(rv, rv);
745 NS_ENSURE_SUCCESS(rv, rv);
748 if (mStartupDelayTimer) {
749 rv = mStartupDelayTimer->Cancel();
750 NS_ENSURE_SUCCESS(rv, rv);
752 LOG((
"%s: app is shutting down, aborting startup delay timer [%08x]",
753 __FUNCTION__, mStartupDelayTimer.get()));
757 mFileSystemWatcher = nsnull;
766 LOG((
"%s: OnWatchFolderPathChanged( %s )",
768 NS_ConvertUTF16toUTF8(aNewWatchPath).
get()));
770 if (mWatchPath.Equals(aNewWatchPath)) {
775 nsCOMPtr<nsIPrefBranch2> prefBranch =
776 do_GetService(
"@mozilla.org/preferences-service;1", &rv);
777 NS_ENSURE_SUCCESS(rv, rv);
779 mWatchPath = aNewWatchPath;
782 TRACE((
"%s: already watching, stopping...", __FUNCTION__));
783 NS_ENSURE_STATE(mFileSystemWatcher);
792 PRBool hasSavedSessionGUID;
794 &hasSavedSessionGUID);
795 NS_ENSURE_SUCCESS(rv, rv);
797 if (hasSavedSessionGUID) {
799 NS_ENSURE_SUCCESS(rv, rv);
802 if (!mFileSystemWatcherGUID.IsEmpty()) {
805 rv = mFileSystemWatcher->DeleteSession(mFileSystemWatcherGUID);
808 NS_WARNING(
"Could not delete old session data!");
811 mFileSystemWatcherGUID.Truncate();
816 mShouldReinitWatcher = PR_TRUE;
823 mRemovedPaths.clear();
824 mChangedPaths.clear();
825 mDelayedChangedPaths.clear();
827 rv = mFileSystemWatcher->StopWatching(PR_FALSE);
828 NS_ENSURE_SUCCESS(rv, rv);
830 else if (mServiceState ==
eDisabled && !mWatchPath.IsEmpty()) {
834 PRBool shouldEnable = PR_FALSE;
837 if (NS_SUCCEEDED(rv) && shouldEnable) {
838 TRACE((
"%s: not watching yet, arming...", __FUNCTION__));
843 NS_ENSURE_SUCCESS(rv, rv);
853 LOG((
"%s: OnEnableWatchFolderChanged( aShouldEnable=%s )",
855 (aShouldEnable ?
"true" :
"false")));
861 if (mServiceState ==
eWatching && !aShouldEnable) {
863 NS_ENSURE_SUCCESS(rv, rv);
868 else if (mServiceState ==
eStarted && aShouldEnable) {
870 NS_ENSURE_SUCCESS(rv, rv);
877 !mWatchPath.IsEmpty() &&
881 NS_ENSURE_SUCCESS(rv, rv);
891 sbWatchFolderService::GetIsSupported(PRBool *aIsSupported)
893 NS_ENSURE_ARG_POINTER(aIsSupported);
899 sbWatchFolderService::GetIsRunning(PRBool *aIsRunning)
901 NS_ENSURE_ARG_POINTER(aIsRunning);
902 *aIsRunning = (mServiceState ==
eWatching);
907 sbWatchFolderService::AddIgnorePath(
const nsAString & aFilePath)
909 LOG((
"sbWatchFolderService::AddIgnorePath %s",
910 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
912 nsString filePath(aFilePath);
914 sbStringMap::iterator it = mIgnorePaths.find(filePath);
915 if (it == mIgnorePaths.end()) {
917 mIgnorePaths[filePath] = ignorePathData_t(1, 0);
920 ++(it->second.depth);
926 sbWatchFolderService::RemoveIgnorePath(
const nsAString & aFilePath)
928 LOG((
"sbWatchFolderService::RemoveIgnorePath %s",
929 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
931 nsString filePath(aFilePath);
933 sbStringMap::iterator it = mIgnorePaths.find(filePath);
935 if (it != mIgnorePaths.end()) {
936 it->second.depth = PR_MAX(0, it->second.depth - 1);
937 if (it->second.depth < 1 && it->second.count < 1) {
939 mIgnorePaths.erase(it);
947 sbWatchFolderService::AddIgnoreCount(
const nsAString & aFilePath,
950 nsString filePath(aFilePath);
952 sbStringMap::iterator it = mIgnorePaths.find(filePath);
953 if (it == mIgnorePaths.end()) {
955 ignorePathData_t newData(0, 0);
956 it = mIgnorePaths.insert(sbStringMap::value_type(filePath, newData)).first;
959 it->second.count +=
aCount;
960 if (it->second.count < 1) {
961 it->second.count = 0;
962 if (it->second.depth < 1) {
964 mIgnorePaths.erase(it);
975 sbWatchFolderService::OnWatcherStarted()
980 if (!mEventPumpTimer) {
981 mEventPumpTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
982 NS_ENSURE_SUCCESS(rv, rv);
985 if (!mChangeDelayTimer) {
986 mChangeDelayTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
987 NS_ENSURE_SUCCESS(rv, rv);
993 LOG((
"%s: arming event pump timer [%08x]",
994 __FUNCTION__, mEventPumpTimer.get()));
995 rv = mEventPumpTimer->InitWithCallback(
this,
997 nsITimer::TYPE_ONE_SHOT);
998 NS_ENSURE_SUCCESS(rv, rv);
1000 mEventPumpTimerIsSet = PR_TRUE;
1001 mShouldProcessEvents = PR_TRUE;
1002 mHasWatcherStarted = PR_TRUE;
1004 TRACE((
"sbWatchFolderService::OnWatcherStarted (path [%s])",
1005 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
1010 sbWatchFolderService::OnWatcherStopped()
1012 if (mEventPumpTimer) {
1013 mEventPumpTimer->Cancel();
1015 if (mChangeDelayTimer) {
1016 mChangeDelayTimer->Cancel();
1019 mHasWatcherStarted = PR_FALSE;
1024 if (mShouldReinitWatcher) {
1026 if (!mFlushFSWatcherTimer) {
1027 mFlushFSWatcherTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
1028 NS_ENSURE_SUCCESS(rv, rv);
1031 rv = mFlushFSWatcherTimer->InitWithCallback(
this,
1033 nsITimer::TYPE_ONE_SHOT);
1034 NS_ENSURE_SUCCESS(rv, rv);
1037 TRACE((
"sbWatchFolderService::OnWatcherStopped (path [%s])",
1038 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
1043 sbWatchFolderService::OnWatcherError(PRUint32 aErrorType,
1044 const nsAString & aDescription)
1047 switch (aErrorType) {
1049 NS_WARNING(
"WARNING: Root path is missing!");
1051 NS_ENSURE_SUCCESS(rv, rv);
1055 NS_WARNING(
"WARNING: Invalid directory!");
1060 NS_ENSURE_SUCCESS(rv, rv);
1068 sbWatchFolderService::OnFileSystemChanged(
const nsAString & aFilePath)
1070 LOG((
"sbWatchFolderService::OnFileSystemChanged %s",
1071 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1073 PRBool isIgnoredPath = PR_FALSE;
1075 NS_ENSURE_SUCCESS(rv, rv);
1078 if (isIgnoredPath) {
1082 nsString filePath(aFilePath);
1086 if (mHasWatcherStarted) {
1089 if (foundIter != mChangedPaths.end()) {
1092 mDelayedChangedPaths.insert(filePath);
1095 if (!mChangeDelayTimerIsSet) {
1096 rv = mChangeDelayTimer->InitWithCallback(
this,
1098 nsITimer::TYPE_ONE_SHOT);
1099 NS_ENSURE_SUCCESS(rv, rv);
1101 mChangeDelayTimerIsSet = PR_TRUE;
1105 mChangedPaths.insert(filePath);
1107 NS_ENSURE_SUCCESS(rv, rv);
1111 mChangedPaths.insert(filePath);
1118 sbWatchFolderService::OnFileSystemRemoved(
const nsAString & aFilePath)
1120 LOG((
"sbWatchFolderService::OnFileSystemRemoved %s",
1121 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1123 PRBool isIgnoredPath = PR_FALSE;
1125 NS_ENSURE_SUCCESS(rv, rv);
1127 if (!isIgnoredPath) {
1128 mRemovedPaths.insert(nsString(aFilePath));
1132 NS_ENSURE_SUCCESS(rv, rv);
1139 sbWatchFolderService::OnFileSystemAdded(
const nsAString & aFilePath)
1141 LOG((
"sbWatchFolderService::OnFileSystemAdded %s",
1142 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1144 PRBool isIgnoredPath = PR_FALSE;
1146 NS_ENSURE_SUCCESS(rv, rv);
1148 if (!isIgnoredPath) {
1149 mAddedPaths.insert(nsString(aFilePath));
1153 NS_ENSURE_SUCCESS(rv, rv);
1163 sbWatchFolderService::OnEnumerationBegin(
sbIMediaList *aMediaList,
1166 if (!mEnumeratedMediaItems) {
1168 mEnumeratedMediaItems =
1169 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1170 NS_ENSURE_SUCCESS(rv, rv);
1178 sbWatchFolderService::OnEnumeratedItem(
sbIMediaList *aMediaList,
1182 mEnumeratedMediaItems->AppendElement(aMediaItem, PR_FALSE);
1188 sbWatchFolderService::OnEnumerationEnd(
sbIMediaList *aMediaList,
1189 nsresult aStatusCode)
1193 rv = mEnumeratedMediaItems->GetLength(&length);
1194 NS_ENSURE_SUCCESS(rv, rv);
1196 LOG((
"%s: Found %i media items during enumeration", __FUNCTION__, length));
1199 if (mCurrentProcessType ==
eRemoval) {
1201 nsCOMPtr<sbIWFRemoveHelper9001> helper =
1202 do_GetService(
"@songbirdnest.com/Songbird/RemoveHelper;1", &rv);
1203 NS_ENSURE_SUCCESS(rv, rv);
1205 mRemovedPaths.clear();
1207 helper->Remove(mEnumeratedMediaItems);
1208 NS_ENSURE_SUCCESS(rv, rv);
1210 else if (mCurrentProcessType ==
eChanged) {
1212 nsCOMPtr<sbIFileMetadataService> metadataService =
1213 do_GetService(
"@songbirdnest.com/Songbird/FileMetadataService;1", &rv);
1214 NS_ENSURE_SUCCESS(rv, rv);
1216 nsCOMPtr<sbIJobProgress> jobProgress;
1217 rv = metadataService->Read(mEnumeratedMediaItems,
1218 getter_AddRefs(jobProgress));
1219 NS_ENSURE_SUCCESS(rv, rv);
1224 nsCOMPtr<sbIWFMoveRenameHelper9000> helper =
1225 do_GetService(
"@songbirdnest.com/Songbird/MoveRenameHelper;1", &rv);
1226 NS_ENSURE_SUCCESS(rv, rv);
1228 nsCOMPtr<nsIArray> uriArray;
1230 NS_ENSURE_SUCCESS(rv, rv);
1231 mAddedPaths.clear();
1235 rv = uriArray->GetLength(&length);
1236 NS_ENSURE_SUCCESS(rv, rv);
1238 LOG((
"%s: Sending %i added item URL's to the move-rename helper",
1239 __FUNCTION__, length));
1242 rv = helper->Process(mEnumeratedMediaItems, uriArray,
this);
1243 NS_ENSURE_SUCCESS(rv, rv);
1255 for (next = begin; next != end; ++
next) {
1256 nsCOMPtr<nsILocalFile> curFile =
1257 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
1258 NS_ENSURE_SUCCESS(rv, rv);
1260 rv = curFile->InitWithPath(*next);
1261 if (NS_FAILED(rv)) {
1262 NS_WARNING(
"ERROR: Could not init a nsILocalFile with a path!");
1266 PRBool doesExist = PR_FALSE;
1267 rv = curFile->Exists(&doesExist);
1268 if (NS_FAILED(rv) || !doesExist) {
1269 mAddedPaths.erase(*next);
1274 NS_ENSURE_SUCCESS(rv, rv);
1277 rv = mEnumeratedMediaItems->Clear();
1278 NS_ENSURE_SUCCESS(rv, rv);
1280 mCurrentProcessType =
eNone;
1288 sbWatchFolderService::Notify(nsITimer *aTimer)
1293 if (aTimer == mStartupDelayTimer) {
1294 LOG((
"%s: startup delay timer [%08x] fired",
1295 __FUNCTION__, mStartupDelayTimer.get()));
1297 NS_ENSURE_SUCCESS(rv, rv);
1301 else if (aTimer == mFlushFSWatcherTimer) {
1302 mFileSystemWatcher = nsnull;
1303 mShouldReinitWatcher = PR_FALSE;
1306 NS_ENSURE_SUCCESS(rv, rv);
1310 else if (aTimer == mEventPumpTimer) {
1311 if (mShouldProcessEvents) {
1315 NS_ENSURE_SUCCESS(rv, rv);
1317 mEventPumpTimerIsSet = PR_FALSE;
1322 LOG((
"%s: arming event pump timer [%08x]",
1323 __FUNCTION__, mEventPumpTimer.get()));
1324 rv = mEventPumpTimer->InitWithCallback(
this,
1326 nsITimer::TYPE_ONE_SHOT);
1327 NS_ENSURE_SUCCESS(rv, rv);
1329 mShouldProcessEvents = PR_TRUE;
1334 else if (aTimer == mChangeDelayTimer) {
1336 NS_ENSURE_SUCCESS(rv, rv);
1338 mChangeDelayTimerIsSet = PR_FALSE;
1348 sbWatchFolderService::OnJobProgress(
sbIJobProgress *aJobProgress)
1350 NS_ENSURE_ARG_POINTER(aJobProgress);
1353 nsresult rv = aJobProgress->GetStatus(&status);
1354 NS_ENSURE_SUCCESS(rv, rv);
1362 NS_ENSURE_SUCCESS(rv, rv);
1374 const char *aLoaderStr,
1376 const nsModuleComponentInfo *aInfo)
1378 NS_ENSURE_ARG_POINTER(aCompMgr);
1379 NS_ENSURE_ARG_POINTER(aPath);
1380 NS_ENSURE_ARG_POINTER(aLoaderStr);
1381 NS_ENSURE_ARG_POINTER(aType);
1382 NS_ENSURE_ARG_POINTER(aInfo);
1384 nsresult rv = NS_ERROR_UNEXPECTED;
1385 nsCOMPtr<nsICategoryManager> catMgr =
1386 do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
1387 NS_ENSURE_SUCCESS(rv, rv);
1389 rv = catMgr->AddCategoryEntry(
"app-startup",
1393 PR_TRUE, PR_TRUE, nsnull);
1394 NS_ENSURE_SUCCESS(rv, rv);
#define STARTUP_TIMER_DELAY
nsresult GetURIArrayForStringPaths(sbStringSet &aPathsSet, nsIArray **aURIs)
friend class sbWatchFolderPrefMgr
#define PREF_WATCHFOLDER_SESSIONGUID
std::set< nsString, sbStringIgnoreCaseCompare > sbStringSet
Generic interface for exposing long running jobs to the UI.
nsString Get(const nsAString &aKey, const nsAString &aDefault=SBVoidString())
nsresult StopWatchingFolder()
nsString Format(const nsAString &aKey, nsTArray< nsString > &aParams, const nsAString &aDefault=SBVoidString())
nsresult ProcessEventPaths()
nsresult OnWatchFolderPathChanged(const nsAString &aNewPath)
nsresult SetStartupDelayTimer()
nsresult HandleSessionLoadError()
const unsigned long INVALID_DIRECTORY
nsresult OnEnableWatchFolderChanged(PRBool aShouldEnable)
const unsigned short STATUS_RUNNING
Constant indicating that the job is active.
nsresult ProcessAddedPaths()
nsresult GetSongbirdWindow(nsIDOMWindow **aSongbirdWindow)
#define CHANGE_DELAY_TIMER_DELAY
nsresult EnumerateItemsByPaths(sbStringSet &aPathSet)
sbStringSet::iterator sbStringSetIter
#define SONGBIRD_WATCHFOLDERSERVICE_CONTRACTID
virtual ~sbWatchFolderService()
#define PREF_WATCHFOLDER_PATH
nsresult HandleEventPathList(sbStringSet &aEventPathSet, EProcessType aProcessType)
#define PREF_WATCHFOLDER_ENABLE
#define FLUSH_FS_WATCHER_DELAY
const unsigned long ROOT_PATH_MISSING
Songbird String Bundle Definitions.
sbStringSet::iterator sbStringSetIter
#define SONGBIRD_WATCHFOLDERSERVICE_CLASSNAME
#define EVENT_PUMP_TIMER_DELAY
std::set< nsString > sbStringSet
Implemented to receive notifications from sbIJobProgress interfaces.
nsresult SetEventPumpTimer()
restoreHistoryPrecursor aCount
NS_DECL_ISUPPORTS NS_DECL_SBIWATCHFOLDERSERVICE NS_DECL_SBIFILESYSTEMLISTENER NS_DECL_SBIMEDIALISTENUMERATIONLISTENER NS_DECL_NSITIMERCALLBACK NS_DECL_SBIJOBPROGRESSLISTENER nsresult Init()
#define SB_PROPERTY_CONTENTURL
nsresult DecrementIgnoredPathCount(const nsAString &aFilePath, PRBool *aIsIgnoredPath)
static NS_METHOD RegisterSelf(nsIComponentManager *aCompMgr, nsIFile *aPath, const char *aLoaderStr, const char *aType, const nsModuleComponentInfo *aInfo)
const unsigned long SESSION_LOAD_ERROR
nsresult GetFilePathURI(const nsAString &aFilePath, nsIURI **aURIRetVal)
nsresult StartWatchingFolder()
nsresult HandleRootPathMissing()
NS_IMPL_ISUPPORTS5(sbWatchFolderService, sbIWatchFolderService, sbIFileSystemListener, sbIMediaListEnumerationListener, nsITimerCallback, sbIJobProgressListener) sbWatchFolderService