sbLocalDatabaseMediaItem.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://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 
28 
29 #include <nsIProgrammingLanguage.h>
30 #include <sbILibrary.h>
31 #include <sbIMediaItemController.h>
32 #include <sbILibraryUtils.h>
33 #include <sbILocalDatabasePropertyCache.h>
34 #include <sbILocalDatabaseResourcePropertyBag.h>
35 #include <sbIPropertyArray.h>
36 #include <sbIPropertyManager.h>
37 #include <sbPropertiesCID.h>
38 
39 #include <nsIClassInfoImpl.h>
40 #include <nsIObserver.h>
41 #include <nsIURIChecker.h>
42 #include <nsIFileURL.h>
43 #include <nsIStringEnumerator.h>
44 #include <nsIVariant.h>
45 #include <nsAutoLock.h>
46 #include <nsNetUtil.h>
47 #include <nsXPCOM.h>
48 #include <prprf.h>
49 #include <sbLocalDatabaseLibrary.h>
50 #include <sbStandardProperties.h>
51 #include <prtime.h>
52 
53 static void AppendInt(nsAString &str, PRInt64 val)
54 {
55  char buf[32];
56  PR_snprintf(buf, sizeof(buf), "%lld", val);
57  str.Append(NS_ConvertASCIItoUTF16(buf));
58 }
59 
62 
63 NS_INTERFACE_MAP_BEGIN(sbLocalDatabaseMediaItem)
64  NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
65  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
66  NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
67  NS_INTERFACE_MAP_ENTRY(sbILocalDatabaseMediaItem)
68  NS_INTERFACE_MAP_ENTRY(sbIMediaItem)
69  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(sbILibraryResource, sbIMediaItem)
70  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, sbIMediaItem)
71 NS_INTERFACE_MAP_END
72 
75  nsIRequestObserver,
76  sbILibraryResource,
78 
79 sbLocalDatabaseMediaItem::sbLocalDatabaseMediaItem()
80 : mMediaItemId(0),
81  mOwnsLibrary(PR_FALSE),
82  mLibrary(nsnull),
83  mSuppressNotifications(PR_TRUE),
84  mItemController(nsnull),
85  mItemControllerFetched(PR_FALSE),
86  mPropertyBagLock(nsnull)
87 {
88 }
89 
91 {
92  if(mPropertyBagLock) {
93  nsAutoLock::DestroyLock(mPropertyBagLock);
94  }
95 
96  // If we've kept an owning reference to the library, release it here
97  if (mLibrary && mOwnsLibrary) {
98  NS_RELEASE(mLibrary);
99  }
100 
101 }
102 
109 nsresult
111  const nsAString& aGuid,
112  PRBool aOwnsLibrary)
113 {
114  NS_ENSURE_ARG_POINTER(aLibrary);
115  NS_ENSURE_ARG(!aGuid.IsEmpty());
116 
117  mLibrary = aLibrary;
118  mGuid.Assign(aGuid);
119  mOwnsLibrary = aOwnsLibrary;
120 
121  // The caller has indicated that the reference we keep to the library is
122  // to be either an owning or non-owning reference. If it is an owning
123  // reference, addref it here.
124  if (aOwnsLibrary) {
125  NS_ADDREF(mLibrary);
126  }
127 
128  mPropertyBagLock =
129  nsAutoLock::NewLock("sbLocalDatabaseMediaItem::mPropertyBagLock");
130  NS_ENSURE_TRUE(mPropertyBagLock, NS_ERROR_OUT_OF_MEMORY);
131 
132  return NS_OK;
133 }
134 
138 nsresult
139 sbLocalDatabaseMediaItem::EnsurePropertyBag()
140 {
141  nsAutoLock lock(mPropertyBagLock);
142 
143  if (mPropertyBag)
144  return NS_OK;
145 
146  nsresult rv;
147 
148  // Sometimes the property bag isn't ready for us to get during construction
149  // because the cache isn't done loading. Check here to see if we need
150  // to grab it.
151 
152  //XXX: If cache is invalidated, refresh now?
153 
154  const PRUnichar* guid = mGuid.get();
155 
156  PRUint32 count;
158  {
159  nsCOMPtr<sbILocalDatabasePropertyCache> propertyCache;
160  rv = mLibrary->GetPropertyCache(getter_AddRefs(propertyCache));
161  NS_ENSURE_SUCCESS(rv, rv);
162  rv = propertyCache->GetProperties(&guid,
163  1,
164  &count,
165  &bags);
166  }
167  NS_ENSURE_SUCCESS(rv, rv);
168 
169  NS_ASSERTION(count == 1, "GetProperties returned too many bags");
170  NS_ASSERTION(bags[0], "GetProperties returned a null bag!");
171 
172  NS_ENSURE_TRUE(bags[0], NS_ERROR_NULL_POINTER);
173  mPropertyBag = bags[0];
174  NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, bags);
175 
176  return NS_OK;
177 }
178 
182 NS_IMETHODIMP
183 sbLocalDatabaseMediaItem::GetInterfaces(PRUint32* count,
184  nsIID*** array)
185 {
186  return NS_CI_INTERFACE_GETTER_NAME(sbLocalDatabaseMediaItem)(count, array);
187 }
188 
192 NS_IMETHODIMP
193 sbLocalDatabaseMediaItem::GetHelperForLanguage(PRUint32 language,
194  nsISupports** _retval)
195 {
196  *_retval = nsnull;
197  return NS_OK;
198 }
199 
203 NS_IMETHODIMP
204 sbLocalDatabaseMediaItem::GetContractID(char** aContractID)
205 {
206  *aContractID = nsnull;
207  return NS_OK;
208 }
209 
213 NS_IMETHODIMP
214 sbLocalDatabaseMediaItem::GetClassDescription(char** aClassDescription)
215 {
216  *aClassDescription = nsnull;
217  return NS_OK;
218 }
219 
223 NS_IMETHODIMP
224 sbLocalDatabaseMediaItem::GetClassID(nsCID** aClassID)
225 {
226  *aClassID = nsnull;
227  return NS_OK;
228 }
229 
233 NS_IMETHODIMP
234 sbLocalDatabaseMediaItem::GetImplementationLanguage(PRUint32* aImplementationLanguage)
235 {
236  *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
237  return NS_OK;
238 }
239 
243 NS_IMETHODIMP
244 sbLocalDatabaseMediaItem::GetFlags(PRUint32 *aFlags)
245 {
246  *aFlags = nsIClassInfo::THREADSAFE;
247  return NS_OK;
248 }
249 
253 NS_IMETHODIMP
254 sbLocalDatabaseMediaItem::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
255 {
256  return NS_ERROR_NOT_AVAILABLE;
257 }
258 
262 NS_IMETHODIMP
263 sbLocalDatabaseMediaItem::GetGuid(nsAString& aGuid)
264 {
265  aGuid = mGuid;
266  return NS_OK;
267 }
268 
272 NS_IMETHODIMP
273 sbLocalDatabaseMediaItem::GetCreated(PRInt64* aCreated)
274 {
275  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
276 
277  NS_ENSURE_ARG_POINTER(aCreated);
278 
279  nsAutoString str;
280  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CREATED), str);
281  NS_ENSURE_SUCCESS(rv, rv);
282 
283  PRInt32 convertedItems = PR_sscanf(NS_ConvertUTF16toUTF8(str).get(), "%lld",
284  aCreated);
285  NS_ENSURE_TRUE(convertedItems > 0, NS_ERROR_FAILURE);
286 
287  return NS_OK;
288 }
289 
293 NS_IMETHODIMP
294 sbLocalDatabaseMediaItem::GetUpdated(PRInt64* aUpdated)
295 {
296  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
297 
298  NS_ENSURE_ARG_POINTER(aUpdated);
299 
300  nsAutoString str;
301  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_UPDATED), str);
302  NS_ENSURE_SUCCESS(rv, rv);
303 
304  PRInt32 convertedItems = PR_sscanf(NS_ConvertUTF16toUTF8(str).get(), "%lld",
305  aUpdated);
306  NS_ENSURE_TRUE(convertedItems > 0, NS_ERROR_FAILURE);
307 
308  return NS_OK;
309 }
310 
314 NS_IMETHODIMP
315 sbLocalDatabaseMediaItem::GetUserEditable(PRBool* aUserEditable)
316 {
317  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
318 
319  NS_ENSURE_ARG_POINTER(aUserEditable);
320 
321  // Item is not editable if the item or its parent have
322  // been explicitly marked as read-only.
323 
324  nsAutoString str;
325  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ISREADONLY), str);
326  NS_ENSURE_SUCCESS(rv, rv);
327 
328  if (str.EqualsLiteral("1")) {
329  *aUserEditable = PR_FALSE;
330  } else if (mLibrary) {
331  rv = mLibrary->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ISREADONLY), str);
332  NS_ENSURE_SUCCESS(rv, rv);
333  *aUserEditable = !str.EqualsLiteral("1");
334  } else {
335  *aUserEditable = PR_TRUE;
336  }
337 
338  // If this item represents a media file and has not
339  // been explicitly marked as read-only, check
340  // that we are able to write to the file
341  if (*aUserEditable) {
342 
343  nsAutoString isList;
344  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_ISLIST), isList);
345  NS_ENSURE_SUCCESS(rv, rv);
346 
347  if (isList.IsEmpty() ||
348  isList.EqualsLiteral("0")) {
349 
350  // If not a list, assume we can write unless proven otherwise.
351  // Don't NS_ENSURE_SUCCESS, since failure == not editable.
352  *aUserEditable = PR_TRUE;
353 
354  nsRefPtr<nsIURI> uri;
355  rv = this->GetContentSrc(getter_AddRefs(uri));
356 
357  if (NS_SUCCEEDED(rv)) {
358  nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri, &rv);
359 
360  // File must be local and writable
361  if (NS_SUCCEEDED(rv)) {
362  nsCOMPtr<nsIFile> file;
363  rv = fileUrl->GetFile(getter_AddRefs(file));
364  if (NS_SUCCEEDED(rv)) {
365  PRBool exists;
366  rv = file->Exists(&exists);
367  NS_ENSURE_SUCCESS(rv, rv);
368 
369  PRBool isWritable = PR_FALSE;
370  if (exists) {
371  rv = file->IsWritable(&isWritable);
372  if (NS_FAILED(rv)) {
373  isWritable = PR_FALSE;
374  }
375  }
376  *aUserEditable = isWritable && exists;
377  }
378  }
379  }
380  }
381  }
382 
383  return NS_OK;
384 }
385 
389 NS_IMETHODIMP
390 sbLocalDatabaseMediaItem::GetPropertyIDs(nsIStringEnumerator** _retval)
391 {
392  NS_ENSURE_ARG_POINTER(_retval);
393 
394  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
395 
396  nsresult rv = EnsurePropertyBag();
397  NS_ENSURE_SUCCESS(rv, rv);
398 
399  nsAutoLock lock(mPropertyBagLock);
400 
401  rv = mPropertyBag->GetIds(_retval);
402  NS_ENSURE_SUCCESS(rv, rv);
403 
404  return NS_OK;
405 }
406 
410 NS_IMETHODIMP
411 sbLocalDatabaseMediaItem::GetProperty(const nsAString& aID,
412  nsAString& _retval)
413 {
414  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
415 
416  nsresult rv = EnsurePropertyBag();
417  NS_ENSURE_SUCCESS(rv, rv);
418 
419  nsAutoLock lock(mPropertyBagLock);
420 
421  rv = mPropertyBag->GetProperty(aID, _retval);
422  NS_ENSURE_SUCCESS(rv, rv);
423 
424  return NS_OK;
425 }
426 
430 NS_IMETHODIMP
431 sbLocalDatabaseMediaItem::SetProperty(const nsAString& aID,
432  const nsAString& aValue)
433 {
434  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
435 
436  // XXXsk Don't let the GUID property to be set. We shouldn't need this
437  // if it were a read only property, so remvoe this when bug 3099 is fixed.
438  if (aID.EqualsLiteral(SB_PROPERTY_GUID)) {
439  NS_WARNING("Attempt to set a read-only property!");
440  return NS_ERROR_INVALID_ARG;
441  }
442  if (aID.EqualsLiteral(SB_PROPERTY_TRACKTYPE)) {
443  mItemController.forget();
444  mItemControllerFetched = PR_FALSE;
445  }
446 
447  // Create a property array to hold the changed properties and their old
448  // values
449  nsresult rv;
450  nsCOMPtr<sbIMutablePropertyArray> properties =
451  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
452  NS_ENSURE_SUCCESS(rv, rv);
453 
454  rv = EnsurePropertyBag();
455  NS_ENSURE_SUCCESS(rv, rv);
456 
457  {
458  nsAutoLock lock(mPropertyBagLock);
459 
460  nsAutoString oldValue;
461  rv = mPropertyBag->GetProperty(aID, oldValue);
462  NS_ENSURE_SUCCESS(rv, rv);
463 
464  rv = properties->AppendProperty(aID, oldValue);
465  NS_ENSURE_SUCCESS(rv, rv);
466 
467  rv = mPropertyBag->SetProperty(aID, aValue);
468  NS_ENSURE_SUCCESS(rv, rv);
469  }
470 
471  if (!mSuppressNotifications) {
472  mLibrary->NotifyListenersItemUpdated(this, properties);
473  }
474 
475  return rv;
476 }
477 
481 NS_IMETHODIMP
483 {
484  NS_ENSURE_ARG_POINTER(aProperties);
485  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
486 
487  nsresult rv = EnsurePropertyBag();
488  NS_ENSURE_SUCCESS(rv, rv);
489 
490  PRUint32 propertyCount;
491  rv = aProperties->GetLength(&propertyCount);
492  NS_ENSURE_SUCCESS(rv, rv);
493 
494  for (PRUint32 i = 0; i < propertyCount; i++) {
495  nsCOMPtr<sbIProperty> property;
496  rv = aProperties->GetPropertyAt(i, getter_AddRefs(property));
497  NS_ENSURE_SUCCESS(rv, rv);
498 
499  nsString propertyID;
500  rv = property->GetId(propertyID);
501  NS_ENSURE_SUCCESS(rv, rv);
502 
503  // XXXsk Don't let the GUID property to be set. We shouldn't need this
504  // if it were a read only property, so remvoe this when bug 3099 is fixed.
505  if (propertyID.EqualsLiteral(SB_PROPERTY_GUID)) {
506  NS_WARNING("Attempt to set a read-only property!");
507  return NS_ERROR_INVALID_ARG;
508  }
509  if (propertyID.EqualsLiteral(SB_PROPERTY_TRACKTYPE)) {
510  mItemController.forget();
511  mItemControllerFetched = PR_FALSE;
512  }
513  }
514 
515  nsCOMPtr<sbIMutablePropertyArray> properties =
516  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
517  NS_ENSURE_SUCCESS(rv, rv);
518 
519  {
520  nsAutoLock lock(mPropertyBagLock);
521 
522  for (PRUint32 i = 0; i < propertyCount; i++) {
523  nsCOMPtr<sbIProperty> property;
524  rv = aProperties->GetPropertyAt(i, getter_AddRefs(property));
525  NS_ENSURE_SUCCESS(rv, rv);
526 
527  nsString propertyID;
528  rv = property->GetId(propertyID);
529  NS_ENSURE_SUCCESS(rv, rv);
530 
531  nsAutoString oldValue;
532  rv = mPropertyBag->GetProperty(propertyID, oldValue);
533  NS_ENSURE_SUCCESS(rv, rv);
534 
535  rv = properties->AppendProperty(propertyID, oldValue);
536  NS_ENSURE_SUCCESS(rv, rv);
537 
538  nsAutoString value;
539  rv = property->GetValue(value);
540  NS_ENSURE_SUCCESS(rv, rv);
541 
542  rv = mPropertyBag->SetProperty(propertyID, value);
543  NS_ENSURE_SUCCESS(rv, rv);
544  }
545  }
546 
547  if (!mSuppressNotifications) {
548  mLibrary->NotifyListenersItemUpdated(this, properties);
549  }
550 
551  return NS_OK;
552 }
553 
557 NS_IMETHODIMP
558 sbLocalDatabaseMediaItem::GetProperties(sbIPropertyArray* aProperties,
559  sbIPropertyArray** _retval)
560 {
561  NS_ENSURE_ARG_POINTER(_retval);
562 
563  NS_ASSERTION(mPropertyBagLock, "mPropertyBagLock is null");
564 
565  nsresult rv = EnsurePropertyBag();
566  NS_ENSURE_SUCCESS(rv, rv);
567 
568  nsCOMPtr<sbIMutablePropertyArray> properties =
569  do_CreateInstance(SB_MUTABLEPROPERTYARRAY_CONTRACTID, &rv);
570  NS_ENSURE_SUCCESS(rv, rv);
571 
572  nsAutoLock lock(mPropertyBagLock);
573 
574  if (aProperties) {
575  PRUint32 propertyCount;
576  rv = aProperties->GetLength(&propertyCount);
577  NS_ENSURE_SUCCESS(rv, rv);
578 
579  for (PRUint32 i = 0; i < propertyCount; i++) {
580  nsCOMPtr<sbIProperty> property;
581  rv = aProperties->GetPropertyAt(i, getter_AddRefs(property));
582  NS_ENSURE_SUCCESS(rv, rv);
583 
584  nsString id;
585  rv = property->GetId(id);
586  NS_ENSURE_SUCCESS(rv, rv);
587 
588  nsAutoString value;
589  rv = mPropertyBag->GetProperty(id, value);
590  NS_ENSURE_SUCCESS(rv, rv);
591 
592  rv = properties->AppendProperty(id, value);
593  NS_ENSURE_SUCCESS(rv, rv);
594  }
595  }
596  else {
597  nsCOMPtr<nsIStringEnumerator> ids;
598  rv = mPropertyBag->GetIds(getter_AddRefs(ids));
599  NS_ENSURE_SUCCESS(rv, rv);
600 
601  nsString id;
602  while (NS_SUCCEEDED(ids->GetNext(id))) {
603 
604  nsAutoString value;
605  rv = mPropertyBag->GetProperty(id, value);
606  NS_ENSURE_SUCCESS(rv, rv);
607 
608  if (!value.IsVoid()) {
609  rv = properties->AppendProperty(id, value);
610  NS_ENSURE_SUCCESS(rv, rv);
611  }
612  }
613  }
614 
615  NS_ADDREF(*_retval = properties);
616  return NS_OK;
617 }
618 
622 NS_IMETHODIMP
623 sbLocalDatabaseMediaItem::Equals(sbILibraryResource* aOtherLibraryResource,
624  PRBool* _retval)
625 {
626  NS_ENSURE_ARG_POINTER(_retval);
627 
628  if (!aOtherLibraryResource) {
629  *_retval = PR_FALSE;
630  return NS_OK;
631  }
632 
633  nsAutoString otherGUID;
634  nsresult rv = aOtherLibraryResource->GetGuid(otherGUID);
635  NS_ENSURE_SUCCESS(rv, rv);
636 
637  *_retval = mGuid.Equals(otherGUID);
638  return NS_OK;
639 }
640 
644 NS_IMETHODIMP
645 sbLocalDatabaseMediaItem::GetMediaItemId(PRUint32* _retval)
646 {
647  NS_ENSURE_ARG_POINTER(_retval);
648 
649  if (mMediaItemId == 0) {
650  nsresult rv = mLibrary->GetMediaItemIdForGuid(mGuid, &mMediaItemId);
651  NS_ENSURE_SUCCESS(rv, rv);
652  }
653 
654  *_retval = mMediaItemId;
655  return NS_OK;
656 }
657 
658 NS_IMETHODIMP
660 {
661  NS_ENSURE_ARG_POINTER(aPropertyBag);
662 
663  nsresult rv = EnsurePropertyBag();
664  NS_ENSURE_SUCCESS(rv, rv);
665 
666  NS_ADDREF(*aPropertyBag = mPropertyBag);
667  return NS_OK;
668 }
669 
670 NS_IMETHODIMP
671 sbLocalDatabaseMediaItem::SetPropertyBag(sbILocalDatabaseResourcePropertyBag* aPropertyBag)
672 {
673  NS_ENSURE_ARG_POINTER(aPropertyBag);
674 
675  if (mPropertyBag) {
676  NS_ERROR("Can't reset the property bag!");
677  return NS_ERROR_UNEXPECTED;
678  }
679 
680  mPropertyBag = aPropertyBag;
681  return NS_OK;
682 }
683 
684 NS_IMETHODIMP_(void)
685 sbLocalDatabaseMediaItem::SetSuppressNotifications(PRBool aSuppress)
686 {
687  mSuppressNotifications = aSuppress;
688 }
689 
693 NS_IMETHODIMP
694 sbLocalDatabaseMediaItem::GetLibrary(sbILibrary** aLibrary)
695 {
696  nsresult rv;
697  nsCOMPtr<sbILibrary> library =
698  do_QueryInterface(NS_ISUPPORTS_CAST(sbILocalDatabaseLibrary*, mLibrary), &rv);
699  NS_ENSURE_SUCCESS(rv, rv);
700 
701  NS_IF_ADDREF(*aLibrary = library);
702  return NS_OK;
703 }
704 
705 /*
706  * See sbIMediaItem
707 NS_IMETHODIMP
708 sbLocalDatabaseMediaItem::GetOriginLibrary(sbILibrary** aOriginLibrary)
709 {
710  return NS_ERROR_NOT_IMPLEMENTED;
711 }
712  */
713 
717 NS_IMETHODIMP
718 sbLocalDatabaseMediaItem::GetIsMutable(PRBool* aIsMutable)
719 {
720  *aIsMutable = PR_TRUE;
721  return NS_OK;
722 }
723 
727 NS_IMETHODIMP
728 sbLocalDatabaseMediaItem::GetItemController(sbIMediaItemController **aMediaItemController)
729 {
730  NS_ENSURE_ARG_POINTER(aMediaItemController);
731 
732  if (!mItemControllerFetched) {
733  mItemControllerFetched = PR_TRUE;
734  // Use the trackType property of the item as a contractid to find the
735  // controller service.
736  nsString trackType;
737  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_TRACKTYPE), trackType);
738  NS_ENSURE_SUCCESS(rv, rv);
739  if (!trackType.IsEmpty()) {
740  // If there is a type, construct the contractid for the controller
741  nsCString cTrackType;
742  cTrackType = NS_ConvertUTF16toUTF8(trackType);
743  ToLowerCase(cTrackType);
744  nsCString cContractID;
745  cContractID =
746  NS_LITERAL_CSTRING(SB_MEDIAITEMCONTROLLER_PARTIALCONTRACTID);
747  cContractID.Append(cTrackType);
748  // fetch the service, ignore the return value because the service
749  // might not be there.
750  mItemController = do_GetService(cContractID.get(), &rv);
751  }
752  }
753 
754  NS_IF_ADDREF(*aMediaItemController = mItemController);
755  return NS_OK;
756 }
757 
761 NS_IMETHODIMP
762 sbLocalDatabaseMediaItem::GetMediaCreated(PRInt64* aMediaCreated)
763 {
764  NS_ENSURE_ARG_POINTER(aMediaCreated);
765 
766  nsAutoString str;
767  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CREATED), str);
768  NS_ENSURE_SUCCESS(rv, rv);
769 
770  NS_ENSURE_FALSE(str.IsVoid(), NS_ERROR_UNEXPECTED);
771 
772  PRInt32 itemsConverted = PR_sscanf(NS_ConvertUTF16toUTF8(str).get(), "%lld",
773  aMediaCreated);
774  NS_ENSURE_TRUE(itemsConverted > 0, NS_ERROR_FAILURE);
775 
776  return NS_OK;
777 }
778 
782 NS_IMETHODIMP
783 sbLocalDatabaseMediaItem::SetMediaCreated(PRInt64 aMediaCreated)
784 {
785  nsAutoString str;
786  AppendInt(str, aMediaCreated);
787 
788  nsresult rv = SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CREATED), str);
789  NS_ENSURE_SUCCESS(rv, rv);
790 
791  return NS_OK;
792 }
793 
797 NS_IMETHODIMP
798 sbLocalDatabaseMediaItem::GetMediaUpdated(PRInt64* aMediaUpdated)
799 {
800  NS_ENSURE_ARG_POINTER(aMediaUpdated);
801 
802  nsAutoString str;
803  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_UPDATED), str);
804  NS_ENSURE_SUCCESS(rv, rv);
805 
806  NS_ENSURE_FALSE(str.IsVoid(), NS_ERROR_UNEXPECTED);
807 
808  PRInt32 itemsConverted = PR_sscanf(NS_ConvertUTF16toUTF8(str).get(), "%lld",
809  aMediaUpdated);
810  NS_ENSURE_TRUE(itemsConverted > 0, NS_ERROR_FAILURE);
811 
812  return NS_OK;
813 }
814 
818 NS_IMETHODIMP
819 sbLocalDatabaseMediaItem::SetMediaUpdated(PRInt64 aMediaUpdated)
820 {
821  nsAutoString str;
822  AppendInt(str, aMediaUpdated);
823 
824  nsresult rv = SetProperty(NS_LITERAL_STRING(SB_PROPERTY_UPDATED), str);
825  NS_ENSURE_SUCCESS(rv, rv);
826 
827  return NS_OK;
828 }
829 
833 NS_IMETHODIMP
834 sbLocalDatabaseMediaItem::GetContentSrc(nsIURI** aContentSrc)
835 {
836  NS_ENSURE_ARG_POINTER(aContentSrc);
837 
838  nsAutoString str;
839  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTURL), str);
840  NS_ENSURE_SUCCESS(rv, rv);
841 
842  NS_ASSERTION(!str.IsVoid(), "This should never be void!");
843 
844  rv = NS_NewURI(aContentSrc, str);
845  NS_ENSURE_SUCCESS(rv, rv);
846 
847  return NS_OK;
848 }
849 
853 NS_IMETHODIMP
854 sbLocalDatabaseMediaItem::SetContentSrc(nsIURI* aContentSrc)
855 {
856  NS_ENSURE_ARG_POINTER(aContentSrc);
857 
858  nsCAutoString cstr;
859  nsresult rv = aContentSrc->GetSpec(cstr);
860  NS_ENSURE_SUCCESS(rv, rv);
861 
862  rv = SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTURL),
863  NS_ConvertUTF8toUTF16(cstr));
864  NS_ENSURE_SUCCESS(rv, rv);
865 
866  return NS_OK;
867 }
868 
872 NS_IMETHODIMP
873 sbLocalDatabaseMediaItem::GetContentLength(PRInt64* aContentLength)
874 {
875  NS_ENSURE_ARG_POINTER(aContentLength);
876 
877  nsAutoString str;
878  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTLENGTH), str);
879  NS_ENSURE_SUCCESS(rv, rv);
880 
881  if (str.IsEmpty()) {
882  *aContentLength = 0;
883  } else {
884  PRInt32 itemsConverted = PR_sscanf(NS_ConvertUTF16toUTF8(str).get(), "%lld",
885  aContentLength);
886  NS_ENSURE_TRUE(itemsConverted > 0, NS_ERROR_FAILURE);
887  }
888  return NS_OK;
889 }
890 
894 NS_IMETHODIMP
895 sbLocalDatabaseMediaItem::SetContentLength(PRInt64 aContentLength)
896 {
897  nsAutoString str;
898  AppendInt(str, aContentLength);
899 
900  nsresult rv = SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTLENGTH), str);
901  NS_ENSURE_SUCCESS(rv, rv);
902 
903  return NS_OK;
904 }
905 
909 NS_IMETHODIMP
910 sbLocalDatabaseMediaItem::GetContentType(nsAString& aContentType)
911 {
912  nsresult rv = GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTTYPE),
913  aContentType);
914  NS_ENSURE_SUCCESS(rv, rv);
915 
916  return NS_OK;
917 }
918 
922 NS_IMETHODIMP
923 sbLocalDatabaseMediaItem::SetContentType(const nsAString& aContentType)
924 {
925  nsresult rv = SetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTTYPE),
926  aContentType);
927  NS_ENSURE_SUCCESS(rv, rv);
928 
929  return NS_OK;
930 }
931 
935 NS_IMETHODIMP
936 sbLocalDatabaseMediaItem::OpenInputStreamAsync(nsIStreamListener *aListener, nsISupports *aContext, nsIChannel** _retval)
937 {
938  nsresult rv;
939  NS_ENSURE_ARG_POINTER(_retval);
940 
941  // Get our URI
942  nsCOMPtr<nsIURI> pURI;
943  rv = this->GetContentSrc( getter_AddRefs(pURI) );
944  NS_ENSURE_SUCCESS(rv, rv);
945 
946  // Get the IO service
947  nsCOMPtr<nsIIOService> pIOService;
948  pIOService = do_GetService("@mozilla.org/network/io-service;1", &rv);
949  NS_ENSURE_SUCCESS(rv, rv);
950 
951  // Make a new channel
952  rv = pIOService->NewChannelFromURI(pURI, _retval);
953  NS_ENSURE_SUCCESS(rv, rv);
954 
955  // Set notification callbacks if possible
956  nsCOMPtr<nsIInterfaceRequestor> pIIR = do_QueryInterface( aListener );
957  if ( pIIR )
958  (*_retval)->SetNotificationCallbacks( pIIR );
959 
960  // Open the channel to read asynchronously
961  return (*_retval)->AsyncOpen( aListener, aContext );
962 }
963 
967 NS_IMETHODIMP
968 sbLocalDatabaseMediaItem::OpenInputStream(nsIInputStream** _retval)
969 {
970  nsresult rv;
971  NS_ENSURE_ARG_POINTER(_retval);
972 
973  // Get our URI
974  nsCOMPtr<nsIURI> pURI;
975  rv = this->GetContentSrc( getter_AddRefs(pURI) );
976  NS_ENSURE_SUCCESS(rv, rv);
977 
978  // Get the IO service
979  nsCOMPtr<nsIIOService> pIOService;
980  pIOService = do_GetService("@mozilla.org/network/io-service;1", &rv);
981  NS_ENSURE_SUCCESS(rv, rv);
982 
983  // Make a new channel
984  nsCOMPtr<nsIChannel> pChannel;
985  rv = pIOService->NewChannelFromURI(pURI, getter_AddRefs(pChannel));
986  NS_ENSURE_SUCCESS(rv, rv);
987 
988  return pChannel->Open(_retval);
989 }
990 
994 NS_IMETHODIMP
995 sbLocalDatabaseMediaItem::OpenOutputStream(nsIOutputStream** _retval)
996 {
997  NS_ENSURE_ARG_POINTER(_retval);
998 
999  nsCOMPtr<nsIURI> pURI;
1000  nsresult rv = GetContentSrc(getter_AddRefs(pURI));
1001  NS_ENSURE_SUCCESS(rv, rv);
1002 
1003  nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(pURI, &rv);
1004  if (NS_FAILED(rv)) {
1005  NS_NOTYETIMPLEMENTED("Don't have code for this case yet!");
1006  return NS_ERROR_NOT_IMPLEMENTED;
1007  }
1008 
1009  nsCOMPtr<nsIFile> file;
1010  rv = fileURL->GetFile(getter_AddRefs(file));
1011  NS_ENSURE_SUCCESS(rv, rv);
1012 
1013  // try to get the canonical file name
1014  PRBool exists;
1015  rv = file->Exists(&exists);
1016  NS_ENSURE_SUCCESS(rv, rv);
1017  if (exists) {
1018  nsCOMPtr<sbILibraryUtils> libUtils =
1019  do_GetService("@songbirdnest.com/Songbird/library/Manager;1", &rv);
1020  NS_ENSURE_SUCCESS(rv, rv);
1021  nsCOMPtr<nsIFile> canonicalFile;
1022  rv = libUtils->GetCanonicalPath(file,
1023  getter_AddRefs(canonicalFile));
1024  NS_ENSURE_SUCCESS(rv, rv);
1025  canonicalFile.forget(getter_AddRefs(file));
1026  }
1027 
1028  rv = NS_NewLocalFileOutputStream(_retval, file);
1029  NS_ENSURE_SUCCESS(rv, rv);
1030 
1031  return NS_OK;
1032 }
1033 
1037 NS_IMETHODIMP
1038 sbLocalDatabaseMediaItem::ToString(nsAString& _retval)
1039 {
1040  nsAutoString buff;
1041 
1042  buff.AppendLiteral("MediaItem {guid: ");
1043  buff.Append(mGuid);
1044  buff.AppendLiteral("}");
1045 
1046  _retval = buff;
1047  return NS_OK;
1048 }
1049 
1053 NS_IMETHODIMP
1054 sbLocalDatabaseMediaItem::TestIsURIAvailable(nsIObserver* aObserver)
1055 {
1056  // Create a URI Checker interface
1057  nsresult rv;
1058  nsCOMPtr<nsIURIChecker> pURIChecker = do_CreateInstance("@mozilla.org/network/urichecker;1", &rv);
1059  NS_ENSURE_SUCCESS(rv, rv);
1060 
1061  // Set it up with the URI in question
1062  nsCOMPtr<nsIURI> pURI;
1063  rv = this->GetContentSrc( getter_AddRefs(pURI) );
1064  NS_ENSURE_SUCCESS(rv, rv);
1065 
1066  rv = pURIChecker->Init( pURI );
1067  NS_ENSURE_SUCCESS(rv, rv);
1068 
1069  // Do an async check with the given observer as the context
1070  rv = pURIChecker->AsyncCheck( this, aObserver );
1071  NS_ENSURE_SUCCESS(rv, rv);
1072 
1073  return NS_OK;
1074 }
1075 
1079 NS_IMETHODIMP
1080 sbLocalDatabaseMediaItem::OnStartRequest( nsIRequest *aRequest, nsISupports *aContext )
1081 {
1082  // We don't care. It's about to check if available.
1083  return NS_OK;
1084 }
1085 
1089 NS_IMETHODIMP
1090 sbLocalDatabaseMediaItem::OnStopRequest( nsIRequest *aRequest, nsISupports *aContext, PRUint32 aStatus )
1091 {
1092  // Get the target observer
1093  nsresult rv;
1094  nsCOMPtr<nsIObserver> observer = do_QueryInterface( aContext, &rv );
1095  NS_ENSURE_SUCCESS(rv, rv);
1096 
1097  // Tell it whether we succeed or fail
1098  nsAutoString data = ( aStatus == NS_BINDING_SUCCEEDED ) ?
1099  NS_LITERAL_STRING( "true" ) : NS_LITERAL_STRING( "false" );
1100  observer->Observe( aRequest, "available", data.get() );
1101 
1102  return NS_OK;
1103 }
1104 
1106  nsIClassInfo,
1108 
1112 
1113 NS_IMETHODIMP
1114 sbLocalDatabaseIndexedMediaItem::GetIndex(PRUint32* aIndex)
1115 {
1116  *aIndex = mIndex;
1117  return NS_OK;
1118 }
1119 
1120 NS_IMETHODIMP
1121 sbLocalDatabaseIndexedMediaItem::GetMediaItem(sbIMediaItem** aMediaItem)
1122 {
1123  NS_ADDREF(*aMediaItem = mMediaItem);
1124  return NS_OK;
1125 }
1126 
1127 // nsIClassInfo
1128 NS_IMETHODIMP
1129 sbLocalDatabaseIndexedMediaItem::GetInterfaces(PRUint32* count, nsIID*** array)
1130 {
1131  return NS_CI_INTERFACE_GETTER_NAME(sbLocalDatabaseIndexedMediaItem)(count, array);
1132 }
1133 
1134 NS_IMETHODIMP
1135 sbLocalDatabaseIndexedMediaItem::GetHelperForLanguage(PRUint32 language,
1136  nsISupports** _retval)
1137 {
1138  *_retval = nsnull;
1139  return NS_OK;
1140 }
1141 
1142 NS_IMETHODIMP
1143 sbLocalDatabaseIndexedMediaItem::GetContractID(char** aContractID)
1144 {
1145  *aContractID = nsnull;
1146  return NS_OK;
1147 }
1148 
1149 NS_IMETHODIMP
1150 sbLocalDatabaseIndexedMediaItem::GetClassDescription(char** aClassDescription)
1151 {
1152  *aClassDescription = nsnull;
1153  return NS_OK;
1154 }
1155 
1156 NS_IMETHODIMP
1157 sbLocalDatabaseIndexedMediaItem::GetClassID(nsCID** aClassID)
1158 {
1159  *aClassID = nsnull;
1160  return NS_OK;
1161 }
1162 
1163 NS_IMETHODIMP
1164 sbLocalDatabaseIndexedMediaItem::GetImplementationLanguage(PRUint32* aImplementationLanguage)
1165 {
1166  *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
1167  return NS_OK;
1168 }
1169 
1170 NS_IMETHODIMP
1171 sbLocalDatabaseIndexedMediaItem::GetFlags(PRUint32 *aFlags)
1172 {
1173  *aFlags = nsIClassInfo::THREADSAFE;
1174  return NS_OK;
1175 }
1176 
1177 NS_IMETHODIMP
1178 sbLocalDatabaseIndexedMediaItem::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
1179 {
1180  return NS_ERROR_NOT_AVAILABLE;
1181 }
sbLocalDatabaseLibrary * mLibrary
NS_IMPL_THREADSAFE_ISUPPORTS2(sbLocalDatabaseIndexedMediaItem, nsIClassInfo, sbIIndexedMediaItem) NS_IMPL_CI_INTERFACE_GETTER2(sbLocalDatabaseIndexedMediaItem
const SB_MEDIAITEMCONTROLLER_PARTIALCONTRACTID
return NS_OK
nsresult Init(sbLocalDatabaseLibrary *aLibrary, const nsAString &aGuid, PRBool aOwnsLibrary=PR_TRUE)
Initializes the media item.
#define SB_PROPERTY_TRACKTYPE
menuItem id
Definition: FeedWriter.js:971
onPageChanged aValue
Definition: FeedWriter.js:1395
inArray array
readonly attribute sbILibrary library
The library that this media item is contained in.
#define SB_MUTABLEPROPERTYARRAY_CONTRACTID
nsCOMPtr< sbIMediaItemController > mItemController
[USER CODE SHOULD NOT REFERENCE THIS CLASS]
var language
Definition: Info.js:44
static nsresult ToString(const nsDiscriminatedUnion &data, nsACString &outString)
Definition: sbVariant.cpp:861
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
void NotifyListenersItemUpdated(in sbIMediaItem aItem, in sbIPropertyArray aProperties)
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
readonly attribute AString guid
The guid of this resource.
#define SB_PROPERTY_CONTENTLENGTH
var count
Definition: test_bug7406.js:32
#define SB_PROPERTY_CREATED
[USER CODE SHOULD NOT REFERENCE THIS CLASS]
#define SB_PROPERTY_UPDATED
#define SB_PROPERTY_CONTENTTYPE
const nsIChannel
General interface to data resources.
this _dialogInput val(dateText)
static nsresult GetProperty(nsIPropertyBag2 *aProperties, nsAString const &aProp, nsAString &aValue)
#define SB_PROPERTY_ISREADONLY
#define SB_PROPERTY_GUID
NS_IMETHODIMP_(nsresult) sbVariant
Definition: sbVariant.cpp:1954
A container for a media item and its index.
Media library abstraction.
Definition: sbILibrary.idl:82
[USER CODE SHOULD NOT REFERENCE THIS CLASS]
var uri
Definition: FeedWriter.js:1135
countRef value
Definition: FeedWriter.js:1423
static void AppendInt(nsAString &str, PRInt64 val)
static nsresult GetPropertyBag(sbIDevice *aDevice, nsIPropertyBag2 **aProperties)
NS_INTERFACE_MAP_END NS_IMPL_CI_INTERFACE_GETTER5(sbLocalDatabaseMediaItem, nsIClassInfo, nsISupportsWeakReference, nsIRequestObserver, sbILibraryResource, sbIMediaItem) sbLocalDatabaseMediaItem
Interface that defines a single item of media in the system.
nsresult SetProperties(nsIArray *aProperties)
NS_IMPL_CI_INTERFACE_GETTER2(sbDataRemoteWrapper, sbIDataRemote, nsIClassInfo) sbDataRemoteWrapper
#define SB_PROPERTY_ISLIST
#define SB_PROPERTY_CONTENTURL
observe data
Definition: FeedWriter.js:1329
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...
_getSelectedPageStyle s i
Interface that defines a mediaitem controller.
let observer
var file