29 #include <sbIWFMoveRenameHelper9000.h>
30 #include <sbIWFRemoveHelper9001.h>
33 #include <sbIApplicationController.h>
34 #include <sbIDirectoryImportService.h>
35 #include <sbIFileMetadataService.h>
36 #include <sbIJobProgress.h>
37 #include <sbIJobProgressService.h>
38 #include <sbIPropertyArray.h>
40 #include <sbIPrompter.h>
41 #include <nsComponentManagerUtils.h>
42 #include <nsServiceManagerUtils.h>
43 #include <nsICategoryManager.h>
44 #include <nsILocalFile.h>
45 #include <nsIObserverService.h>
48 #include <sbIMediacoreTypeSniffer.h>
49 #include <nsThreadUtils.h>
50 #include <nsXPCOMCIDInternal.h>
51 #include <nsIXULRuntime.h>
56 static PRLogModuleInfo* gLog = nsnull;
68 mCanInteract = PR_TRUE;
69 mHasWatcherStarted = PR_FALSE;
70 mShouldReinitWatcher = PR_FALSE;
71 mShouldSynchronize = PR_FALSE;
72 mEventPumpTimerIsSet = PR_FALSE;
73 mChangeDelayTimerIsSet = PR_FALSE;
74 mShouldProcessEvents = PR_FALSE;
75 mCurrentProcessType =
eNone;
79 gLog = PR_NewLogModule(
"sbWatchFolder");
97 nsCOMPtr<sbIFileSystemWatcher> fileSystemWatcher =
98 do_CreateInstance(
"@songbirdnest.com/filesystem/watcher;1", &rv);
102 PRBool isWatcherSupported = PR_FALSE;
103 rv = fileSystemWatcher->GetIsSupported(&isWatcherSupported);
104 NS_ENSURE_SUCCESS(rv, rv);
107 if (isWatcherSupported) {
108 nsCOMPtr<nsIXULRuntime> appInfo =
109 do_GetService(XULRUNTIME_SERVICE_CONTRACTID, &rv);
111 if (NS_SUCCEEDED(rv)) {
112 PRBool isInSafeMode = PR_FALSE;
113 rv = appInfo->GetInSafeMode(&isInSafeMode);
115 isWatcherSupported = NS_FAILED(rv) || !isInSafeMode;
119 if (!isWatcherSupported) {
125 do_GetService(
"@songbirdnest.com/Songbird/library/Manager;1", &rv);
126 NS_ENSURE_SUCCESS(rv, rv);
150 if (mWatchPath.Equals(EmptyString())) {
151 return NS_ERROR_UNEXPECTED;
159 NS_ENSURE_SUCCESS(rv, rv);
161 TRACE((
"%s: started watching [%s]",
163 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
173 if (mWatchPath.IsEmpty() || mServiceState !=
eStarted) {
179 do_CreateInstance(
"@songbirdnest.com/filesystem/watcher;1", &rv);
180 NS_ENSURE_SUCCESS(rv, rv);
182 if (mFileSystemWatcherGUID.Equals(EmptyCString())) {
185 TRACE((
"%s: initiating new FS watcher for [%s]",
187 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
188 rv = mFileSystemWatcher->Init(
this, mWatchPath, PR_TRUE);
189 NS_ENSURE_SUCCESS(rv, rv);
192 TRACE((
"%s: initiating saved session %s",
193 __FUNCTION__, mFileSystemWatcherGUID.get()));
194 rv = mFileSystemWatcher->InitWithSession(mFileSystemWatcherGUID,
this);
195 NS_ENSURE_SUCCESS(rv, rv);
198 if (mShouldSynchronize) {
199 NS_ENSURE_STATE(mMediaList);
203 rv = mFileSystemWatcher->StartWatching();
204 NS_ENSURE_SUCCESS(rv, rv);
209 if (mShouldSynchronize) {
210 mShouldSynchronize = PR_FALSE;
223 NS_ENSURE_STATE(mFileSystemWatcher);
227 mRemovedPaths.clear();
228 mChangedPaths.clear();
229 mDelayedChangedPaths.clear();
232 if (mFileSystemWatcherGUID.Equals(EmptyCString())) {
235 rv = mFileSystemWatcher->GetSessionGuid(mFileSystemWatcherGUID);
236 NS_ENSURE_SUCCESS(rv, rv);
240 rv = mFileSystemWatcher->StopWatching(PR_TRUE);
241 NS_ENSURE_SUCCESS(rv, rv);
252 if (!mStartupDelayTimer) {
253 LOG((
"%s: creating new startup delay timer", __FUNCTION__));
254 mStartupDelayTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
255 NS_ENSURE_SUCCESS(rv, rv);
258 LOG((
"%s: arming up startup delay timer [%08x]",
259 __FUNCTION__, mStartupDelayTimer.get()));
260 return mStartupDelayTimer->InitWithCallback(
this,
262 nsITimer::TYPE_ONE_SHOT);
268 if (mHasWatcherStarted) {
269 if (mEventPumpTimerIsSet) {
273 mShouldProcessEvents = PR_FALSE;
276 LOG((
"%s: arming event pump timer [%08x]",
277 __FUNCTION__, mEventPumpTimer.get()));
280 mEventPumpTimer->InitWithCallback(
this,
282 nsITimer::TYPE_ONE_SHOT);
283 NS_ENSURE_SUCCESS(rv, rv);
285 mEventPumpTimerIsSet = PR_TRUE;
286 mShouldProcessEvents = PR_TRUE;
296 TRACE((
"%s: Processing the observed event paths", __FUNCTION__));
297 TRACE((
"%s: mRemovedPaths.size() == %i", __FUNCTION__, mRemovedPaths.size()));
298 TRACE((
"%s: mAddedPaths.size() == %i", __FUNCTION__, mAddedPaths.size()));
299 TRACE((
"%s: mChangedPaths.size() == %i", __FUNCTION__, mChangedPaths.size()));
306 if (mRemovedPaths.size() > 0 && mAddedPaths.size() > 0) {
307 LOG((
"sbWatchFolder: possible move/rename detected"));
309 NS_ENSURE_SUCCESS(rv, rv);
313 NS_ENSURE_SUCCESS(rv, rv);
316 NS_ENSURE_SUCCESS(rv, rv);
320 NS_ENSURE_SUCCESS(rv, rv);
329 LOG((
"%s: Processing event path list [aEventPathSet.size == %i]",
330 __FUNCTION__, aEventPathSet.size()));
332 if (aEventPathSet.empty()) {
336 mCurrentProcessType = aProcessType;
339 NS_ENSURE_SUCCESS(rv, rv);
341 aEventPathSet.clear();
348 LOG((
"%s: Processing the added file paths... [mAddedPaths.size == %i]",
349 __FUNCTION__, mAddedPaths.size()));
351 if (mAddedPaths.empty()) {
356 nsCOMPtr<nsIArray> uriArray;
358 NS_ENSURE_SUCCESS(rv, rv);
362 PRUint32 uriArrayLength = 0;
363 rv = uriArray->GetLength(&uriArrayLength);
364 NS_ENSURE_SUCCESS(rv, rv);
366 if (uriArrayLength > 0) {
367 nsCOMPtr<sbIDirectoryImportService> importService;
368 rv = GetImporter(getter_AddRefs(importService));
369 NS_ENSURE_SUCCESS(rv, rv);
375 nsCOMPtr<sbIDirectoryImportJob> job;
376 rv = importService->ImportWithCustomSnifferAndMetadataScanner(
382 getter_AddRefs(job));
383 NS_ENSURE_SUCCESS(rv, rv);
385 nsCOMPtr<sbIJobProgressService> progressService =
386 do_GetService(
"@songbirdnest.com/Songbird/JobProgressService;1", &rv);
387 if (NS_SUCCEEDED(rv) && progressService) {
388 nsCOMPtr<sbIJobProgress> jobProgress = do_QueryInterface(job, &rv);
389 NS_ENSURE_SUCCESS(rv, rv);
391 rv = progressService->ShowProgressDialog(jobProgress, nsnull, 1);
392 NS_ENSURE_SUCCESS(rv, rv);
403 NS_ENSURE_ARG_POINTER(aURIs);
406 nsCOMPtr<nsIMutableArray> uriArray =
407 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
408 NS_ENSURE_SUCCESS(rv, rv);
411 rv = GetTypeSniffer(getter_AddRefs(typeSniffer));
412 NS_ENSURE_SUCCESS(rv,rv);
417 for (next = begin; next != end; ++
next) {
418 nsCOMPtr<nsIURI> fileURI;
421 NS_WARNING(
"Could not get a URI for a file!");
427 PRBool isValid = PR_FALSE;
428 rv = typeSniffer->IsValidMediaURL(fileURI, &isValid);
429 if (NS_SUCCEEDED(rv) && isValid) {
430 rv = uriArray->AppendElement(fileURI, PR_FALSE);
432 NS_WARNING(
"Could not append the URI to the mutable array!");
437 nsCOMPtr<nsIArray>
array = do_QueryInterface(uriArray, &rv);
438 NS_ENSURE_SUCCESS(rv, rv);
447 NS_ENSURE_ARG_POINTER(aURIRetVal);
451 nsCOMPtr<nsILocalFile> pathFile =
452 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
453 NS_ENSURE_SUCCESS(rv, rv);
455 rv = pathFile->InitWithPath(aFilePath);
456 NS_ENSURE_SUCCESS(rv, rv);
458 return mLibraryUtils->GetFileContentURI(pathFile, aURIRetVal);
465 nsCOMPtr<sbIMutablePropertyArray> properties =
467 NS_ENSURE_SUCCESS(rv, rv);
474 for (next = begin; next != end; ++
next) {
476 nsCOMPtr<nsIURI> fileURI;
479 NS_WARNING(
"Could not get the file path URI!");
484 rv = fileURI->GetSpec(pathSpec);
486 NS_WARNING(
"Could not get the URI spec!");
490 rv = properties->AppendProperty(propName, NS_ConvertUTF8toUTF16(pathSpec));
492 NS_WARNING(
"Could not append a property!");
497 rv = mMediaList->EnumerateItemsByProperties(properties,
this, enumType);
498 NS_ENSURE_SUCCESS(rv, rv);
506 NS_ENSURE_ARG_POINTER(aSongbirdWindow);
509 nsCOMPtr<sbIApplicationController> appController =
510 do_GetService(
"@songbirdnest.com/Songbird/ApplicationController;1", &rv);
511 NS_ENSURE_SUCCESS(rv, rv);
513 return appController->GetActiveMainWindow(aSongbirdWindow);
519 NS_ASSERTION(NS_IsMainThread(),
520 "HandleSessionLoadError() not called on main thread!");
521 NS_ENSURE_STATE(mFileSystemWatcher);
533 if (!mFileSystemWatcherGUID.IsEmpty()) {
536 rv = mFileSystemWatcher->DeleteSession(mFileSystemWatcherGUID);
538 NS_WARNING(
"Could not delete the bad session data file!");
541 mFileSystemWatcherGUID.Truncate();
544 rv = mFileSystemWatcher->Init(
this, mWatchPath, PR_TRUE);
545 NS_ENSURE_SUCCESS(rv, rv);
547 rv = mFileSystemWatcher->StartWatching();
548 NS_ENSURE_SUCCESS(rv, rv);
551 nsString dialogTitle =
552 bundle.
Get(
"watch_folder.session_load_error.rescan_title");
554 nsTArray<nsString> params;
555 params.AppendElement(mWatchPath);
556 nsString dialogText =
557 bundle.
Format(
"watch_folder.session_load_error.rescan_text", params);
559 nsCOMPtr<nsIDOMWindow> songbirdWindow;
561 NS_ENSURE_SUCCESS(rv, rv);
563 nsCOMPtr<sbIPrompter> prompter =
564 do_CreateInstance(
"@songbirdnest.com/Songbird/Prompter;1", &rv);
565 NS_ENSURE_SUCCESS(rv, rv);
567 rv = prompter->SetWaitForWindow(PR_TRUE);
568 NS_ENSURE_SUCCESS(rv, rv);
570 PRBool shouldRescan = PR_FALSE;
571 prompter->Confirm(songbirdWindow,
572 dialogTitle.BeginReading(),
573 dialogText.BeginReading(),
580 NS_ENSURE_SUCCESS(rv, rv);
592 nsCOMPtr<sbIDirectoryImportService> dirImportService;
593 rv = GetImporter(getter_AddRefs(dirImportService));
594 NS_ENSURE_SUCCESS(rv, rv);
597 nsCOMPtr<nsILocalFile> watchPathFile =
598 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
599 NS_ENSURE_SUCCESS(rv, rv);
601 rv = watchPathFile->InitWithPath(mWatchPath);
602 NS_ENSURE_SUCCESS(rv, rv);
604 nsCOMPtr<nsIMutableArray> dirArray =
605 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
607 rv = dirArray->AppendElement(watchPathFile, PR_FALSE);
608 NS_ENSURE_SUCCESS(rv, rv);
610 nsCOMPtr<sbIDirectoryImportJob> importJob;
611 rv = dirImportService->ImportWithCustomSnifferAndMetadataScanner(
617 getter_AddRefs(importJob));
618 NS_ENSURE_SUCCESS(rv, rv);
628 nsCOMPtr<sbIJobProgressService> progressService =
629 do_GetService(
"@songbirdnest.com/Songbird/JobProgressService;1", &rv);
630 NS_ENSURE_SUCCESS(rv, rv);
632 nsCOMPtr<sbIJobProgress> job = do_QueryInterface(importJob, &rv);
633 NS_ENSURE_SUCCESS(rv, rv);
635 nsCOMPtr<sbIApplicationController> appController =
636 do_GetService(
"@songbirdnest.com/Songbird/ApplicationController;1", &rv);
637 NS_ENSURE_SUCCESS(rv, rv);
639 nsCOMPtr<nsIDOMWindow> activeWindow;
640 rv = appController->GetActiveWindow(getter_AddRefs(activeWindow));
641 NS_ENSURE_SUCCESS(rv, rv);
643 rv = progressService->ShowProgressDialog(job, activeWindow, 1);
644 NS_ENSURE_SUCCESS(rv, rv);
660 nsString dialogTitle = bundle.
Get(
"watch_folder.root_path_missing.title");
662 nsTArray<nsString> params;
663 params.AppendElement(mWatchPath);
664 nsString dialogText =
665 bundle.
Format(
"watch_folder.root_path_missing.text", params);
667 nsCOMPtr<nsIDOMWindow> songbirdWindow;
669 NS_ENSURE_SUCCESS(rv, rv);
671 nsCOMPtr<sbIPrompter> prompter =
672 do_CreateInstance(
"@songbirdnest.com/Songbird/Prompter;1", &rv);
673 NS_ENSURE_SUCCESS(rv, rv);
675 rv = prompter->SetWaitForWindow(PR_TRUE);
676 NS_ENSURE_SUCCESS(rv, rv);
678 rv = prompter->Alert(songbirdWindow,
679 dialogTitle.BeginReading(),
680 dialogText.BeginReading());
681 NS_ENSURE_SUCCESS(rv, rv);
688 PRBool *aIsIgnoredPath)
690 NS_ENSURE_ARG_POINTER(aIsIgnoredPath);
692 sbStringMap::iterator foundIter = mIgnorePaths.find(nsString(aFilePath));
693 if (foundIter == mIgnorePaths.end()) {
694 *aIsIgnoredPath = PR_FALSE;
696 *aIsIgnoredPath = PR_TRUE;
697 if (foundIter->second.count > 0) {
698 --foundIter->second.count;
699 if ((foundIter->second.count < 1) && (foundIter->second.depth < 1)) {
701 mIgnorePaths.erase(foundIter);
709 sbWatchFolder::Start(
const nsACString & aSessionGuid)
711 mFileSystemWatcherGUID = aSessionGuid;
714 NS_ENSURE_SUCCESS(rv, rv);
720 sbWatchFolder::Stop(nsACString & _retval NS_OUTPARAM)
725 NS_ENSURE_SUCCESS(rv, rv);
728 if (mStartupDelayTimer) {
729 rv = mStartupDelayTimer->Cancel();
730 NS_ENSURE_SUCCESS(rv, rv);
732 LOG((
"%s: app is shutting down, aborting startup delay timer [%08x]",
733 __FUNCTION__, mStartupDelayTimer.get()));
736 _retval = mFileSystemWatcherGUID;
739 mFileSystemWatcher = nsnull;
745 sbWatchFolder::SetFolder(
const nsAString & aNewWatchPath, PRBool aSynchronizeMediaList)
749 NS_ConvertUTF16toUTF8(aNewWatchPath).
get()));
751 if (mWatchPath.Equals(aNewWatchPath, CaseInsensitiveCompare)) {
757 mWatchPath = aNewWatchPath;
758 mShouldSynchronize = aSynchronizeMediaList;
761 TRACE((
"%s: already watching, stopping...", __FUNCTION__));
762 NS_ENSURE_STATE(mFileSystemWatcher);
769 if (!mFileSystemWatcherGUID.IsEmpty()) {
772 rv = mFileSystemWatcher->DeleteSession(mFileSystemWatcherGUID);
775 NS_WARNING(
"Could not delete old session data!");
778 mFileSystemWatcherGUID.Truncate();
783 mShouldReinitWatcher = PR_TRUE;
790 mRemovedPaths.clear();
791 mChangedPaths.clear();
792 mDelayedChangedPaths.clear();
794 rv = mFileSystemWatcher->StopWatching(PR_FALSE);
795 NS_ENSURE_SUCCESS(rv, rv);
797 else if (mServiceState ==
eDisabled && !mWatchPath.IsEmpty()) {
802 TRACE((
"%s: not watching yet, arming...", __FUNCTION__));
807 NS_ENSURE_SUCCESS(rv, rv);
815 sbWatchFolder::Disable()
817 LOG((
"%s", __FUNCTION__));
825 NS_ENSURE_SUCCESS(rv, rv);
832 sbWatchFolder::Enable()
834 LOG((
"%s", __FUNCTION__));
842 NS_ENSURE_SUCCESS(rv, rv);
849 !mWatchPath.IsEmpty())
852 NS_ENSURE_SUCCESS(rv, rv);
861 NS_IMETHODIMP sbWatchFolder::GetMediaList(
sbIMediaList * *aMediaList)
863 NS_ENSURE_ARG_POINTER(aMediaList);
864 NS_IF_ADDREF(*aMediaList = mMediaList);
868 NS_IMETHODIMP sbWatchFolder::SetMediaList(
sbIMediaList * aMediaList)
872 if (mMediaList && aMediaList) {
873 PRBool same = PR_FALSE;
874 rv = mMediaList->Equals(aMediaList, &same);
875 NS_ENSURE_SUCCESS(rv, rv);
886 mMediaList = aMediaList;
895 NS_IMETHODIMP sbWatchFolder::GetPath(nsAString &
aPath)
903 NS_ENSURE_ARG_POINTER(aImporter);
906 nsCOMPtr<sbIDirectoryImportService>
importer = mCustomImporter;
908 importer = do_GetService(
909 "@songbirdnest.com/Songbird/DirectoryImportService;1", &rv);
910 NS_ENSURE_SUCCESS(rv, rv);
912 importer.forget(aImporter);
919 mCustomImporter = aImporter;
925 NS_ENSURE_ARG_POINTER(aTypeSniffer);
927 nsCOMPtr<sbIMediacoreTypeSniffer> sniffer = mTypeSniffer;
929 sniffer = do_GetService(
930 "@songbirdnest.com/Songbird/Mediacore/TypeSniffer;1", &rv);
931 NS_ENSURE_SUCCESS(rv, rv);
933 sniffer.forget(aTypeSniffer);
940 mTypeSniffer = aTypeSniffer;
946 NS_ENSURE_ARG_POINTER(aMetadataScanner);
949 nsCOMPtr<sbIFileMetadataService> scanner = mMetadataScanner;
951 scanner = do_GetService(
952 "@songbirdnest.com/Songbird/FileMetadataService;1", &rv);
953 NS_ENSURE_SUCCESS(rv, rv);
955 scanner.forget(aMetadataScanner);
962 mMetadataScanner = aMetadataScanner;
966 NS_IMETHODIMP sbWatchFolder::GetCanInteract(PRBool *aCanInteract)
968 NS_ENSURE_ARG_POINTER(aCanInteract);
969 *aCanInteract = mCanInteract;
973 NS_IMETHODIMP sbWatchFolder::SetCanInteract(PRBool aCanInteract)
975 mCanInteract = aCanInteract;
980 sbWatchFolder::GetIsSupported(PRBool *aIsSupported)
982 NS_ENSURE_ARG_POINTER(aIsSupported);
988 sbWatchFolder::GetIsRunning(PRBool *aIsRunning)
990 NS_ENSURE_ARG_POINTER(aIsRunning);
991 *aIsRunning = (mServiceState ==
eWatching);
996 sbWatchFolder::AddIgnorePath(
const nsAString & aFilePath)
998 LOG((
"sbWatchFolder::AddIgnorePath %s",
999 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1001 nsString filePath(aFilePath);
1003 sbStringMap::iterator it = mIgnorePaths.find(filePath);
1004 if (it == mIgnorePaths.end()) {
1006 mIgnorePaths[filePath] = ignorePathData_t(1, 0);
1009 ++(it->second.depth);
1015 sbWatchFolder::RemoveIgnorePath(
const nsAString & aFilePath)
1017 LOG((
"sbWatchFolder::RemoveIgnorePath %s",
1018 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1020 nsString filePath(aFilePath);
1022 sbStringMap::iterator it = mIgnorePaths.find(filePath);
1024 if (it != mIgnorePaths.end()) {
1025 it->second.depth = PR_MAX(0, it->second.depth - 1);
1026 if (it->second.depth < 1 && it->second.count < 1) {
1028 mIgnorePaths.erase(it);
1036 sbWatchFolder::AddIgnoreCount(
const nsAString & aFilePath,
1039 nsString filePath(aFilePath);
1041 sbStringMap::iterator it = mIgnorePaths.find(filePath);
1042 if (it == mIgnorePaths.end()) {
1044 ignorePathData_t newData(0, 0);
1045 it = mIgnorePaths.insert(sbStringMap::value_type(filePath, newData)).first;
1048 it->second.count +=
aCount;
1049 if (it->second.count < 1) {
1050 it->second.count = 0;
1051 if (it->second.depth < 1) {
1053 mIgnorePaths.erase(it);
1064 sbWatchFolder::OnWatcherStarted()
1069 if (!mEventPumpTimer) {
1070 mEventPumpTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
1071 NS_ENSURE_SUCCESS(rv, rv);
1074 if (!mChangeDelayTimer) {
1075 mChangeDelayTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
1076 NS_ENSURE_SUCCESS(rv, rv);
1082 LOG((
"%s: arming event pump timer [%08x]",
1083 __FUNCTION__, mEventPumpTimer.get()));
1084 rv = mEventPumpTimer->InitWithCallback(
this,
1086 nsITimer::TYPE_ONE_SHOT);
1087 NS_ENSURE_SUCCESS(rv, rv);
1089 mEventPumpTimerIsSet = PR_TRUE;
1090 mShouldProcessEvents = PR_TRUE;
1091 mHasWatcherStarted = PR_TRUE;
1093 TRACE((
"sbWatchFolder::OnWatcherStarted (path [%s])",
1094 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
1099 sbWatchFolder::OnWatcherStopped()
1101 if (mEventPumpTimer) {
1102 mEventPumpTimer->Cancel();
1104 if (mChangeDelayTimer) {
1105 mChangeDelayTimer->Cancel();
1108 mHasWatcherStarted = PR_FALSE;
1113 if (mShouldReinitWatcher) {
1115 if (!mFlushFSWatcherTimer) {
1116 mFlushFSWatcherTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
1117 NS_ENSURE_SUCCESS(rv, rv);
1120 rv = mFlushFSWatcherTimer->InitWithCallback(
this,
1122 nsITimer::TYPE_ONE_SHOT);
1123 NS_ENSURE_SUCCESS(rv, rv);
1126 TRACE((
"sbWatchFolder::OnWatcherStopped (path [%s])",
1127 NS_ConvertUTF16toUTF8(mWatchPath).
get()));
1132 sbWatchFolder::OnWatcherError(PRUint32 aErrorType,
1133 const nsAString & aDescription)
1136 switch (aErrorType) {
1138 NS_WARNING(
"WARNING: Root path is missing!");
1140 NS_ENSURE_SUCCESS(rv, rv);
1144 NS_WARNING(
"WARNING: Invalid directory!");
1149 NS_ENSURE_SUCCESS(rv, rv);
1157 sbWatchFolder::OnFileSystemChanged(
const nsAString & aFilePath)
1159 LOG((
"sbWatchFolder::OnFileSystemChanged %s",
1160 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1162 PRBool isIgnoredPath = PR_FALSE;
1164 NS_ENSURE_SUCCESS(rv, rv);
1167 if (isIgnoredPath) {
1171 nsString filePath(aFilePath);
1175 if (mHasWatcherStarted) {
1178 if (foundIter != mChangedPaths.end()) {
1181 mDelayedChangedPaths.insert(filePath);
1184 if (!mChangeDelayTimerIsSet) {
1185 rv = mChangeDelayTimer->InitWithCallback(
this,
1187 nsITimer::TYPE_ONE_SHOT);
1188 NS_ENSURE_SUCCESS(rv, rv);
1190 mChangeDelayTimerIsSet = PR_TRUE;
1194 mChangedPaths.insert(filePath);
1196 NS_ENSURE_SUCCESS(rv, rv);
1200 mChangedPaths.insert(filePath);
1207 sbWatchFolder::OnFileSystemRemoved(
const nsAString & aFilePath)
1209 LOG((
"sbWatchFolder::OnFileSystemRemoved %s",
1210 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1212 PRBool isIgnoredPath = PR_FALSE;
1214 NS_ENSURE_SUCCESS(rv, rv);
1216 if (!isIgnoredPath) {
1217 mRemovedPaths.insert(nsString(aFilePath));
1221 NS_ENSURE_SUCCESS(rv, rv);
1228 sbWatchFolder::OnFileSystemAdded(
const nsAString & aFilePath)
1230 LOG((
"sbWatchFolder::OnFileSystemAdded %s",
1231 NS_LossyConvertUTF16toASCII(aFilePath).
get()));
1233 PRBool isIgnoredPath = PR_FALSE;
1235 NS_ENSURE_SUCCESS(rv, rv);
1237 if (!isIgnoredPath) {
1238 mAddedPaths.insert(nsString(aFilePath));
1242 NS_ENSURE_SUCCESS(rv, rv);
1252 sbWatchFolder::OnEnumerationBegin(
sbIMediaList *aMediaList,
1255 if (!mEnumeratedMediaItems) {
1257 mEnumeratedMediaItems =
1258 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1259 NS_ENSURE_SUCCESS(rv, rv);
1267 sbWatchFolder::OnEnumeratedItem(
sbIMediaList *aMediaList,
1271 mEnumeratedMediaItems->AppendElement(aMediaItem, PR_FALSE);
1277 sbWatchFolder::OnEnumerationEnd(
sbIMediaList *aMediaList,
1278 nsresult aStatusCode)
1282 rv = mEnumeratedMediaItems->GetLength(&length);
1283 NS_ENSURE_SUCCESS(rv, rv);
1285 LOG((
"%s: Found %i media items during enumeration", __FUNCTION__, length));
1288 if (mCurrentProcessType ==
eRemoval) {
1290 nsCOMPtr<sbIWFRemoveHelper9001> helper =
1291 do_GetService(
"@songbirdnest.com/Songbird/RemoveHelper;1", &rv);
1292 NS_ENSURE_SUCCESS(rv, rv);
1294 mRemovedPaths.clear();
1296 helper->Remove(mEnumeratedMediaItems);
1297 NS_ENSURE_SUCCESS(rv, rv);
1299 else if (mCurrentProcessType ==
eChanged) {
1301 nsCOMPtr<sbIFileMetadataService> metadataService;
1302 rv = GetMetadataScanner(getter_AddRefs(metadataService));
1303 NS_ENSURE_SUCCESS(rv, rv);
1305 nsCOMPtr<sbIJobProgress> jobProgress;
1306 rv = metadataService->Read(mEnumeratedMediaItems,
1307 getter_AddRefs(jobProgress));
1308 NS_ENSURE_SUCCESS(rv, rv);
1313 nsCOMPtr<sbIWFMoveRenameHelper9000> helper =
1314 do_GetService(
"@songbirdnest.com/Songbird/MoveRenameHelper;1", &rv);
1315 NS_ENSURE_SUCCESS(rv, rv);
1317 nsCOMPtr<nsIArray> uriArray;
1319 NS_ENSURE_SUCCESS(rv, rv);
1320 mAddedPaths.clear();
1324 rv = uriArray->GetLength(&length);
1325 NS_ENSURE_SUCCESS(rv, rv);
1327 LOG((
"%s: Sending %i added item URL's to the move-rename helper",
1328 __FUNCTION__, length));
1331 rv = helper->Process(mEnumeratedMediaItems, uriArray,
this);
1332 NS_ENSURE_SUCCESS(rv, rv);
1344 for (next = begin; next != end; ++
next) {
1345 nsCOMPtr<nsILocalFile> curFile =
1346 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
1347 NS_ENSURE_SUCCESS(rv, rv);
1349 rv = curFile->InitWithPath(*next);
1350 if (NS_FAILED(rv)) {
1351 NS_WARNING(
"ERROR: Could not init a nsILocalFile with a path!");
1355 PRBool doesExist = PR_FALSE;
1356 rv = curFile->Exists(&doesExist);
1357 if (NS_FAILED(rv) || !doesExist) {
1358 mAddedPaths.erase(*next);
1363 NS_ENSURE_SUCCESS(rv, rv);
1366 rv = mEnumeratedMediaItems->Clear();
1367 NS_ENSURE_SUCCESS(rv, rv);
1369 mCurrentProcessType =
eNone;
1377 sbWatchFolder::Notify(nsITimer *aTimer)
1382 if (aTimer == mStartupDelayTimer) {
1383 LOG((
"%s: startup delay timer [%08x] fired",
1384 __FUNCTION__, mStartupDelayTimer.get()));
1386 NS_ENSURE_SUCCESS(rv, rv);
1390 else if (aTimer == mFlushFSWatcherTimer) {
1391 mFileSystemWatcher = nsnull;
1392 mShouldReinitWatcher = PR_FALSE;
1395 NS_ENSURE_SUCCESS(rv, rv);
1399 else if (aTimer == mEventPumpTimer) {
1400 if (mShouldProcessEvents) {
1404 NS_ENSURE_SUCCESS(rv, rv);
1406 mEventPumpTimerIsSet = PR_FALSE;
1411 LOG((
"%s: arming event pump timer [%08x]",
1412 __FUNCTION__, mEventPumpTimer.get()));
1413 rv = mEventPumpTimer->InitWithCallback(
this,
1415 nsITimer::TYPE_ONE_SHOT);
1416 NS_ENSURE_SUCCESS(rv, rv);
1418 mShouldProcessEvents = PR_TRUE;
1423 else if (aTimer == mChangeDelayTimer) {
1425 NS_ENSURE_SUCCESS(rv, rv);
1427 mChangeDelayTimerIsSet = PR_FALSE;
1439 NS_ENSURE_ARG_POINTER(aJobProgress);
1442 nsresult rv = aJobProgress->GetStatus(&status);
1443 NS_ENSURE_SUCCESS(rv, rv);
1451 NS_ENSURE_SUCCESS(rv, rv);
sbStringSet::iterator sbStringSetIter
nsresult StartWatchingFolder()
#define STARTUP_TIMER_DELAY
nsresult HandleSessionLoadError()
nsresult GetSongbirdWindow(nsIDOMWindow **aSongbirdWindow)
Generic interface for exposing long running jobs to the UI.
nsString Get(const nsAString &aKey, const nsAString &aDefault=SBVoidString())
nsString Format(const nsAString &aKey, nsTArray< nsString > &aParams, const nsAString &aDefault=SBVoidString())
NS_IMPL_ISUPPORTS5(sbWatchFolder, sbIWatchFolder, sbIFileSystemListener, sbIMediaListEnumerationListener, nsITimerCallback, sbIJobProgressListener) sbWatchFolder
const unsigned long INVALID_DIRECTORY
const unsigned short STATUS_RUNNING
Constant indicating that the job is active.
#define CHANGE_DELAY_TIMER_DELAY
NS_DECL_ISUPPORTS NS_DECL_SBIWATCHFOLDER NS_DECL_SBIFILESYSTEMLISTENER NS_DECL_SBIMEDIALISTENUMERATIONLISTENER NS_DECL_NSITIMERCALLBACK NS_DECL_SBIJOBPROGRESSLISTENER nsresult Init()
nsresult StopWatchingFolder()
nsresult ProcessEventPaths()
Handles finding media files in directories and adding them to a library or list.
nsresult GetFilePathURI(const nsAString &aFilePath, nsIURI **aURIRetVal)
nsresult GetURIArrayForStringPaths(sbStringSet &aPathsSet, nsIArray **aURIs)
#define FLUSH_FS_WATCHER_DELAY
const unsigned long ROOT_PATH_MISSING
Songbird String Bundle Definitions.
sbStringSet::iterator sbStringSetIter
#define EVENT_PUMP_TIMER_DELAY
nsresult ProcessAddedPaths()
nsresult EnumerateItemsByPaths(sbStringSet &aPathSet)
nsresult DecrementIgnoredPathCount(const nsAString &aFilePath, PRBool *aIsIgnoredPath)
std::set< nsString > sbStringSet
nsresult SetEventPumpTimer()
nsresult HandleEventPathList(sbStringSet &aEventPathSet, EProcessType aProcessType)
Implemented to receive notifications from sbIJobProgress interfaces.
nsresult HandleRootPathMissing()
restoreHistoryPrecursor aCount
attribute sbIDirectoryImportService importer
#define SB_PROPERTY_CONTENTURL
attribute sbIMediacoreTypeSniffer typeSniffer
const unsigned long SESSION_LOAD_ERROR
nsresult SetStartupDelayTimer()
std::set< nsString, IgnoringCase > sbStringSet