sbLibraryUtils.cpp
Go to the documentation of this file.
1 /* vim: set sw=2 : */
2 /*
3  *=BEGIN SONGBIRD GPL
4  *
5  * This file is part of the Songbird web player.
6  *
7  * Copyright(c) 2005-2010 POTI, Inc.
8  * http://www.songbirdnest.com
9  *
10  * This file may be licensed under the terms of of the
11  * GNU General Public License Version 2 (the ``GPL'').
12  *
13  * Software distributed under the License is distributed
14  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
15  * express or implied. See the GPL for the specific language
16  * governing rights and limitations.
17  *
18  * You should have received a copy of the GPL along with this
19  * program. If not, go to http://www.gnu.org/licenses/gpl.html
20  * or write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  *=END SONGBIRD GPL
24  */
25 
26 #include "sbLibraryUtils.h"
27 
29 
30 #include <vector>
31 
32 #include <nsIFile.h>
33 #include <nsIFileURL.h>
34 #include <nsIProxyObjectManager.h>
35 #include <nsIThread.h>
36 #include <nsIURI.h>
37 
38 #include <nsArrayUtils.h>
39 #include <nsAutoPtr.h>
40 #include <nsComponentManagerUtils.h>
41 #include <nsNetUtil.h>
42 #include <nsStringAPI.h>
43 #include <nsThreadUtils.h>
44 
45 #include <sbIDevice.h>
46 #include <sbIDeviceManager.h>
47 #include <sbILibrary.h>
48 #include <sbILocalDatabaseSmartMediaList.h>
49 #include <sbIMediaList.h>
50 #include <sbIMediaItem.h>
51 #include <sbIPropertyArray.h>
52 #include <sbIPropertyInfo.h>
53 #include <sbIPropertyManager.h>
54 
55 #include <sbArrayUtils.h>
56 #include <sbFileUtils.h>
57 #include <sbPropertiesCID.h>
60 #include <sbStandardProperties.h>
61 #include <sbStringUtils.h>
62 
63 static nsresult
65  sbIPropertyArray * aProperties,
66  nsIArray * aCopies)
67 {
68  NS_ENSURE_ARG_POINTER(aList);
69  NS_ENSURE_ARG_POINTER(aProperties);
70 
71  nsresult rv;
72 
73  nsCOMPtr<sbIMediaListEnumerationListener> enumerator;
74  nsRefPtr<sbMediaListEnumSingleItemHelper> single;
75  if (aCopies) {
76  enumerator = sbMediaListEnumArrayHelper::New(aCopies);
77  }
78  else {
80  enumerator = do_QueryInterface(single);
81  }
82  NS_ENSURE_TRUE(enumerator, NS_ERROR_OUT_OF_MEMORY);
83 
84  rv = aList->EnumerateItemsByProperties(
85  aProperties,
86  enumerator,
88  NS_ENSURE_SUCCESS(rv, rv);
89 
90  // If we're not getting all the copies, just see if we found one, if not
91  // return not available error
92  if (!aCopies) {
93  nsCOMPtr<sbIMediaItem> item = single->GetItem();
94  if (!item) {
95  return NS_ERROR_NOT_AVAILABLE;
96  }
97  }
98 
99  return NS_OK;
100 }
101 
102 static nsresult
104  nsString const & aOriginLibGuid,
105  nsString const & aOriginItemGuid,
106  nsIArray * aCopies)
107 {
108  NS_ENSURE_ARG_POINTER(aList);
109 
110  nsresult rv;
111 
112  nsCOMPtr<sbIMutablePropertyArray> properties =
113  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
114  NS_ENSURE_SUCCESS(rv, rv);
115 
116  if (!aOriginLibGuid.IsEmpty()) {
117  rv = properties->AppendProperty(
118  NS_LITERAL_STRING(SB_PROPERTY_ORIGINLIBRARYGUID),
119  aOriginLibGuid);
120  NS_ENSURE_SUCCESS(rv, rv);
121  }
122 
123  rv = properties->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
124  aOriginItemGuid);
125  NS_ENSURE_SUCCESS(rv, rv);
126 
127  return FindByProperties(aList, properties, aCopies);
128 }
129 
130 static nsresult
132  nsString const & aContentURL,
133  nsIArray * aCopies)
134 {
135  NS_ENSURE_ARG_POINTER(aList);
136 
137  nsresult rv;
138 
139  nsCOMPtr<sbIMutablePropertyArray> properties =
140  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
141  NS_ENSURE_SUCCESS(rv, rv);
142 
143  rv = properties->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTURL),
144  aContentURL);
145  NS_ENSURE_SUCCESS(rv, rv);
146 
147  return FindByProperties(aList, properties, aCopies);
148 }
149 
150 static nsresult
152  nsString const & aOriginURL,
153  nsIArray * aCopies)
154 {
155  NS_ENSURE_ARG_POINTER(aList);
156 
157  nsresult rv;
158 
159  nsCOMPtr<sbIMutablePropertyArray> properties =
160  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
161  NS_ENSURE_SUCCESS(rv, rv);
162 
163  rv = properties->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINURL),
164  aOriginURL);
165  NS_ENSURE_SUCCESS(rv, rv);
166 
167  return FindByProperties(aList, properties, aCopies);
168 }
169 
170 /* static */
171 nsresult sbLibraryUtils::GetItemInLibrary(/* in */ sbIMediaItem* aMediaItem,
172  /* in */ sbILibrary* aLibrary,
173  /* out */ sbIMediaItem** aItemCopy)
174 {
175  /* this is an internal method, just assert/crash, don't be nice */
176  NS_ASSERTION(aMediaItem, "no item to look up!");
177  NS_ASSERTION(aLibrary, "no library to search in!");
178  NS_ASSERTION(aItemCopy, "null return value pointer!");
179 
180  nsresult rv;
181 
182  nsCOMPtr<nsIMutableArray> theCopies =
183  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  rv = sbLibraryUtils::FindCopiesByID(aMediaItem, aLibrary, theCopies);
187  NS_ENSURE_SUCCESS(rv, rv);
188 
189  PRUint32 count;
190  rv = theCopies->GetLength(&count);
191  NS_ENSURE_SUCCESS(rv, rv);
192 
193  // Look for originals
194  if (count == 0) {
195  rv = sbLibraryUtils::FindOriginalsByID(aMediaItem, aLibrary, theCopies);
196  NS_ENSURE_SUCCESS(rv, rv);
197  }
198 
199  rv = theCopies->GetLength(&count);
200  NS_ENSURE_SUCCESS(rv, rv);
201 
202  if (count != 0) {
203  nsCOMPtr<sbIMediaItem> item = do_QueryElementAt(theCopies, 0, &rv);
204  NS_ENSURE_SUCCESS(rv, rv);
205 
206  item.forget(aItemCopy);
207  return NS_OK;
208  }
209 
210  // give up
211  *aItemCopy = nsnull;
212  return NS_OK;
213 }
214 
215 nsresult
217  sbIMediaList * aMediaList,
218  nsIMutableArray * aCopies)
219 {
220  NS_ENSURE_ARG_POINTER(aMediaItem);
221  NS_ENSURE_ARG_POINTER(aMediaList);
222 
223  nsresult rv;
224  PRBool foundOne = PR_FALSE;
225  nsString url;
226 
227  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINURL),
228  url);
229  if (rv != NS_ERROR_NOT_AVAILABLE) {
230  NS_ENSURE_SUCCESS(rv, rv);
231  }
232 
233  if (url.IsEmpty()) {
234  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTURL),
235  url);
236  if (rv != NS_ERROR_NOT_AVAILABLE) {
237  NS_ENSURE_SUCCESS(rv, rv);
238  }
239  }
240 
241  if (!url.IsEmpty()) {
242  rv = FindByContentURL(aMediaList,
243  url,
244  aCopies);
245  if (rv != NS_ERROR_NOT_AVAILABLE) {
246  NS_ENSURE_SUCCESS(rv, rv);
247  PRUint32 length;
248  if (aCopies) {
249  rv = aCopies->GetLength(&length);
250  NS_ENSURE_SUCCESS(rv, rv);
251  foundOne = length != 0;
252  }
253  else {
254  foundOne = PR_TRUE;
255  }
256  }
257  rv = FindByOriginURL(aMediaList,
258  url,
259  aCopies);
260  if (rv != NS_ERROR_NOT_AVAILABLE) {
261  NS_ENSURE_SUCCESS(rv, rv);
262  PRUint32 length;
263  if (aCopies) {
264  rv = aCopies->GetLength(&length);
265  NS_ENSURE_SUCCESS(rv, rv);
266  foundOne |= length != 0;
267  }
268  else {
269  foundOne = PR_TRUE;
270  }
271  }
272  }
273  return (aCopies || foundOne) ? NS_OK : NS_ERROR_NOT_AVAILABLE;
274 }
275 
277  sbIMediaList * aList,
278  nsIMutableArray * aCopies)
279 {
280  NS_ENSURE_ARG_POINTER(aMediaItem);
281  NS_ENSURE_ARG_POINTER(aList);
282 
283  nsresult rv;
284 
285  nsString guid;
286  rv = aMediaItem->GetGuid(guid);
287  NS_ENSURE_SUCCESS(rv, rv);
288 
289  rv = FindByOrigin(aList, nsString(), guid, aCopies);
290  if (rv != NS_ERROR_NOT_AVAILABLE) {
291  NS_ENSURE_SUCCESS(rv, rv);
292  if (!aCopies)
293  return NS_OK;
294  }
295 
296  nsString originLibID;
297  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINLIBRARYGUID),
298  originLibID);
299  if (rv == NS_ERROR_NOT_AVAILABLE || originLibID.IsEmpty()) {
300  if (!aCopies)
301  return NS_ERROR_NOT_AVAILABLE;
302  return NS_OK;
303  }
304  NS_ENSURE_SUCCESS(rv, rv);
305 
306  nsString originItemID;
307  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
308  originItemID);
309  if (rv == NS_ERROR_NOT_AVAILABLE || originItemID.IsEmpty()) {
310  if (!aCopies)
311  return NS_ERROR_NOT_AVAILABLE;
312  return NS_OK;
313  }
314  NS_ENSURE_SUCCESS(rv, rv);
315 
316  nsCOMPtr<sbIMutablePropertyArray> properties =
317  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
318  NS_ENSURE_SUCCESS(rv, rv);
319 
320  rv = properties->AppendProperty(
321  NS_LITERAL_STRING(SB_PROPERTY_ORIGINLIBRARYGUID),
322  originLibID);
323  NS_ENSURE_SUCCESS(rv, rv);
324  rv = properties->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
325  originItemID);
326  NS_ENSURE_SUCCESS(rv, rv);
327 
328  rv = FindByProperties(aList, properties, aCopies);
329  if (rv == NS_ERROR_NOT_AVAILABLE) {
330  if (!aCopies)
331  return NS_ERROR_NOT_AVAILABLE;
332  return NS_OK;
333  }
334  NS_ENSURE_SUCCESS(rv, rv);
335 
336  return NS_OK;
337 }
338 
346  sbIMediaList * aList,
347  nsIMutableArray * aCopies)
348 {
349  NS_ENSURE_ARG_POINTER(aMediaItem);
350  NS_ENSURE_ARG_POINTER(aList);
351 
352  nsresult rv;
353 
354  nsString originID;
355  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
356  originID);
357  if (rv == NS_ERROR_NOT_AVAILABLE || originID.IsEmpty()) {
358  NS_ENSURE_SUCCESS(rv, rv);
359  if (!aCopies)
360  return NS_ERROR_NOT_AVAILABLE;
361  return NS_OK;
362  }
363 
364  nsCOMPtr<nsIArray> copies;
365  rv = aList->GetItemsByProperty(NS_LITERAL_STRING(SB_PROPERTY_GUID),
366  originID,
367  getter_AddRefs(copies));
368  NS_ENSURE_SUCCESS(rv, rv);
369 
370  PRUint32 count;
371  rv = copies->GetLength(&count);
372  NS_ENSURE_SUCCESS(rv, rv);
373 
374  if (aCopies) {
375  rv = sbAppendnsIArray(copies, aCopies);
376  NS_ENSURE_SUCCESS(rv, rv);
377  }
378  else if (count == 0) {
379  return NS_ERROR_NOT_AVAILABLE;
380  }
381  return NS_OK;
382 }
383 
384 /* static */
386  /* out */ PRInt64 * _retval)
387 {
388  NS_ENSURE_ARG_POINTER(aItem);
389 
390  PRInt64 contentLength = 0;
391  nsresult rv = aItem->GetContentLength(&contentLength);
392 
393  if(NS_FAILED(rv) || !contentLength) {
394  // try to get the length from disk
395  nsCOMPtr<sbIMediaItem> item(aItem);
396 
397  if (!NS_IsMainThread()) {
398  // Proxy item to get contentURI.
399  // Note that we do *not* call do_GetProxyForObject if we're already on
400  // the main thread - doing that causes us to process the next pending event
401  nsCOMPtr<nsIThread> target;
402  rv = NS_GetMainThread(getter_AddRefs(target));
403 
404  rv = do_GetProxyForObject(target,
405  NS_GET_IID(sbIMediaItem),
406  aItem,
407  NS_PROXY_SYNC | NS_PROXY_ALWAYS,
408  getter_AddRefs(item));
409  NS_ENSURE_SUCCESS(rv, rv);
410  }
411 
412  nsCOMPtr<nsIURI> contentURI;
413  rv = item->GetContentSrc(getter_AddRefs(contentURI));
414  NS_ENSURE_SUCCESS(rv, rv);
415 
416  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(contentURI, &rv);
417  if (NS_FAILED(rv))
418  return rv;
419  // note that this will abort if this is not a local file. This is the
420  // desired behaviour.
421 
422  nsCOMPtr<nsIFile> file;
423  rv = fileURL->GetFile(getter_AddRefs(file));
424  NS_ENSURE_SUCCESS(rv, rv);
425 
426  rv = file->GetFileSize(&contentLength);
427  NS_ENSURE_SUCCESS(rv, rv);
428 
429  rv = aItem->SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTLENGTH),
430  sbAutoString(contentLength));
431  NS_ENSURE_SUCCESS(rv, rv);
432  }
433 
434  if (_retval)
435  *_retval = contentLength;
436 
437  return NS_OK;
438 }
439 
440 /* static */
442  /* in */ nsIURI * aURI)
443 {
444  NS_ENSURE_ARG_POINTER(aItem);
445  NS_ENSURE_ARG_POINTER(aURI);
446 
447  nsresult rv;
448 
449  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
450  NS_ENSURE_SUCCESS(rv, rv);
451  // note that this will abort if this is not a local file. This is the
452  // desired behaviour.
453 
454  nsCOMPtr<nsIFile> file;
455  rv = fileURL->GetFile(getter_AddRefs(file));
456  NS_ENSURE_SUCCESS(rv, rv);
457 
458  PRInt64 length;
459  rv = file->GetFileSize(&length);
460  NS_ENSURE_SUCCESS(rv, rv);
461 
462  rv = aItem->SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTLENGTH),
463  sbAutoString(length));
464  NS_ENSURE_SUCCESS(rv, rv);
465 
466  return NS_OK;
467 }
468 
469 /* static */
471  /* out */ sbIMediaItem** _retval)
472 {
473  NS_ENSURE_ARG_POINTER(aItem);
474  NS_ENSURE_ARG_POINTER(_retval);
475 
476  nsresult rv;
477 
478  // Get the origin library and item GUIDs.
479  nsAutoString originLibraryGUID;
480  nsAutoString originItemGUID;
481  rv = aItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINLIBRARYGUID),
482  originLibraryGUID);
483  NS_ENSURE_SUCCESS(rv, rv);
484  rv = aItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
485  originItemGUID);
486  NS_ENSURE_SUCCESS(rv, rv);
487 
488  // Get the origin item.
489  nsCOMPtr<sbILibraryManager> libraryManager =
490  do_GetService("@songbirdnest.com/Songbird/library/Manager;1", &rv);
491  NS_ENSURE_SUCCESS(rv, rv);
492  nsCOMPtr<sbILibrary> library;
493  rv = libraryManager->GetLibrary(originLibraryGUID, getter_AddRefs(library));
494  NS_ENSURE_SUCCESS(rv, rv);
495  rv = library->GetItemByGuid(originItemGUID, _retval);
496  NS_ENSURE_SUCCESS(rv, rv);
497 
498  return NS_OK;
499 }
500 
501 inline
502 nsCOMPtr<nsIIOService> GetIOService(nsresult & rv)
503 {
504  // Get the IO service.
505  if (NS_IsMainThread()) {
506  return do_GetIOService(&rv);
507  }
508  return do_ProxiedGetService(NS_IOSERVICE_CONTRACTID, &rv);
509 }
510 
511 /* static */
512 nsresult sbLibraryUtils::GetContentURI(nsIURI* aURI,
513  nsIURI** _retval,
514  nsIIOService * aIOService)
515 {
516  NS_ENSURE_ARG_POINTER(aURI);
517  NS_ENSURE_ARG_POINTER(_retval);
518 
519  nsresult rv;
520  nsCOMPtr<nsIURI> uri = aURI;
521 
522  // Applies only to Windows and Mac
523  PRBool compatible = PR_TRUE;
524 #if XP_UNIX && !XP_MACOSX
525  compatible = PR_FALSE;
526 #endif
527 
528  PRBool isFileScheme;
529  rv = uri->SchemeIs("file", &isFileScheme);
530  NS_ENSURE_SUCCESS(rv, rv);
531 
532  if (isFileScheme && compatible) {
533  nsCOMPtr<nsIIOService> ioService;
534  if (aIOService) {
535  ioService = aIOService;
536  } else {
537  ioService = GetIOService(rv);
538  NS_ENSURE_SUCCESS(rv, rv);
539  }
540 
541  nsCAutoString spec;
542 
543  #ifdef XP_WIN
544  // On Windows, convert "file:" URI's to lower-case.
545  rv = uri->GetSpec(spec);
546  NS_ENSURE_SUCCESS(rv, rv);
547 
548  ToLowerCase(spec);
549  #elif XP_MACOSX
550 
563  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri, &rv);
564  NS_ENSURE_SUCCESS(rv, rv);
565 
566  nsCOMPtr<nsIFile> file;
567  rv = fileURL->GetFile(getter_AddRefs(file));
568  NS_ENSURE_SUCCESS(rv, rv);
569 
570  nsCOMPtr<nsIProtocolHandler> protocolHandler;
571  rv = ioService->GetProtocolHandler("file",
572  getter_AddRefs(protocolHandler));
573  NS_ENSURE_SUCCESS(rv, rv);
574 
575  nsCOMPtr<nsIFileProtocolHandler> fileProtocolHandler =
576  do_QueryInterface(protocolHandler, &rv);
577  NS_ENSURE_SUCCESS(rv, rv);
578 
579  rv = fileProtocolHandler->GetURLSpecFromActualFile(file, spec);
580  NS_ENSURE_SUCCESS(rv, rv);
581  #endif
582 
583  rv = ioService->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
584  NS_ENSURE_SUCCESS(rv, rv);
585  }
586 
587  // Return results.
588  NS_ADDREF(*_retval = uri);
589 
590  return NS_OK;
591 }
592 
593 /* static */
595  PRUint16 *aListContentType)
596 {
597  NS_ENSURE_ARG_POINTER(aMediaList);
598  NS_ENSURE_ARG_POINTER(aListContentType);
599 
600  nsresult rv;
601 
602  *aListContentType = sbIMediaList::CONTENTTYPE_NONE;
603 
604  nsCOMPtr<sbILocalDatabaseSmartMediaList> smartList =
605  do_QueryInterface(aMediaList, &rv);
606  if (NS_FAILED(rv))
607  rv = aMediaList->GetListContentType(aListContentType);
608  else
609  rv = smartList->GetListContentType(aListContentType);
610 
611  NS_ENSURE_SUCCESS(rv, rv);
612 
613  return NS_OK;
614 }
615 
616 /* static */
617 nsresult sbLibraryUtils::GetFileContentURI(nsIFile* aFile,
618  nsIURI** _retval)
619 {
620  NS_ENSURE_ARG_POINTER(aFile);
621  NS_ENSURE_ARG_POINTER(_retval);
622 
623  nsCOMPtr<nsIURI> uri;
624  nsresult rv;
625 
626  // Get the file URI.
627  rv = sbNewFileURI(aFile, getter_AddRefs(uri));
628  NS_ENSURE_SUCCESS(rv, rv);
629 
630  #ifdef XP_WIN
631  // Convert URI to a lowercase content URI.
632  rv = GetContentURI(uri, _retval);
633  NS_ENSURE_SUCCESS(rv, rv);
634  #else
635  NS_ADDREF(*_retval = uri);
636  #endif
637 
638  return NS_OK;
639 }
640 
645 {
646 public:
647  MediaItemArrayCreator(nsCOMArray<sbIMediaItem> & aMediaItems) :
648  mMediaItems(aMediaItems)
649  {}
651  NS_DECL_SBIMEDIALISTENUMERATIONLISTENER
652 private:
653  nsCOMArray<sbIMediaItem> & mMediaItems;
654 };
655 
658 
659 NS_IMETHODIMP MediaItemArrayCreator::OnEnumerationBegin(sbIMediaList*,
660  PRUint16 *_retval)
661 {
662  NS_ENSURE_ARG_POINTER(_retval);
664  return NS_OK;
665 }
666 
667 NS_IMETHODIMP MediaItemArrayCreator::OnEnumeratedItem(sbIMediaList*,
668  sbIMediaItem* aItem,
669  PRUint16 *_retval)
670 {
671  NS_ENSURE_ARG_POINTER(aItem);
672  NS_ENSURE_ARG_POINTER(_retval);
673 
674  PRBool const added = mMediaItems.AppendObject(aItem);
675  NS_ENSURE_TRUE(added, NS_ERROR_OUT_OF_MEMORY);
676 
678 
679  return NS_OK;
680 }
681 
682 NS_IMETHODIMP MediaItemArrayCreator::OnEnumerationEnd(sbIMediaList*,
683  nsresult)
684 {
685  return NS_OK;
686 }
687 
688 
689 nsresult
691  nsAString const & aPropertyName,
692  nsAString const & aValue,
693  nsCOMArray<sbIMediaItem> & aMediaItems) {
694  nsRefPtr<MediaItemArrayCreator> creator = new MediaItemArrayCreator(aMediaItems);
695  return aMediaList->EnumerateItemsByProperty(aPropertyName,
696  aValue,
697  creator,
699 }
700 
705 {
706 public:
707  sbLUMediaListEnumerator(PRUint32 aContentType)
708  : mContentType(aContentType)
709  {}
711  NS_DECL_SBIMEDIALISTENUMERATIONLISTENER
712 
713  nsresult GetMediaLists(nsIArray ** aMediaLists)
714  {
715  return CallQueryInterface(mMediaLists, aMediaLists);
716  }
717 private:
718  nsCOMPtr<nsIMutableArray> mMediaLists;
719  PRUint32 mContentType;
720 };
721 
724 
725 NS_IMETHODIMP sbLUMediaListEnumerator::OnEnumerationBegin(sbIMediaList*,
726  PRUint16 *_retval)
727 {
728  NS_ENSURE_ARG_POINTER(_retval);
729  nsresult rv;
730 
731  mMediaLists = do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
732  NS_ENSURE_SUCCESS(rv, rv);
733 
735  return NS_OK;
736 }
737 
738 NS_IMETHODIMP sbLUMediaListEnumerator::OnEnumeratedItem(sbIMediaList*,
739  sbIMediaItem* aItem,
740  PRUint16 *_retval)
741 {
742  NS_ENSURE_ARG_POINTER(aItem);
743  NS_ENSURE_ARG_POINTER(_retval);
744  NS_ENSURE_TRUE(mMediaLists, NS_ERROR_NOT_INITIALIZED);
745 
746  nsresult rv;
747 
748  nsCOMPtr<sbIMediaList> list = do_QueryInterface(aItem);
749  if (list) {
750  bool include = mContentType == sbIMediaList::CONTENTTYPE_MIX;
751  if (!include) {
752  PRUint16 contentType;
753  rv = list->GetListContentType(&contentType);
754  NS_ENSURE_SUCCESS(rv, rv);
755 
756  include = (contentType & mContentType) != 0;
757  }
758  if (include) {
759  rv = mMediaLists->AppendElement(list, PR_FALSE);
760  NS_ENSURE_SUCCESS(rv, rv);
761  }
762 
763  }
765 
766  return NS_OK;
767 }
768 
769 NS_IMETHODIMP sbLUMediaListEnumerator::OnEnumerationEnd(sbIMediaList*,
770  nsresult)
771 {
772  return NS_OK;
773 }
774 
776  PRUint32 aContentType,
777  nsIArray ** aMediaLists)
778 {
779  NS_ENSURE_ARG_POINTER(aLibrary);
780  NS_ENSURE_ARG_POINTER(aMediaLists);
781 
782  nsresult rv;
783  nsString propIsList(NS_LITERAL_STRING(SB_PROPERTY_ISLIST));
784  nsString propIsHidden(NS_LITERAL_STRING(SB_PROPERTY_HIDDEN));
785  nsString propTrue(NS_LITERAL_STRING("1"));
786  nsString propFalse(NS_LITERAL_STRING("0"));
787  PRUint16 enumType = sbIMediaList::ENUMERATIONTYPE_SNAPSHOT;
788 
789  nsRefPtr<sbLUMediaListEnumerator> enumerator =
790  new sbLUMediaListEnumerator(aContentType);
791 
792  nsCOMPtr<sbIMutablePropertyArray> properties =
793  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
794  NS_ENSURE_SUCCESS(rv, rv);
795 
796  rv = properties->AppendProperty(propIsList, propTrue);
797  NS_ENSURE_SUCCESS(rv, rv);
798  rv = properties->AppendProperty(propIsHidden, propFalse);
799  NS_ENSURE_SUCCESS(rv, rv);
800 
801  rv = aLibrary->EnumerateItemsByProperties(properties, enumerator, enumType);
802  NS_ENSURE_SUCCESS(rv, rv);
803 
804  rv = enumerator->GetMediaLists(aMediaLists);
805  NS_ENSURE_SUCCESS(rv, rv);
806 
807  return NS_OK;
808 }
809 
813 nsresult
815 {
816  nsresult rv;
817 
818  nsCOMPtr<sbIPropertyManager> manager =
819  do_GetService("@songbirdnest.com/Songbird/Properties/PropertyManager;1",
820  &rv);
821  nsCOMPtr<sbIPropertyInfo> info;
822  rv = manager->GetPropertyInfo(NS_LITERAL_STRING(SB_PROPERTY_CONTENTTYPE),
823  getter_AddRefs(info));
824  NS_ENSURE_SUCCESS(rv, rv);
825 
826  nsString opName;
827  rv = info->GetOPERATOR_EQUALS(opName);
828  NS_ENSURE_SUCCESS(rv, rv);
829 
830  // Get the operator.
831  rv = info->GetOperator(opName, aOperator);
832  NS_ENSURE_SUCCESS(rv, rv);
833 
834  return NS_OK;
835 }
836 
840 nsresult
842  nsAString const & aListName,
843  nsAString & aName)
844 {
845  nsresult rv;
846 
847  aName = aListName;
848  nsCOMPtr<nsIArray> mediaLists;
849  rv = aLibrary->GetItemsByProperty(NS_LITERAL_STRING(SB_PROPERTY_ISLIST),
850  NS_LITERAL_STRING("1"),
851  getter_AddRefs(mediaLists));
852  if (rv != NS_ERROR_NOT_AVAILABLE) {
853  NS_ENSURE_SUCCESS(rv, rv);
854  }
855 
856  PRUint32 listLength;
857  rv = mediaLists->GetLength(&listLength);
858  NS_ENSURE_SUCCESS(rv, rv);
859 
860  PRUint32 nameLength = aListName.Length();
861  nsTArray<PRUint64> listIDs;
862  nsString listName;
863  PRUint64 availableId = 1;
864  for (PRUint32 i = 0; i < listLength; ++i) {
865  nsCOMPtr<sbIMediaList> mediaList = do_QueryElementAt(mediaLists, i, &rv);
866  NS_ENSURE_SUCCESS(rv, rv);
867 
868  rv = mediaList->GetName(listName);
869  NS_ENSURE_SUCCESS(rv, rv);
870 
871  if (!listName.IsEmpty()) {
872  nsDependentSubstring subString(listName, 0, nameLength);
873  if (subString.Equals(aListName)) {
874  PRUint32 listNameLength = listName.Length();
875  if (listNameLength == nameLength) {
876  listIDs.AppendElement(1);
877  }
878  else {
879  nsDependentSubstring idString(listName,
880  nameLength + 1,
881  listNameLength);
882  PRUint64 id = nsString_ToUint64(idString, &rv);
883  if (rv == NS_ERROR_INVALID_ARG)
884  continue;
885  listIDs.AppendElement(id);
886  }
887  }
888  }
889  }
890 
891  while (1) {
892  if (!listIDs.Contains(availableId))
893  break;
894 
895  ++availableId;
896  }
897 
898  if (availableId > 1) {
899  aName.Append(NS_LITERAL_STRING(" "));
900  AppendInt(aName, availableId);
901  }
902 
903  return NS_OK;
904 }
905 
906 nsresult
908 {
909  NS_ENSURE_ARG_POINTER(aOriginal);
910  NS_ENSURE_ARG_POINTER(aCopy);
911 
912  nsresult rv;
913 
914  nsCOMPtr<sbILibrary> originalLibrary;
915  rv = aOriginal->GetLibrary(getter_AddRefs(originalLibrary));
916  NS_ENSURE_SUCCESS(rv, rv);
917 
918  nsCOMPtr<sbILibrary> newLibrary;
919  rv = aCopy->GetLibrary(getter_AddRefs(newLibrary));
920  NS_ENSURE_SUCCESS(rv, rv);
921 
922  const PRBool originalIsMain = sbIsMainLibrary(originalLibrary);
923  const PRBool copyIsMain = sbIsMainLibrary(newLibrary);
924 
925  // If we're copying from the main library or between two non-main libraries
926  // set the link up normally. DL is device library or other non-main library.
927  // ML to ML = No Link
928  // ML to DL = Normal Link
929  // DL to ML = Reverse Link
930  // DL TO DL = No Link (Even if different libraries). origin guid from source
931  // will be copied to the copy.
932  if (!originalIsMain && copyIsMain) {
933  // Copying from a non-main library to main library create a reverse link
934  // swap the original and copy
935  sbIMediaItem * temp = aCopy;
936  aCopy = aOriginal;
937  aOriginal = temp;
938  }
939  else if ((!originalIsMain && !copyIsMain) ||
940  (originalIsMain && copyIsMain)) {
941  return NS_OK;
942  }
943 
944  nsCOMPtr<sbIMutablePropertyArray> props =
945  do_CreateInstance(
946  "@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1",
947  &rv);
948  NS_ENSURE_SUCCESS(rv, rv);
949 
950  nsString originalGuid;
951  rv = aOriginal->GetGuid(originalGuid);
952  NS_ENSURE_SUCCESS(rv, rv);
953 
954  rv = props->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINITEMGUID),
955  originalGuid);
956  NS_ENSURE_SUCCESS(rv, rv);
957 
958  nsCOMPtr<sbILibrary> originalLib;
959  rv = aOriginal->GetLibrary(getter_AddRefs(originalLib));
960  NS_ENSURE_SUCCESS(rv, rv);
961 
962  nsString originalLibGuid;
963  rv = originalLib->GetGuid(originalLibGuid);
964  NS_ENSURE_SUCCESS(rv, rv);
965 
966  rv = props->AppendProperty(NS_LITERAL_STRING(SB_PROPERTY_ORIGINLIBRARYGUID),
967  originalLibGuid);
968  NS_ENSURE_SUCCESS(rv, rv);
969 
970  // Determine whether the target item belongs to a device:
971  nsCOMPtr<sbIDeviceManager2> deviceMgr =
972  do_GetService("@songbirdnest.com/Songbird/DeviceManager;2", &rv);
973  NS_ENSURE_SUCCESS(rv, rv);
974 
975  nsCOMPtr<sbIDevice> targetDev;
976  rv = deviceMgr->GetDeviceForItem(aCopy, getter_AddRefs(targetDev));
977  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "GetDeviceForItem() failed");
978 
979  // Set SB_PROPERTY_ORIGIN_IS_IN_MAIN_LIBRARY on the target
980  // item if it belongs to a device and the original item is
981  // in the main library:
982  if (targetDev) {
983  // Get the main library:
984  nsCOMPtr<sbILibrary> mainLib;
985  rv = GetMainLibrary(getter_AddRefs(mainLib));
986  NS_ENSURE_SUCCESS(rv, rv);
987 
988  PRBool isMainLib;
989  rv = originalLib->Equals(mainLib, &isMainLib);
990  NS_ENSURE_SUCCESS(rv, rv);
991  if (isMainLib) {
992  rv = props->AppendProperty(
993  NS_LITERAL_STRING(SB_PROPERTY_ORIGIN_IS_IN_MAIN_LIBRARY),
994  NS_LITERAL_STRING("1"));
995  NS_ENSURE_SUCCESS(rv, rv);
996  }
997  }
998 
999  rv = aCopy->SetProperties(props);
1000  NS_ENSURE_SUCCESS(rv, rv);
1001 
1002  return NS_OK;
1003 }
1004 
nsCOMPtr< nsIIOService > GetIOService(nsresult &rv)
static nsresult GetItemsByProperty(sbIMediaList *aMediaList, nsAString const &aPropertyName, nsAString const &aValue, nsCOMArray< sbIMediaItem > &aMediaItems)
return NS_OK
static nsresult LinkCopy(sbIMediaItem *aOriginal, sbIMediaItem *aCopy)
Links a copy to its original. It will take into account the libraries the items belong to...
static nsresult GetContentLength(sbIMediaItem *aItem, PRInt64 *_retval=nsnull)
static nsresult FindByProperties(sbIMediaList *aList, sbIPropertyArray *aProperties, nsIArray *aCopies)
#define SB_PROPERTY_ORIGINLIBRARYGUID
static nsresult GetItemInLibrary(sbIMediaItem *aItem, sbILibrary *aLibrary, sbIMediaItem **_retval)
static sbMediaListEnumSingleItemHelper * New()
#define SB_PROPERTY_ORIGINURL
Interface used to enumerate the items in a media list.
onPageChanged aValue
Definition: FeedWriter.js:1395
PRUint64 nsString_ToUint64(const nsAString &str, nsresult *rv)
static nsresult GetMediaListByContentType(sbILibrary *aLibrary, PRUint32 aContentType, nsIArray **aMediaLists)
static nsresult GetFileContentURI(nsIFile *aFile, nsIURI **_retval)
Return a library content URI for the file specified by aFile. Special processing is required to conve...
nsresult sbAppendnsIArray(nsIArray *aSrc, nsIMutableArray *aDest, PRBool aWeak=PR_FALSE, PRUint32 aElementsToCopy=0)
Definition: sbArrayUtils.h:87
static nsresult FindByOrigin(sbIMediaList *aList, nsString const &aOriginLibGuid, nsString const &aOriginItemGuid, nsIArray *aCopies)
static nsresult FindCopiesByID(sbIMediaItem *aMediaItem, sbIMediaList *aList, nsIMutableArray *aCopies)
#define SB_PROPERTY_HIDDEN
static nsresult SetContentLength(sbIMediaItem *aItem, nsIURI *aURI)
#define SB_MUTABLEPROPERTYARRAY_CONTRACTID
static nsresult GetOriginItem(sbIMediaItem *aItem, sbIMediaItem **_retval)
nsresult do_GetProxyForObject(nsIEventTarget *aTarget, REFNSIID aIID, nsISupports *aObj, PRInt32 aProxyType, void **aProxyObject)
MediaItemArrayCreator(nsCOMArray< sbIMediaItem > &aMediaItems)
static nsresult GetContentURI(nsIURI *aURI, nsIURI **_retval, nsIIOService *aIOService=nsnull)
Return a library content URI for the URI specified by aURI. A library content URI is a specially form...
var ioService
A brief description of the contents of this interface.
#define SB_PROPERTY_CONTENTLENGTH
var count
Definition: test_bug7406.js:32
const sbCreateProxiedComponent do_ProxiedGetService(const nsCID &aCID, nsresult *error=0)
An interface to represent an operator that may act upon a property.
#define SB_PROPERTY_CONTENTTYPE
BogusChannel prototype contentLength
const unsigned short ENUMERATIONTYPE_SNAPSHOT
This flag means that the list being enumerated is a copy that may become out of date.
const unsigned short CONTENTTYPE_MIX
var libraryManager
sbLUMediaListEnumerator(PRUint32 aContentType)
#define SB_PROPERTY_GUID
PRBool sbIsMainLibrary(sbILibrary *aLibrary)
static nsresult SuggestUniqueNameForPlaylist(sbILibrary *aLibrary, nsAString const &aListName, nsAString &aName)
Suggest a unique name for playlist.
const unsigned short CONTENTTYPE_NONE
These flags specify the contentType of the media list.
static nsresult GetMediaListContentType(sbIMediaList *aMediaList, PRUint16 *aListContentType)
Return a media list content type.
#define SB_PROPERTY_ORIGIN_IS_IN_MAIN_LIBRARY
Media library abstraction.
Definition: sbILibrary.idl:82
static nsresult FindOriginalsByID(sbIMediaItem *aMediaItem, sbIMediaList *aList, nsIMutableArray *aCopies)
NS_IMPL_ISUPPORTS1(MediaItemArrayCreator, sbIMediaListEnumerationListener) NS_IMETHODIMP MediaItemArrayCreator
static nsresult FindItemsWithSameURL(sbIMediaItem *aMediaItem, sbIMediaList *aMediaList, nsIMutableArray *aCopies)
static nsresult FindByContentURL(sbIMediaList *aList, nsString const &aContentURL, nsIArray *aCopies)
_updateCookies aName
NS_DECL_ISUPPORTS static NS_DECL_SBIMEDIALISTENUMERATIONLISTENER sbMediaListEnumArrayHelper * New(nsIArray *aArray=nsnull)
Creates a enum array helper and initializes it.
var uri
Definition: FeedWriter.js:1135
function url(spec)
static void AppendInt(nsAString &str, PRInt64 val)
nsresult GetMainLibrary(sbILibrary **aMainLibrary)
Interface that defines a single item of media in the system.
#define SB_PROPERTY_ISLIST
static PRUint32 GetEqualOperator(sbIPropertyOperator **aOperator)
NS_DECL_ISUPPORTS NS_DECL_SBIMEDIALISTENUMERATIONLISTENER nsresult GetMediaLists(nsIArray **aMediaLists)
#define SB_PROPERTY_CONTENTURL
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...
nsresult sbNewFileURI(nsIFile *aFile, nsIURI **aURI)
#define SB_PROPERTY_ORIGINITEMGUID
_getSelectedPageStyle s i
var file
static nsresult FindByOriginURL(sbIMediaList *aList, nsString const &aOriginURL, nsIArray *aCopies)