DeviceBase.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 
32 #include "DeviceBase.h"
33 #include "sbIDeviceBase.h"
34 
35 #include <nsAppDirectoryServiceDefs.h>
36 #include <nsAutoLock.h>
37 #include <nsAutoPtr.h>
38 #include <nsCOMArray.h>
39 #include <nsCRTGlue.h>
40 #include <nsComponentManagerUtils.h>
41 #include <nsDirectoryServiceUtils.h>
42 #include <nsIFileURL.h>
43 #include <nsIIOService.h>
44 #include <nsILocalFile.h>
45 #include <nsIProxyObjectManager.h>
46 #include <nsIURI.h>
47 #include <nsIURIFixup.h>
48 #include <nsIWritablePropertyBag2.h>
49 #include <nsMemory.h>
50 #include <nsProxyRelease.h>
51 #include <nsServiceManagerUtils.h>
52 #include <nsStringGlue.h>
53 #include <nsThreadUtils.h>
54 #include <nsUnicharUtils.h>
55 #include <nsXPCOM.h>
56 
57 #include <sbILibraryFactory.h>
58 #include <sbILibraryManager.h>
59 #include <sbIPropertyArray.h>
60 #include <sbLocalDatabaseCID.h>
61 #include <sbStandardProperties.h>
62 
63 #define MSG_DEVICE_BASE (0x2000) // Base message ID
64 
65 #define MSG_DEVICE_TRANSFER (MSG_DEVICE_BASE + 0)
66 #define MSG_DEVICE_UPLOAD (MSG_DEVICE_BASE + 1)
67 #define MSG_DEVICE_DELETE (MSG_DEVICE_BASE + 2)
68 #define MSG_DEVICE_UPDATE_METADATA (MSG_DEVICE_BASE + 3)
69 #define MSG_DEVICE_EVENT (MSG_DEVICE_BASE + 4)
70 #define MSG_DEVICE_INITIALIZE (MSG_DEVICE_BASE + 5)
71 #define MSG_DEVICE_FINALIZE (MSG_DEVICE_BASE + 6)
72 #define MSG_DEVICE_EJECT (MSG_DEVICE_BASE + 7)
73 
74 #define TRANSFER_TABLE_NAME NS_LITERAL_STRING("Transfer")
75 #define URL_COLUMN_NAME NS_LITERAL_STRING("url")
76 #define SOURCE_COLUMN_NAME NS_LITERAL_STRING("source")
77 #define DESTINATION_COLUMN_NAME NS_LITERAL_STRING("destination")
78 #define INDEX_COLUMN_NAME NS_LITERAL_STRING("id")
79 
80 /*
81  * To log this module, set the following environment variable:
82  * NSPR_LOG_MODULES=sbDeviceBase:5
83  */
84 #ifdef PR_LOGGING
85 static PRLogModuleInfo *gUSBMassStorageDeviceLog = nsnull;
86 #define TRACE(args) if (gUSBMassStorageDeviceLog) PR_LOG(gUSBMassStorageDeviceLog, PR_LOG_DEBUG, args)
87 #define LOG(args) if (gUSBMassStorageDeviceLog) PR_LOG(gUSBMassStorageDeviceLog, PR_LOG_WARN, args)
88 #else
89 #define TRACE(args) /* nothing */
90 #define LOG(args) /* nothing */
91 #endif
92 
93 //Utility functions.
94 void
95 ReplaceChars(nsAString& aOldString,
96  const nsAString& aOldChars,
97  const PRUnichar aNewChar)
98 {
99  PRUint32 length = aOldString.Length();
100  for (PRUint32 index = 0; index < length; index++) {
101  PRUnichar currentChar = aOldString.CharAt(index);
102  PRInt32 oldCharsIndex = aOldChars.FindChar(currentChar);
103  if (oldCharsIndex > -1)
104  aOldString.Replace(index, 1, aNewChar);
105  }
106 }
107 
108 void
109 ReplaceChars(nsACString& aOldString,
110  const nsACString& aOldChars,
111  const char aNewChar)
112 {
113  PRUint32 length = aOldString.Length();
114  for (PRUint32 index = 0; index < length; index++) {
115  char currentChar = aOldString.CharAt(index);
116  PRInt32 oldCharsIndex = aOldChars.FindChar(currentChar);
117  if (oldCharsIndex > -1)
118  aOldString.Replace(index, 1, aNewChar);
119  }
120 }
121 
122 //sbDeviceBaseLibraryListener class.
125 
126 /* static */ PLDHashOperator PR_CALLBACK
127 sbDeviceBaseLibraryListener::ShiftIndexesCallback(nsISupportsHashKey::KeyType aKey,
128  PRUint32& aEntry,
129  void* aUserData)
130 {
131  NS_ASSERTION(aUserData, "Null userData!");
132 
133  PRUint32* index = static_cast<PRUint32*>(aUserData);
134  NS_ENSURE_TRUE(index, PL_DHASH_STOP);
135 
136  if (aEntry > *index) {
137  aEntry--;
138  }
139 
140  return PL_DHASH_NEXT;
141 }
142 
144 : mDevice(nsnull),
145  mIgnoreListener(PR_FALSE),
146  mManagePlaylists(PR_FALSE)
147 {
148 }
149 
151 {
152 }
153 
154 nsresult
155 sbDeviceBaseLibraryListener::Init(const nsAString &aDeviceIdentifier,
156  sbIDeviceBase* aDevice)
157 {
158  NS_ENSURE_ARG_POINTER(aDevice);
159 
160  mDeviceIdentifier = aDeviceIdentifier;
161  mDevice = aDevice;
162  PRBool success = mBeforeRemoveIndexes.Init();
163  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
164 
165  return NS_OK;
166 }
167 
168 nsresult
170 {
171  mIgnoreListener = aIgnoreListener;
172  return NS_OK;
173 }
174 
175 nsresult
177 {
178  mManagePlaylists = aManagePlaylists;
179  return NS_OK;
180 }
181 
182 NS_IMETHODIMP
183 sbDeviceBaseLibraryListener::OnItemAdded(sbIMediaList *aMediaList,
184  sbIMediaItem *aMediaItem,
185  PRUint32 aIndex,
186  PRBool *aNoMoreForBatch)
187 {
188  NS_ENSURE_ARG_POINTER(aMediaList);
189  NS_ENSURE_ARG_POINTER(aMediaItem);
190  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
191 
192  *aNoMoreForBatch = PR_FALSE;
193 
194  nsresult rv;
195 
196  //XXXAus: Before adding to queue, make sure it doesn't come from
197  //another device. Ask DeviceManager for the device library
198  //containing this item.
199 
200  nsCOMPtr<sbILibrary> library;
201  rv = aMediaList->GetLibrary(getter_AddRefs(library));
202  NS_ENSURE_SUCCESS(rv, rv);
203 
204  PRBool destinationIsLibrary;
205  rv = aMediaList->Equals(library, &destinationIsLibrary);
206  NS_ENSURE_SUCCESS(rv, rv);
207 
208  nsCOMPtr<sbIMediaList> list = do_QueryInterface(aMediaItem, &rv);
209  PRBool addedIsList = NS_SUCCEEDED(rv);
210 
211  // If we're managing playlists and a list is being added to the library, we
212  // need to attach a listener so we can track changes to the list
213  if (mManagePlaylists && destinationIsLibrary && addedIsList) {
214  rv = list->AddListener(this,
215  PR_FALSE,
222  nsnull);
223  NS_ENSURE_SUCCESS(rv, rv);
224 
225  nsAutoPtr<sbRemovedItemIndexes> removedIndexes(new sbRemovedItemIndexes());
226  NS_ENSURE_TRUE(removedIndexes, NS_ERROR_OUT_OF_MEMORY);
227 
228  PRBool success = removedIndexes->Init();
229  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
230 
231  success = mBeforeRemoveIndexes.Put(list, removedIndexes);
232  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
233 
234  removedIndexes.forget();
235  }
236 
237  if(mIgnoreListener) {
238  return NS_OK;
239  }
240 
241  nsCOMPtr<nsIMutableArray> items =
242  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
243  NS_ENSURE_SUCCESS(rv, rv);
244 
245  rv = items->AppendElement(aMediaItem, PR_FALSE);
246  NS_ENSURE_SUCCESS(rv, rv);
247 
248  PRUint32 transferItemCount = 0;
249  if (mManagePlaylists) {
250  if (destinationIsLibrary) {
251  if (addedIsList) {
252  rv = mDevice->CreatePlaylists(mDeviceIdentifier,
253  items,
254  &transferItemCount);
255  NS_ENSURE_SUCCESS(rv, rv);
256  }
257  else {
258  nsCOMPtr<nsIURI> uri;
259  //XXXAus: Read this from a library pref???
260  rv = mDevice->TransferItems(mDeviceIdentifier,
261  items,
262  uri,
264  PR_TRUE,
265  nsnull,
266  &transferItemCount);
267  NS_ENSURE_SUCCESS(rv, rv);
268  }
269  }
270  else {
271  if (addedIsList) {
272  NS_WARNING("DeviceBase does not support lists of lists!");
273  }
274  else {
275  // An item is getting added to a list
276  rv = mDevice->AddToPlaylist(mDeviceIdentifier,
277  aMediaList,
278  items,
279  0,
280  &transferItemCount);
281  NS_ENSURE_SUCCESS(rv, rv);
282  }
283  }
284  }
285  else {
286  nsCOMPtr<nsIURI> uri;
287  rv = mDevice->TransferItems(mDeviceIdentifier,
288  items,
289  uri,
291  PR_TRUE,
292  nsnull,
293  &transferItemCount);
294  NS_ENSURE_SUCCESS(rv, rv);
295  }
296 
297  return NS_OK;
298 }
299 
300 NS_IMETHODIMP
301 sbDeviceBaseLibraryListener::OnBeforeItemRemoved(sbIMediaList *aMediaList,
302  sbIMediaItem *aMediaItem,
303  PRUint32 aIndex,
304  PRBool *aNoMoreForBatch)
305 {
306  NS_ENSURE_ARG_POINTER(aMediaList);
307  NS_ENSURE_ARG_POINTER(aMediaItem);
308  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
309 
310  nsresult rv;
311  *aNoMoreForBatch = PR_FALSE;
312 
313  // If we're not managing playlists, nothing to do here
314  if (!mManagePlaylists) {
315  return NS_OK;
316  }
317 
318  if(mIgnoreListener) {
319  return NS_OK;
320  }
321 
322  // We need to track the indexes of items that are about to be removed from
323  // lists. Note that this will not work as expected when removing an item
324  // from a list that has multiple instances of the same item.
325  nsCOMPtr<sbILibrary> library;
326  rv = aMediaList->GetLibrary(getter_AddRefs(library));
327  NS_ENSURE_SUCCESS(rv, rv);
328 
329  PRBool fromListIsLibrary;
330  rv = aMediaList->Equals(library, &fromListIsLibrary);
331  NS_ENSURE_SUCCESS(rv, rv);
332 
333  if (!fromListIsLibrary) {
334  PRUint32 index;
335  rv = aMediaList->IndexOf(aMediaItem, 0, &index);
336  NS_ENSURE_SUCCESS(rv, rv);
337 
338  sbRemovedItemIndexes* removedIndexes;
339  PRBool success = mBeforeRemoveIndexes.Get(aMediaList, &removedIndexes);
340  NS_ENSURE_TRUE(success, NS_ERROR_UNEXPECTED);
341 
342  success = removedIndexes->Put(aMediaItem, index);
343  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
344  }
345 
346  return NS_OK;
347 }
348 
349 NS_IMETHODIMP
350 sbDeviceBaseLibraryListener::OnAfterItemRemoved(sbIMediaList *aMediaList,
351  sbIMediaItem *aMediaItem,
352  PRUint32 aIndex,
353  PRBool *aNoMoreForBatch)
354 {
355  NS_ENSURE_ARG_POINTER(aMediaList);
356  NS_ENSURE_ARG_POINTER(aMediaItem);
357  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
358 
359  nsresult rv;
360 
361  *aNoMoreForBatch = PR_FALSE;
362 
363  nsCOMPtr<sbILibrary> library;
364  rv = aMediaList->GetLibrary(getter_AddRefs(library));
365  NS_ENSURE_SUCCESS(rv, rv);
366 
367  PRBool fromListIsLibrary;
368  rv = aMediaList->Equals(library, &fromListIsLibrary);
369  NS_ENSURE_SUCCESS(rv, rv);
370 
371  nsCOMPtr<sbIMediaList> list = do_QueryInterface(aMediaItem, &rv);
372  PRBool removedIsList = NS_SUCCEEDED(rv);
373 
374  if (mManagePlaylists && fromListIsLibrary && removedIsList) {
375  rv = list->RemoveListener(this);
376  NS_ENSURE_SUCCESS(rv, rv);
377  }
378 
379  if(mIgnoreListener) {
380  return NS_OK;
381  }
382 
383  nsCOMPtr<nsIMutableArray> items =
384  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
385  NS_ENSURE_SUCCESS(rv, rv);
386 
387  rv = items->AppendElement(aMediaItem, PR_FALSE);
388  NS_ENSURE_SUCCESS(rv, rv);
389 
390  PRUint32 deleteItemCount;
391  if (mManagePlaylists) {
392  if (fromListIsLibrary) {
393  if (removedIsList) {
394  rv = mDevice->DeletePlaylists(mDeviceIdentifier, items, &deleteItemCount);
395  NS_ENSURE_SUCCESS(rv, rv);
396 
397  mBeforeRemoveIndexes.Remove(aMediaList);
398  }
399  else {
400  rv = mDevice->DeleteItems(mDeviceIdentifier, items, &deleteItemCount);
401  NS_ENSURE_SUCCESS(rv, rv);
402  }
403  }
404  else {
405  if (removedIsList) {
406  NS_WARNING("Removal of lists that contain lists is not suported");
407  }
408  else {
409  sbRemovedItemIndexes* removedIndexes;
410  PRBool success = mBeforeRemoveIndexes.Get(aMediaList, &removedIndexes);
411  NS_ENSURE_TRUE(success, NS_ERROR_UNEXPECTED);
412 
413  PRUint32 index;
414  PRBool found = removedIndexes->Get(aMediaItem, &index);
415  if (found) {
416  removedIndexes->Remove(aMediaItem);
417  rv = mDevice->RemoveFromPlaylist(mDeviceIdentifier,
418  aMediaList,
419  aMediaItem,
420  index,
421  &deleteItemCount);
422  NS_ENSURE_SUCCESS(rv, rv);
423 
424  // Removing an item from the playlist will shift the indexes of the
425  // items that come after it, so we shift the indexes in the
426  // mBeforeRemoveIndexes list to keep them in sync.
427  removedIndexes->Enumerate(ShiftIndexesCallback, &index);
428  }
429  else {
430  NS_WARNING("OnAfterItemRemoved on item not in mBeforeRemoveIndexes");
431  }
432  }
433  }
434  }
435  else {
436  rv = mDevice->DeleteItems(mDeviceIdentifier, items, &deleteItemCount);
437  NS_ENSURE_SUCCESS(rv, rv);
438  }
439 
440  return NS_OK;
441 }
442 
443 NS_IMETHODIMP
444 sbDeviceBaseLibraryListener::OnItemUpdated(sbIMediaList *aMediaList,
445  sbIMediaItem *aMediaItem,
446  sbIPropertyArray* aProperties,
447  PRBool* aNoMoreForBatch)
448 {
449  NS_ENSURE_ARG_POINTER(aMediaItem);
450  NS_ENSURE_ARG_POINTER(aMediaList);
451  NS_ENSURE_ARG_POINTER(aProperties);
452  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
453 
454  *aNoMoreForBatch = PR_FALSE;
455 
456  if(mIgnoreListener) {
457  return NS_OK;
458  }
459 
460  nsresult rv;
461 
462  nsCOMPtr<nsIMutableArray> items;
463  items = do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
464  NS_ENSURE_SUCCESS(rv, rv);
465 
466  rv = items->AppendElement(aMediaItem, PR_FALSE);
467  NS_ENSURE_SUCCESS(rv, rv);
468 
469  PRUint32 updateItemCount;
470  rv = mDevice->UpdateItems(mDeviceIdentifier, items, &updateItemCount);
471  NS_ENSURE_SUCCESS(rv, rv);
472 
473  return NS_OK;
474 }
475 
476 NS_IMETHODIMP
477 sbDeviceBaseLibraryListener::OnItemMoved(sbIMediaList *aMediaList,
478  PRUint32 aFromIndex,
479  PRUint32 aToIndex,
480  PRBool *aNoMoreForBatch)
481 {
482  NS_ENSURE_ARG_POINTER(aMediaList);
483  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
484 
485  *aNoMoreForBatch = PR_FALSE;
486 
487  if(mIgnoreListener) {
488  return NS_OK;
489  }
490 
491  if (aFromIndex == aToIndex) {
492  return NS_OK;
493  }
494 
495  PRUint32 updateItemCount;
496  nsresult rv;
497  rv = mDevice->MovePlaylistItem(mDeviceIdentifier,
498  aMediaList,
499  aFromIndex,
500  aToIndex,
501  &updateItemCount);
502  NS_ENSURE_SUCCESS(rv, rv);
503 
504  return NS_OK;
505 
506 }
507 
508 NS_IMETHODIMP
509 sbDeviceBaseLibraryListener::OnBeforeListCleared(sbIMediaList *aMediaList,
510  PRBool aExcludeLists,
511  PRBool* aNoMoreForBatch)
512 {
513  /* Validate parameters. */
514  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
515 
516  *aNoMoreForBatch = PR_FALSE;
517  return NS_OK;
518 }
519 
520 NS_IMETHODIMP
521 sbDeviceBaseLibraryListener::OnListCleared(sbIMediaList *aMediaList,
522  PRBool aExcludeLists,
523  PRBool* aNoMoreForBatch)
524 {
525  NS_ENSURE_ARG_POINTER(aMediaList);
526  NS_ENSURE_ARG_POINTER(aNoMoreForBatch);
527 
528  *aNoMoreForBatch = PR_FALSE;
529 
530  if(mIgnoreListener) {
531  return NS_OK;
532  }
533 
534  nsresult rv;
535 
536  nsCOMPtr<sbILibrary> library;
537  rv = aMediaList->GetLibrary(getter_AddRefs(library));
538  NS_ENSURE_SUCCESS(rv, rv);
539 
540  PRBool fromListIsLibrary;
541  rv = aMediaList->Equals(library, &fromListIsLibrary);
542  NS_ENSURE_SUCCESS(rv, rv);
543 
544  PRUint32 deletedItemCount = 0;
545  if (!mManagePlaylists || fromListIsLibrary) {
546  rv = mDevice->DeleteAllItems(mDeviceIdentifier, &deletedItemCount);
547  NS_ENSURE_SUCCESS(rv, rv);
548  }
549  else {
550  rv = mDevice->ClearPlaylist(mDeviceIdentifier,
551  aMediaList,
552  &deletedItemCount);
553  NS_ENSURE_SUCCESS(rv, rv);
554  }
555 
556  return NS_OK;
557 }
558 
559 NS_IMETHODIMP
560 sbDeviceBaseLibraryListener::OnBatchBegin(sbIMediaList *aMediaList)
561 {
562  return NS_OK;
563 }
564 
565 NS_IMETHODIMP
566 sbDeviceBaseLibraryListener::OnBatchEnd(sbIMediaList *aMediaList)
567 {
568  return NS_OK;
569 }
570 
571 //sbILocalDatabaseMediaListCopyListener
574 
576 {
577 
578 }
579 
581 {
582 
583 }
584 
585 nsresult
586 sbDeviceBaseLibraryCopyListener::Init(const nsAString &aDeviceIdentifier,
587  sbIDeviceBase* aDevice)
588 {
589  NS_ENSURE_ARG_POINTER(aDevice);
590 
591  mDeviceIdentifier = aDeviceIdentifier;
592  mDevice = aDevice;
593 
594  return NS_OK;
595 }
596 
597 NS_IMETHODIMP
598 sbDeviceBaseLibraryCopyListener::OnItemCopied(sbIMediaItem *aSourceItem,
599  sbIMediaItem *aDestItem)
600 {
601  NS_ENSURE_ARG_POINTER(aSourceItem);
602  NS_ENSURE_ARG_POINTER(aDestItem);
603 
604  nsresult rv;
605  nsCOMPtr<nsIMutableArray> items;
606 
607  items = do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
608  NS_ENSURE_SUCCESS(rv, rv);
609 
610  rv = items->AppendElement(aSourceItem, PR_FALSE);
611  NS_ENSURE_SUCCESS(rv, rv);
612 
613  nsCOMPtr<nsIURI> uri;
614  //XXXAus: Get URI from pref for library???
615 
616  nsCOMPtr<sbILibrary> library;
617  rv = aDestItem->GetLibrary(getter_AddRefs(library));
618 
619  PRUint32 transferItemCount = 0;
620  rv = mDevice->TransferItems(mDeviceIdentifier,
621  items,
622  uri,
624  PR_TRUE,
625  library,
626  &transferItemCount);
627 
628  return NS_OK;
629 }
630 
631 //sbDeviceBaseCallbackProxy class.
634 
636 {
637 }
638 
640 {
641  // Release callback proxy from the owning thread.
643  {
644  sbIDeviceBaseCallback *callbackProxy = nsnull;
645  mCallbackProxy.swap(callbackProxy);
646  NS_ProxyRelease(mOwningThread, callbackProxy);
647  }
648 }
649 
651 {
652  NS_ASSERTION(aCallback, "aCallback is null");
653 
654  nsCOMPtr<nsIProxyObjectManager> proxyObjectManager;
655  nsresult rv;
656 
657  // Get the callback owning thread so proxy can be released on it.
658  nsCOMPtr<nsIThread> thread;
659  rv = NS_GetCurrentThread(getter_AddRefs(thread));
660  NS_ENSURE_SUCCESS(rv, rv);
661  mOwningThread = do_QueryInterface(thread, &rv);
662  NS_ENSURE_SUCCESS(rv, rv);
663 
664  // Proxy callback so callbacks can be made from other threads.
665  proxyObjectManager = do_CreateInstance("@mozilla.org/xpcomproxy;1", &rv);
666  NS_ENSURE_SUCCESS(rv, rv);
667  rv = proxyObjectManager->GetProxyForObject
668  (NS_PROXY_TO_CURRENT_THREAD,
669  NS_GET_IID(sbIDeviceBaseCallback),
670  aCallback,
671  nsIProxyObjectManager::INVOKE_ASYNC |
672  nsIProxyObjectManager::FORCE_PROXY_CREATION,
673  getter_AddRefs(mCallbackProxy));
674  NS_ENSURE_SUCCESS(rv, rv);
675 
676  return (NS_OK);
677 }
678 
679 //sbDeviceBase class.
681 {
682 #ifdef PR_LOGGING
683  if (!gUSBMassStorageDeviceLog) {
684  gUSBMassStorageDeviceLog = PR_NewLogModule("sbDeviceBase");
685  }
686 #endif
687 }
688 
690 {
691 }
692 
693 nsresult
695 {
696  NS_ENSURE_TRUE(mDeviceLibraries.Init(), NS_ERROR_OUT_OF_MEMORY);
697  NS_ENSURE_TRUE(mDeviceQueues.Init(), NS_ERROR_OUT_OF_MEMORY);
698  NS_ENSURE_TRUE(mDeviceCallbacks.Init(), NS_ERROR_OUT_OF_MEMORY);
699  NS_ENSURE_TRUE(mDeviceStates.Init(), NS_ERROR_OUT_OF_MEMORY);
700  NS_ENSURE_TRUE(mDeviceLibraryListeners.Init(), NS_ERROR_OUT_OF_MEMORY);
701 
702  return NS_OK;
703 }
704 
705 nsresult
707 {
708  NS_ENSURE_ARG_POINTER(aCallback);
709 
710  nsRefPtr<sbDeviceBaseCallbackProxy> callbackProxy;
711  nsresult rv;
712 
713  // Proxy callback so callbacks can be made from other threads.
714  callbackProxy = new sbDeviceBaseCallbackProxy();
715  NS_ENSURE_TRUE(callbackProxy, NS_ERROR_OUT_OF_MEMORY);
716  rv = callbackProxy->Init(aCallback);
717  NS_ENSURE_SUCCESS(rv, rv);
718 
719  if(mDeviceCallbacks.Put(aCallback, callbackProxy)) {
720  return NS_OK;
721  }
722 
723  return NS_ERROR_OUT_OF_MEMORY;
724 }
725 
726 nsresult
728 {
729  NS_ENSURE_ARG_POINTER(aCallback);
730 
731  mDeviceCallbacks.Remove(aCallback);
732 
733  return NS_OK;
734 }
735 
736 PR_STATIC_CALLBACK(PLDHashOperator)
738 {
739  nsCOMArray<sbIDeviceBaseCallback> *array = static_cast<nsCOMArray<sbIDeviceBaseCallback> *>(closure);
740  array->AppendObject(data->mCallbackProxy);
741  return PL_DHASH_NEXT;
742 }
743 
744 void
746 {
747  NS_ASSERTION(aMediaItem, "aMediaItem is null");
748  PRUint32 callbackCount = 0;
749  nsCOMArray<sbIDeviceBaseCallback> callbackSnapshot;
750  mDeviceCallbacks.EnumerateRead(EnumDeviceCallback, &callbackSnapshot);
751 
752  callbackCount = callbackSnapshot.Count();
753  if(!callbackCount)
754  return;
755 
756  for(PRUint32 i = 0; i < callbackCount; i++)
757  {
758  nsCOMPtr<sbIDeviceBaseCallback> callback = callbackSnapshot.ObjectAt(i);
759  if(callback) {
760  try {
761  callback->OnTransferStart(aMediaItem);
762  }
763  catch(...) {
764  //Oops. Someone is being really bad.
765  NS_ERROR("pCallback->OnTransferStart threw an exception");
766  }
767  }
768  }
769 }
770 
771 void
773  PRInt32 aStatus)
774 {
775  NS_ASSERTION(aMediaItem, "aMediaItem is null");
776  PRUint32 callbackCount = 0;
777  nsCOMArray<sbIDeviceBaseCallback> callbackSnapshot;
778  mDeviceCallbacks.EnumerateRead(EnumDeviceCallback, &callbackSnapshot);
779 
780  callbackCount = callbackSnapshot.Count();
781  if(!callbackCount)
782  return;
783 
784  for(PRUint32 i = 0; i < callbackCount; i++)
785  {
786  nsCOMPtr<sbIDeviceBaseCallback> callback = callbackSnapshot.ObjectAt(i);
787  if(callback) {
788  try {
789  callback->OnTransferComplete(aMediaItem, aStatus);
790  }
791  catch(...) {
792  //Oops. Someone is being really bad.
793  NS_ERROR("pCallback->OnTransferComplete threw an exception");
794  }
795  }
796  }
797 }
798 
799 void
800 sbDeviceBase::DoDeviceConnectCallback(const nsAString& aDeviceString)
801 {
802  PRUint32 callbackCount = 0;
803  nsCOMArray<sbIDeviceBaseCallback> callbackSnapshot;
804  mDeviceCallbacks.EnumerateRead(EnumDeviceCallback, &callbackSnapshot);
805 
806  callbackCount = callbackSnapshot.Count();
807  if(!callbackCount)
808  return;
809 
810  for(PRUint32 i = 0; i < callbackCount; i++)
811  {
812  nsCOMPtr<sbIDeviceBaseCallback> callback = callbackSnapshot.ObjectAt(i);
813  if(callback) {
814  try {
815  callback->OnDeviceConnect(aDeviceString);
816  }
817  catch(...) {
818  //Oops. Someone is being really bad.
819  NS_ERROR("pCallback->OnDeviceConnect threw an exception");
820  }
821  }
822  }
823 }
824 
825 void
826 sbDeviceBase::DoDeviceDisconnectCallback(const nsAString& aDeviceString)
827 {
828  PRUint32 callbackCount = 0;
829  nsCOMArray<sbIDeviceBaseCallback> callbackSnapshot;
830  mDeviceCallbacks.EnumerateRead(EnumDeviceCallback, &callbackSnapshot);
831 
832  callbackCount = callbackSnapshot.Count();
833  if(!callbackCount)
834  return;
835 
836  for(PRUint32 i = 0; i < callbackCount; i++)
837  {
838  nsCOMPtr<sbIDeviceBaseCallback> callback = callbackSnapshot.ObjectAt(i);
839  if(callback) {
840  try {
841  callback->OnDeviceDisconnect(aDeviceString);
842  }
843  catch(...) {
844  //Oops. Someone is being really bad.
845  NS_ERROR("pCallback->OnDeviceDisconnect threw an exception");
846  }
847  }
848  }
849 }
850 
851 void
852 sbDeviceBase::DoStateChangedCallback(const nsAString& aDeviceString,
853  PRUint32 aState)
854 {
855  PRUint32 callbackCount = 0;
856  nsCOMArray<sbIDeviceBaseCallback> callbackSnapshot;
857  mDeviceCallbacks.EnumerateRead(EnumDeviceCallback, &callbackSnapshot);
858 
859  callbackCount = callbackSnapshot.Count();
860  if(!callbackCount)
861  return;
862 
863  for(PRUint32 i = 0; i < callbackCount; i++)
864  {
865  nsCOMPtr<sbIDeviceBaseCallback> callback = callbackSnapshot.ObjectAt(i);
866  if(callback) {
867  try {
868  callback->OnStateChanged(aDeviceString, aState);
869  }
870  catch(...) {
871  //Oops. Someone is being really bad.
872  NS_ERROR("pCallback->OnStateChanged threw an exception");
873  }
874  }
875  }
876 }
877 
878 nsresult
879 sbDeviceBase::CreateDeviceLibrary(const nsAString &aDeviceIdentifier,
880  nsIURI *aDeviceDatabaseURI,
881  sbIDeviceBase *aDevice)
882 {
883  NS_ENSURE_ARG_POINTER(aDevice);
884 
885  nsresult rv;
886  nsCOMPtr<sbILibraryFactory> libraryFactory =
887  do_GetService(SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID, &rv);
888  NS_ENSURE_SUCCESS(rv, rv);
889 
890  nsCOMPtr<nsIWritablePropertyBag2> libraryProps =
891  do_CreateInstance("@mozilla.org/hash-property-bag;1", &rv);
892  NS_ENSURE_SUCCESS(rv, rv);
893 
894  nsCOMPtr<nsIFile> libraryFile;
895  if(aDeviceDatabaseURI) {
896  //Use preferred database location.
897  nsCOMPtr<nsIFileURL> furl = do_QueryInterface(aDeviceDatabaseURI, &rv);
898  NS_ENSURE_SUCCESS(rv, rv);
899 
900  rv = furl->GetFile(getter_AddRefs(libraryFile));
901  NS_ENSURE_SUCCESS(rv, rv);
902  }
903  else {
904  //No preferred database location, fetch default location.
905  rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
906  getter_AddRefs(libraryFile));
907  NS_ENSURE_SUCCESS(rv, rv);
908 
909  rv = libraryFile->Append(NS_LITERAL_STRING("db"));
910  NS_ENSURE_SUCCESS(rv, rv);
911 
912  PRBool exists = PR_FALSE;
913  rv = libraryFile->Exists(&exists);
914  NS_ENSURE_SUCCESS(rv, rv);
915  if(!exists) {
916  rv = libraryFile->Create(nsIFile::DIRECTORY_TYPE, 0700);
917  NS_ENSURE_SUCCESS(rv, rv);
918  }
919 
920  nsAutoString filename(aDeviceIdentifier);
921  filename.AppendLiteral(".db");
922 
923  rv = libraryFile->Append(filename);
924  NS_ENSURE_SUCCESS(rv, rv);
925  }
926 
927  rv = libraryProps->SetPropertyAsInterface(NS_LITERAL_STRING("databaseFile"),
928  libraryFile);
929  NS_ENSURE_SUCCESS(rv, rv);
930 
931 #ifdef PR_LOGGING
932  {
933  nsCAutoString str;
934  if(NS_SUCCEEDED(libraryFile->GetNativePath(str))) {
935  LOG(("Attempting to create device library with file path %s", str.get()));
936  }
937  }
938 #endif
939 
940  nsCOMPtr<sbILibrary> library;
941  rv = libraryFactory->CreateLibrary(libraryProps, getter_AddRefs(library));
942  NS_ENSURE_SUCCESS(rv, rv);
943 
944  nsRefPtr<sbDeviceBaseLibraryListener> listener;
945  NS_NEWXPCOM(listener, sbDeviceBaseLibraryListener);
946  NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
947 
948  rv = listener->Init(aDeviceIdentifier, aDevice);
949  NS_ENSURE_SUCCESS(rv, rv);
950 
951  nsCOMPtr<sbIMediaList> list;
952  list = do_QueryInterface(library, &rv);
953  NS_ENSURE_SUCCESS(rv, rv);
954 
955  rv = list->AddListener(listener,
956  PR_FALSE,
961  nsnull);
962  NS_ENSURE_SUCCESS(rv, rv);
963 
964  rv = SetListenerForDeviceLibrary(aDeviceIdentifier, listener);
965  NS_ENSURE_SUCCESS(rv, rv);
966 
967  nsCOMPtr<sbILocalDatabaseSimpleMediaList> simpleList;
968  simpleList = do_QueryInterface(list, &rv);
969 
970  if(NS_SUCCEEDED(rv)) {
971  nsRefPtr<sbDeviceBaseLibraryCopyListener> copyListener;
972  NS_NEWXPCOM(copyListener, sbDeviceBaseLibraryCopyListener);
973  NS_ENSURE_TRUE(copyListener, NS_ERROR_OUT_OF_MEMORY);
974 
975  rv = copyListener->Init(aDeviceIdentifier, aDevice);
976  NS_ENSURE_SUCCESS(rv, rv);
977 
978  rv = simpleList->SetCopyListener(copyListener);
979  NS_ENSURE_SUCCESS(rv, rv);
980  }
981  else {
982  NS_WARN_IF_FALSE(rv,
983  "Failed to get sbILocalDatabaseSimpleMediaList interface. Copy Listener disabled.");
984  }
985 
986  if(mDeviceLibraries.Put(nsAutoString(aDeviceIdentifier), library)) {
987  return NS_OK;
988  }
989 
990  return NS_ERROR_OUT_OF_MEMORY;
991 }
992 
993 nsresult
994 sbDeviceBase::RemoveDeviceLibrary(const nsAString &aDeviceIdentifier)
995 {
996  mDeviceLibraries.Remove(aDeviceIdentifier);
997  return NS_OK;
998 }
999 
1000 nsresult
1001 sbDeviceBase::GetLibraryForDevice(const nsAString &aDeviceIdentifier,
1002  sbILibrary* *aDeviceLibrary)
1003 {
1004  NS_ENSURE_ARG_POINTER(aDeviceLibrary);
1005 
1006  if(mDeviceLibraries.Get(nsAutoString(aDeviceIdentifier), aDeviceLibrary)) {
1007  return NS_OK;
1008  }
1009 
1010  return NS_ERROR_INVALID_ARG;
1011 }
1012 
1013 nsresult
1015 {
1016  NS_ENSURE_ARG_POINTER(aDeviceLibrary);
1017 
1018  nsresult rv;
1019  nsCOMPtr<sbILibraryManager> libraryManager;
1020  libraryManager =
1021  do_GetService("@songbirdnest.com/Songbird/library/Manager;1", &rv);
1022  NS_ENSURE_SUCCESS(rv, rv);
1023 
1024  return libraryManager->RegisterLibrary(aDeviceLibrary, PR_FALSE);
1025 }
1026 
1027 nsresult
1029 {
1030  NS_ENSURE_ARG_POINTER(aDeviceLibrary);
1031 
1032  nsresult rv;
1033  nsCOMPtr<sbILibraryManager> libraryManager;
1034  libraryManager =
1035  do_GetService("@songbirdnest.com/Songbird/library/Manager;1", &rv);
1036  NS_ENSURE_SUCCESS(rv, rv);
1037 
1038  return libraryManager->UnregisterLibrary(aDeviceLibrary);
1039 }
1040 
1041 nsresult
1042 sbDeviceBase::CreateTransferQueue(const nsAString &aDeviceIdentifier)
1043 {
1044  nsresult rv;
1045  nsCOMPtr<nsIMutableArray> deviceQueue =
1046  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1047  NS_ENSURE_SUCCESS(rv, rv);
1048 
1049  if(mDeviceQueues.Put(nsAutoString(aDeviceIdentifier), deviceQueue)) {
1050  return NS_OK;
1051  }
1052 
1053  return NS_ERROR_OUT_OF_MEMORY;
1054 }
1055 
1056 nsresult
1057 sbDeviceBase::RemoveTransferQueue(const nsAString &aDeviceIdentifier)
1058 {
1059  mDeviceQueues.Remove(nsAutoString(aDeviceIdentifier));
1060  return NS_OK;
1061 }
1062 
1063 nsresult
1064 sbDeviceBase::AddItemToTransferQueue(const nsAString &aDeviceIdentifier,
1065  sbIMediaItem* aMediaItem)
1066 {
1067  NS_ENSURE_ARG_POINTER(aMediaItem);
1068 
1069  nsCOMPtr<nsIMutableArray> deviceQueue;
1070  if(mDeviceQueues.Get(aDeviceIdentifier, getter_AddRefs(deviceQueue))) {
1071  return deviceQueue->AppendElement(aMediaItem, PR_FALSE);
1072  }
1073 
1074  return NS_ERROR_INVALID_ARG;
1075 }
1076 
1077 nsresult
1078 sbDeviceBase::RemoveItemFromTransferQueue(const nsAString &aDeviceIdentifier,
1079  sbIMediaItem* aMediaItem)
1080 {
1081  NS_ENSURE_ARG_POINTER(aMediaItem);
1082 
1083  nsresult rv;
1084  PRUint32 index = 0;
1085 
1086  nsCOMPtr<nsIMutableArray> deviceQueue;
1087  if(mDeviceQueues.Get(aDeviceIdentifier, getter_AddRefs(deviceQueue))) {
1088  rv = deviceQueue->IndexOf(0, aMediaItem, &index);
1089  NS_ENSURE_SUCCESS(rv, rv);
1090 
1091  return deviceQueue->RemoveElementAt(index);
1092  }
1093 
1094  return NS_OK;
1095 }
1096 
1097 nsresult
1098 sbDeviceBase::GetNextItemFromTransferQueue(const nsAString &aDeviceIdentifier,
1099  sbIMediaItem* *aMediaItem)
1100 {
1101  NS_ENSURE_ARG_POINTER(aMediaItem);
1102 
1103  nsCOMPtr<nsIMutableArray> deviceQueue;
1104  if(mDeviceQueues.Get(aDeviceIdentifier, getter_AddRefs(deviceQueue))) {
1105  return deviceQueue->QueryElementAt(0,
1106  NS_GET_IID(sbIMediaItem),
1107  (void **)aMediaItem);
1108  }
1109 
1110  return NS_ERROR_INVALID_ARG;
1111 }
1112 
1113 nsresult
1114 sbDeviceBase::GetItemByIndexFromTransferQueue(const nsAString &aDeviceIdentifier,
1115  PRUint32 aItemIndex,
1116  sbIMediaItem* *aMediaItem)
1117 {
1118  NS_ENSURE_ARG_POINTER(aMediaItem);
1119 
1120  nsCOMPtr<nsIMutableArray> deviceQueue;
1121  if(mDeviceQueues.Get(aDeviceIdentifier, getter_AddRefs(deviceQueue))) {
1122  return deviceQueue->QueryElementAt(aItemIndex,
1123  NS_GET_IID(sbIMediaItem),
1124  (void **)aMediaItem);
1125  }
1126 
1127  return NS_ERROR_INVALID_ARG;
1128 }
1129 
1130 nsresult
1131 sbDeviceBase::GetTransferQueue(const nsAString &aDeviceIdentifier,
1132  nsIMutableArray* *aTransferQueue)
1133 {
1134  NS_ENSURE_ARG_POINTER(aTransferQueue);
1135 
1136  *aTransferQueue = nsnull;
1137  if(mDeviceQueues.Get(aDeviceIdentifier, aTransferQueue)) {
1138  return NS_OK;
1139  }
1140 
1141  return NS_ERROR_INVALID_ARG;
1142 }
1143 
1144 nsresult
1145 sbDeviceBase::ClearTransferQueue(const nsAString &aDeviceIdentifier)
1146 {
1147  nsCOMPtr<nsIMutableArray> deviceQueue;
1148  if(mDeviceQueues.Get(nsAutoString(aDeviceIdentifier), getter_AddRefs(deviceQueue))) {
1149  return deviceQueue->Clear();
1150  }
1151 
1152  return NS_ERROR_INVALID_ARG;
1153 }
1154 
1155 nsresult
1156 sbDeviceBase::IsTransferQueueEmpty(const nsAString &aDeviceIdentifier,
1157  PRBool &aEmpty)
1158 {
1159  aEmpty = PR_FALSE;
1160 
1161  nsCOMPtr<nsIMutableArray> queue;
1162  nsresult rv = GetTransferQueue(aDeviceIdentifier, getter_AddRefs(queue));
1163  NS_ENSURE_SUCCESS(rv, rv);
1164 
1165  PRUint32 length = 0;
1166  rv = queue->GetLength(&length);
1167  NS_ENSURE_SUCCESS(rv, rv);
1168 
1169  if(!length) {
1170  aEmpty = PR_TRUE;
1171  }
1172 
1173  return NS_OK;
1174 }
1175 
1176 nsresult
1177 sbDeviceBase::GetDeviceState(const nsAString& aDeviceIdentifier,
1178  PRUint32* aDeviceState)
1179 {
1180  NS_ENSURE_ARG_POINTER(aDeviceState);
1181  *aDeviceState = sbIDeviceBase::STATE_IDLE;
1182 
1183  if(mDeviceStates.Get(aDeviceIdentifier, aDeviceState)) {
1184  return NS_OK;
1185  }
1186 
1187  return NS_ERROR_INVALID_ARG;
1188 }
1189 
1190 nsresult
1191 sbDeviceBase::SetDeviceState(const nsAString& aDeviceIdentifier,
1192  PRUint32 aDeviceState)
1193 {
1194  NS_ENSURE_ARG(aDeviceState >= sbIDeviceBase::STATE_IDLE &&
1195  aDeviceState <= sbIDeviceBase::STATE_DELETING);
1196 
1197  PRUint32 currentState;
1198  NS_ENSURE_TRUE(mDeviceStates.Get(aDeviceIdentifier, &currentState),
1199  NS_ERROR_INVALID_ARG);
1200  if(mDeviceStates.Put(aDeviceIdentifier, aDeviceState)) {
1201  if (aDeviceState != currentState)
1202  DoStateChangedCallback(aDeviceIdentifier, aDeviceState);
1203  return NS_OK;
1204  }
1205 
1206  return NS_ERROR_OUT_OF_MEMORY;
1207 }
1208 
1209 nsresult
1210 sbDeviceBase::InitDeviceState(const nsAString& aDeviceIdentifier)
1211 {
1212  if(mDeviceStates.Put(aDeviceIdentifier, sbIDeviceBase::STATE_IDLE)) {
1213  return NS_OK;
1214  }
1215 
1216  return NS_ERROR_OUT_OF_MEMORY;
1217 }
1218 
1219 nsresult
1220 sbDeviceBase::ClearDeviceState(const nsAString& aDeviceIdentifier)
1221 {
1222  mDeviceStates.Remove(aDeviceIdentifier);
1223 
1224  return NS_OK;
1225 }
1226 
1227 
1228 nsresult
1229 sbDeviceBase::SetListenerForDeviceLibrary(const nsAString& aDeviceIdentifier,
1230  sbIMediaListListener *aMediaListListener)
1231 {
1232  NS_ENSURE_ARG_POINTER(aMediaListListener);
1233 
1234  if(mDeviceLibraryListeners.Put(aDeviceIdentifier, aMediaListListener)) {
1235  return NS_OK;
1236  }
1237 
1238  return NS_ERROR_OUT_OF_MEMORY;
1239 }
1240 
1241 nsresult
1242 sbDeviceBase::GetListenerForDeviceLibrary(const nsAString& aDeviceIdentifier,
1243  sbIMediaListListener* *aMediaListListener)
1244 {
1245  NS_ENSURE_ARG_POINTER(aMediaListListener);
1246 
1247  if(mDeviceLibraryListeners.Get(aDeviceIdentifier, aMediaListListener)) {
1248  return NS_OK;
1249  }
1250 
1251  return NS_ERROR_INVALID_ARG;
1252 }
1253 
1254 nsresult
1255 sbDeviceBase::RemoveListenerForDeviceLibrary(const nsAString& aDeviceIdentifier)
1256 {
1257  nsCOMPtr<sbILibrary> library;
1258  nsCOMPtr<sbIMediaListListener> listener;
1259 
1260  if(mDeviceLibraryListeners.Get(aDeviceIdentifier, getter_AddRefs(listener)) &&
1261  mDeviceLibraries.Get(aDeviceIdentifier, getter_AddRefs(library))) {
1262 
1263  nsresult rv;
1264  nsCOMPtr<sbIMediaList> list;
1265 
1266  list = do_QueryInterface(library, &rv);
1267  NS_ENSURE_SUCCESS(rv, rv);
1268 
1269  rv = list->RemoveListener(listener);
1270  NS_ENSURE_SUCCESS(rv, rv);
1271 
1272  mDeviceLibraryListeners.Remove(aDeviceIdentifier);
1273 
1274  return NS_OK;
1275  }
1276 
1277  return NS_ERROR_INVALID_ARG;
1278 }
nsresult GetListenerForDeviceLibrary(const nsAString &aDeviceIdentifier, sbIMediaListListener **aMediaListListener)
nsresult RemoveItemFromTransferQueue(const nsAString &aDeviceIdentifier, sbIMediaItem *aMediaItem)
Remove an item from the internal transfer queue.
const unsigned long OP_UPLOAD
Device Operation Constants.
nsresult SetIgnoreListener(PRBool aIgnoreListener)
Definition: DeviceBase.cpp:169
void ReplaceChars(nsAString &aOldString, const nsAString &aOldChars, const PRUnichar aNewChar)
Definition: DeviceBase.cpp:95
void DoStateChangedCallback(const nsAString &aDeviceIdentifier, PRUint32 aState)
Definition: DeviceBase.cpp:852
const NS_APP_USER_PROFILE_50_DIR
EnumDeviceCallback(nsISupports *key, sbDeviceBaseCallbackProxy *data, void *closure)
Definition: DeviceBase.cpp:737
return NS_OK
nsresult SetDeviceState(const nsAString &aDeviceIdentifier, PRUint32 aDeviceState)
PR_STATIC_CALLBACK(PRBool) FindElementCallback(void *aElement
inArray array
nsresult Init(sbBaseDevice *aDevice)
[USER CODE SHOULD NOT REFERENCE THIS CLASS]
nsresult GetDeviceState(const nsAString &aDeviceIdentifier, PRUint32 *aDeviceState)
nsresult IsTransferQueueEmpty(const nsAString &aDeviceIdentifier, PRBool &aEmpty)
nsresult UnregisterDeviceLibrary(sbILibrary *aDeviceLibrary)
Unregister a device library with the library manager.
nsresult GetLibraryForDevice(const nsAString &aDeviceIdentifier, sbILibrary **aDeviceLibrary)
Get the library instance for a device.
nsInterfaceHashtableMT< nsStringHashKey, nsIMutableArray > mDeviceQueues
Definition: DeviceBase.h:373
const unsigned long LISTENER_FLAGS_BEFOREITEMREMOVED
A brief description of the contents of this interface.
nsresult SetManagePlaylists(PRBool aManagePlaylists)
Definition: DeviceBase.cpp:176
nsClassHashtable< nsISupportsHashKey, sbRemovedItemIndexes > mBeforeRemoveIndexes
Definition: DeviceBase.h:111
[SOON TO BE DEPRECATED AFTER 0.3] The callback class for sbIDeviceBase
nsCOMPtr< nsIEventTarget > mOwningThread
Definition: DeviceBase.h:143
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
nsresult Init(const nsAString &aDeviceIdentifier, sbIDeviceBase *aDevice)
Definition: DeviceBase.cpp:155
nsresult CreateTransferQueue(const nsAString &aDeviceIdentifier)
Create an internal transfer queue for a device instance.
nsresult GetTransferQueue(const nsAString &aDeviceIdentifier, nsIMutableArray **aTransferQueue)
Get the internnal transfer queue for a device instance.
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
Interface used to listen to changes to a media list.
#define SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID
[SOON TO BE DEPRECATED AFTER 0.3] Base interface for all supported devices.
nsresult InitDeviceState(const nsAString &aDeviceIdentifier)
nsDataHashtableMT< nsStringHashKey, PRUint32 > mDeviceStates
Definition: DeviceBase.h:375
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceBaseLibraryListener, sbIMediaListListener)
nsCOMPtr< sbIDeviceBaseCallback > mCallbackProxy
Definition: DeviceBase.h:142
NS_DECL_ISUPPORTS NS_DECL_SBILOCALDATABASEMEDIALISTCOPYLISTENER sbDeviceBaseLibraryCopyListener()
nsresult RemoveTransferQueue(const nsAString &aDeviceIdentifier)
Remove an internal transfer queue for a device instance.
const PRUint32 STATE_IDLE
const PRUint32 STATE_DELETING
nsresult AddCallback(sbIDeviceBaseCallback *aCallback)
Definition: DeviceBase.cpp:706
virtual ~sbDeviceBaseLibraryListener()
Definition: DeviceBase.cpp:150
const unsigned long LISTENER_FLAGS_AFTERITEMREMOVED
var libraryManager
nsInterfaceHashtableMT< nsStringHashKey, sbILibrary > mDeviceLibraries
Definition: DeviceBase.h:372
nsresult SetListenerForDeviceLibrary(const nsAString &aDeviceIdentifier, sbIMediaListListener *aMediaListListener)
static PLDHashOperator PR_CALLBACK ShiftIndexesCallback(nsISupportsHashKey::KeyType aKey, PRUint32 &aEntry, void *aUserData)
Definition: DeviceBase.cpp:127
nsresult AddItemToTransferQueue(const nsAString &aDeviceIdentifier, sbIMediaItem *aMediaItem)
Add an item to the internal transfer queue.
nsresult GetNextItemFromTransferQueue(const nsAString &aDeviceIdentifier, sbIMediaItem **aMediaItem)
Get the next item in the transfer queue.
grep callback
Media library abstraction.
Definition: sbILibrary.idl:82
const unsigned long LISTENER_FLAGS_LISTCLEARED
nsresult CreateDeviceLibrary(const nsAString &aDeviceIdentifier, nsIURI *aDeviceDatabaseURI, sbIDeviceBase *aDevice)
Create a library for a device instance.
Definition: DeviceBase.cpp:879
sbIDeviceBase * mDevice
Definition: DeviceBase.h:104
nsresult Init()
Initialize the base device class for use.
Definition: DeviceBase.cpp:694
void DoDeviceDisconnectCallback(const nsAString &aDeviceIdentifier)
Definition: DeviceBase.cpp:826
const unsigned long LISTENER_FLAGS_ITEMMOVED
nsresult RegisterDeviceLibrary(sbILibrary *aDeviceLibrary)
Register a device library with the library manager.
var uri
Definition: FeedWriter.js:1135
const unsigned long LISTENER_FLAGS_ITEMADDED
NS_DECL_ISUPPORTS NS_DECL_SBIMEDIALISTLISTENER sbDeviceBaseLibraryListener()
Definition: DeviceBase.cpp:143
nsresult RemoveCallback(sbIDeviceBaseCallback *aCallback)
Definition: DeviceBase.cpp:727
void DoTransferStartCallback(sbIMediaItem *aMediaItem)
Definition: DeviceBase.cpp:745
virtual ~sbDeviceBase()
Definition: DeviceBase.cpp:689
nsresult RemoveListenerForDeviceLibrary(const nsAString &aDeviceIdentifier)
nsInterfaceHashtableMT< nsStringHashKey, sbIMediaListListener > mDeviceLibraryListeners
Definition: DeviceBase.h:377
nsresult RemoveDeviceLibrary(const nsAString &aDeviceIdentifier)
Remove a library for a device instance.
Definition: DeviceBase.cpp:994
nsresult GetItemByIndexFromTransferQueue(const nsAString &aDeviceIdentifier, PRUint32 aItemIndex, sbIMediaItem **aMediaItem)
Get an item from the transfer queue by index.
Interface that defines a single item of media in the system.
nsRefPtrHashtableMT< nsISupportsHashKey, sbDeviceBaseCallbackProxy > mDeviceCallbacks
Definition: DeviceBase.h:374
nsresult ClearTransferQueue(const nsAString &aDeviceIdentifier)
Clear the entire transfer queue.
void DoDeviceConnectCallback(const nsAString &aDeviceIdentifier)
Definition: DeviceBase.cpp:800
nsresult ClearDeviceState(const nsAString &aDeviceIdentifier)
const unsigned long LISTENER_FLAGS_ITEMUPDATED
nsresult Init(sbIDeviceBaseCallback *aCallback)
Definition: DeviceBase.cpp:650
void DoTransferCompleteCallback(sbIMediaItem *aMediaItem, PRInt32 aStatus)
Definition: DeviceBase.cpp:772
nsDataHashtable< nsISupportsHashKey, PRUint32 > sbRemovedItemIndexes
Definition: DeviceBase.h:110
const unsigned long OP_DOWNLOAD
restoreWindow aState
observe data
Definition: FeedWriter.js:1329
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...
virtual ~sbDeviceBaseCallbackProxy()
Definition: DeviceBase.cpp:639
Songbird DeviceBase Component Definition.
_getSelectedPageStyle s i
#define LOG(args)
Definition: DeviceBase.cpp:90