sbIPDDevice.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2011 POTI, Inc.
9  * http://www.songbirdnest.com
10  *
11  * This file may be licensed under the terms of of the
12  * GNU General Public License Version 2 (the ``GPL'').
13  *
14  * Software distributed under the License is distributed
15  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
16  * express or implied. See the GPL for the specific language
17  * governing rights and limitations.
18  *
19  * You should have received a copy of the GPL along with this
20  * program. If not, go to http://www.gnu.org/licenses/gpl.html
21  * or write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  *=END SONGBIRD GPL
25  */
26 
32 //------------------------------------------------------------------------------
33 //
34 // iPod device imported services.
35 //
36 //------------------------------------------------------------------------------
37 
38 // Self import.
39 #include "sbIPDDevice.h"
40 
41 // Local imports.
42 #include "sbIPDFairPlayEvent.h"
43 #include "sbIPDLog.h"
44 #include "sbIPDUtils.h"
45 
46 // Songbird imports.
47 #include <sbAutoRWLock.h>
48 #include <sbDeviceContent.h>
49 #include <sbDeviceUtils.h>
50 #include <sbIDeviceProperties.h>
51 #include <sbIMediacoreManager.h>
52 #include <sbIMediacorePlaybackControl.h>
53 #include <sbIMediacoreSequencer.h>
54 #include <sbIMediacoreStatus.h>
55 #include <sbIMediaListView.h>
57 #include <sbStandardProperties.h>
59 #include <sbStringUtils.h>
60 
61 // Mozilla imports.
62 #include <nsIClassInfoImpl.h>
63 #include <nsIProgrammingLanguage.h>
64 #include <nsIPropertyBag2.h>
65 #include <nsIWritablePropertyBag.h>
66 #include <nsIWritablePropertyBag2.h>
67 #include <nsMemory.h>
68 #include <nsServiceManagerUtils.h>
69 #include <nsIPromptService.h>
70 #include <prprf.h>
71 #include <nsThreadUtils.h>
72 #include <sbDebugUtils.h>
73 
74 
75 //------------------------------------------------------------------------------
76 //
77 // iPod device configuration.
78 //
79 //------------------------------------------------------------------------------
80 
81 //
82 // sbIPDSupportedMediaList List of supported media file extensions derived
83 // from "http://docs.info.apple.com/article.html?artnum=304784".
84 // sbIPDSupportedMediaListLength Length of supported media file extension list.
85 // sbIPDSupportedAudioMediaList List of supported audio media file extensions
86 // derived from
87 // "http://docs.info.apple.com/article.html?artnum=304784".
88 // sbIPDSupportedAudioMediaListLength
89 // Length of supported audio media file extension
90 // list.
91 //
92 
93 const char *sbIPDSupportedMediaList[] =
94 {
95  "mp3",
96  "m4a",
97  "m4p",
98  "jpg",
99  "gif",
100  "tif",
101  "m4v",
102  "mov",
103  "mp4",
104  "aif",
105  "wav",
106  "aa",
107  "aac"
108 };
110  NS_ARRAY_LENGTH(sbIPDSupportedMediaList);
112 {
113  "mp3",
114  "m4a",
115  "m4p",
116  "mp4",
117  "aif",
118  "wav",
119  "aa",
120  "aac"
121 };
123  NS_ARRAY_LENGTH(sbIPDSupportedAudioMediaList);
124 
125 
126 //------------------------------------------------------------------------------
127 //
128 // iPod device nsISupports and nsIClassInfo implementation.
129 //
130 //------------------------------------------------------------------------------
131 
132 // nsISupports implementation.
133 // NS_IMPL_THREADSAFE_ISUPPORTS2_CI(sbIPDDevice,
134 // sbIDevice,
135 // sbIDeviceEventTarget)
139 NS_IMPL_CI_INTERFACE_GETTER2(sbIPDDevice, sbIDevice, sbIDeviceEventTarget)
140 
141 // nsIClassInfo implementation.
142 NS_DECL_CLASSINFO(sbIPDDevice)
143 NS_IMPL_THREADSAFE_CI(sbIPDDevice)
144 
145 
146 //------------------------------------------------------------------------------
147 //
148 // iPod device sbIDevice implementation.
149 //
150 //------------------------------------------------------------------------------
151 
156 NS_IMETHODIMP
157 sbIPDDevice::Connect()
158 {
159  nsresult rv;
160 
161  // Connect. Disconnect on error.
162  rv = ConnectInternal();
163  if (NS_FAILED(rv))
164  Disconnect();
165 
166  return rv;
167 }
168 
169 nsresult
170 sbIPDDevice::ConnectInternal()
171 {
172  nsresult rv;
173 
174  // Do nothing if device is already connected. If the device is not connected,
175  // nothing should be accessing the "connect lock" fields.
176  {
177  sbAutoReadLock autoConnectLock(mConnectLock);
178  if (mConnected)
179  return NS_OK;
180  }
181 
182  // Invoke the super-class.
183  rv = sbBaseDevice::Connect();
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  // Get the device properties.
187  nsCOMPtr<nsIPropertyBag2> properties = do_QueryInterface(mCreationProperties,
188  &rv);
189  NS_ENSURE_SUCCESS(rv, rv);
190 
191  // Get the device mount path.
192  rv = properties->GetPropertyAsAString(NS_LITERAL_STRING("MountPath"),
193  mMountPath);
194  NS_ENSURE_SUCCESS(rv, rv);
195 
196  // Get the Firewire GUID.
197  rv = properties->GetPropertyAsAString(NS_LITERAL_STRING("FirewireGUID"),
198  mFirewireGUID);
199  if (NS_SUCCEEDED(rv)) {
200  FIELD_LOG
201  (("Connect %s\n", NS_LossyConvertUTF16toASCII(mFirewireGUID).get()));
202  } else {
203  FIELD_LOG(("Connect could not get iPod Firewire GUID.\n"));
204  }
205 
206  // Connect the device capabilities.
207  rv = CapabilitiesConnect();
208  NS_ENSURE_SUCCESS(rv, rv);
209 
210  // Connect the iPod database.
211  rv = DBConnect();
212  NS_ENSURE_SUCCESS(rv, rv);
213 
214  // Connect the iPod preference services.
215  rv = PrefConnect();
216  NS_ENSURE_SUCCESS(rv, rv);
217 
218  // Connect the Songbird device library.
219  rv = LibraryConnect();
220  NS_ENSURE_SUCCESS(rv, rv);
221 
222  // Connect the FairPlay services.
223  rv = FPConnect();
224  NS_ENSURE_SUCCESS(rv, rv);
225 
226  // Mark the device as connected. After this, "connect lock" fields may be
227  // used.
228  {
229  sbAutoWriteLock autoConnectLock(mConnectLock);
230  mConnected = PR_TRUE;
231  }
232 
233  // Start the iPod request processing.
234  rv = ReqProcessingStart();
235  NS_ENSURE_SUCCESS(rv, rv);
236 
237  // Mount the device.
238  //XXXeps Do in DBConnect
239  rv = PushRequest(TransferRequest::REQUEST_MOUNT, nsnull, mDeviceLibrary);
240  NS_ENSURE_SUCCESS(rv, rv);
241 
242  // Set up the iPod for the first time if needed
243  rv = SetUpIfNeeded();
244  NS_ENSURE_SUCCESS(rv, rv);
245 
246  return NS_OK;
247 }
248 
249 
254 NS_IMETHODIMP
256 {
257  return sbBaseDevice::Disconnect();
258 }
259 
260 nsresult
262 {
263  // Disconnect the FairPlay services.
264  FPDisconnect();
265 
266  // Disconnect the Songbird device library.
267  LibraryDisconnect();
268 
269  // Disconnect the iPod preference services.
270  PrefDisconnect();
271 
272  // Disconnect the iPod database.
273  DBDisconnect();
274 
275  // Invoke the super-class.
277 
278  return NS_OK;
279 }
280 
285 NS_IMETHODIMP
286 sbIPDDevice::GetPreference(const nsAString& aPrefName,
287  nsIVariant** _retval)
288 {
289  // Forward call to base class.
290  return sbBaseDevice::GetPreference(aPrefName, _retval);
291 }
292 
293 
298 NS_IMETHODIMP
299 sbIPDDevice::SetPreference(const nsAString& aPrefName,
300  nsIVariant* aPrefValue)
301 {
302  // Validate arguments.
303  NS_ENSURE_ARG_POINTER(aPrefValue);
304 
305  // Function variables.
306  nsresult rv;
307 
308  // If a preference needs to be set on the device, enqueue a set preference
309  // request. The internal, locally stored preference is still set here to
310  // provide immediate feedback.
311  if (aPrefName.Equals(SB_SYNC_PARTNER_PREF)) {
312  rv = ReqPushSetNamedValue(REQUEST_SET_PREF, aPrefName, aPrefValue);
313  NS_ENSURE_SUCCESS(rv, rv);
314  }
315 
316  // Forward call to base class.
317  return sbBaseDevice::SetPreference(aPrefName, aPrefValue);
318 }
319 
320 
325 NS_IMETHODIMP
326 sbIPDDevice::SubmitRequest(PRUint32 aRequestType,
327  nsIPropertyBag2* aRequestParameters)
328 {
329  // Log progress.
330  LOG("Enter: sbIPDDevice::SubmitRequest\n");
331 
332  return sbBaseDevice::SubmitRequest(aRequestType, aRequestParameters);
333 }
334 
335 
340 NS_IMETHODIMP
342 {
344 }
345 
346 
351 NS_IMETHODIMP
353 {
354  nsresult rv;
355 
356  // Log progress.
357  LOG("Enter: sbIPDDevice::Eject\n");
358 
359  // work out if we're playing or not...
360 
361  // get the playlist playback
362  nsCOMPtr<sbIMediacoreManager> mm =
363  do_GetService(SB_MEDIACOREMANAGER_CONTRACTID, &rv);
364  NS_ENSURE_SUCCESS(rv, rv);
365 
366  nsCOMPtr<sbIMediacoreSequencer> sequencer;
367  rv = mm->GetSequencer(getter_AddRefs(sequencer));
368  NS_ENSURE_SUCCESS(rv, rv);
369 
370  nsCOMPtr<sbIMediacoreStatus> status;
371  rv = mm->GetStatus(getter_AddRefs(status));
372  NS_ENSURE_SUCCESS(rv, rv);
373 
374  PRUint32 state = 0;
375  rv = status->GetState(&state);
376  NS_ENSURE_SUCCESS(rv, rv);
377 
378  // Not playing, nothing to do.
381  return NS_OK;
382  }
383 
384  // get the index into the currently playing view
385  PRUint32 currentIndex;
386  rv = sequencer->GetViewPosition(&currentIndex);
387  NS_ENSURE_SUCCESS(rv, rv);
388 
389  // get the currently playing view
390  nsCOMPtr<sbIMediaListView> mediaListView;
391  rv = sequencer->GetView(getter_AddRefs(mediaListView));
392  NS_ENSURE_SUCCESS(rv, rv);
393 
394  // get the currently playing media item from the view
395  nsCOMPtr<sbIMediaItem> mediaItem;
396  rv = mediaListView->GetItemByIndex(currentIndex, getter_AddRefs(mediaItem));
397  NS_ENSURE_SUCCESS(rv, rv);
398 
399  // get the library that the media item lives in
400  nsCOMPtr<sbILibrary> library;
401  rv = mediaItem->GetLibrary(getter_AddRefs(library));
402  NS_ENSURE_SUCCESS(rv, rv);
403 
404  // is that library our device library?
405  PRBool equal;
406  rv = mDeviceLibrary->Equals(library, &equal);
407  NS_ENSURE_SUCCESS(rv, rv);
408 
409  if (equal) {
410  // ask the user if we should eject
411  PRBool eject;
412  rv = PromptForEjectDuringPlayback(&eject);
413  NS_ENSURE_SUCCESS(rv, rv);
414 
415  if (eject) {
416  // give them what they asked for
417  nsCOMPtr<sbIMediacorePlaybackControl> playbackControl;
418  rv = mm->GetPlaybackControl(getter_AddRefs(playbackControl));
419  NS_ENSURE_SUCCESS(rv, rv);
420 
421  if (playbackControl) {
422  rv = playbackControl->Stop();
423  NS_ENSURE_SUCCESS(rv, rv);
424  }
425 
426  return NS_OK;
427  }
428 
429  return NS_ERROR_ABORT;
430  }
431 
432  return NS_OK;
433 }
434 
435 /*
436  * Call sync() on all libraries attached to this device
437  */
438 NS_IMETHODIMP
440 {
442 }
443 
444 /*
445  * Determine if a media item can be transferred to the device
446  */
447 NS_IMETHODIMP
450 {
451  return sbBaseDevice::SupportsMediaItem(aMediaItem, aCallback);
452 }
453 
454 //
455 // Getters/setters.
456 //
457 
462 NS_IMETHODIMP
463 sbIPDDevice::GetName(nsAString& aName)
464 {
465  nsresult rv;
466  // Log progress.
467  LOG("Enter: sbIPDDevice::GetName\n");
468  nsAutoString name;
469  rv = mProperties->GetPropertyAsAString(NS_LITERAL_STRING("FriendlyName"),
470  name);
471  NS_ENSURE_SUCCESS(rv, rv);
472  aName.Assign(name);
473 
474  return NS_OK;
475 }
476 
477 
483 NS_IMETHODIMP
484 sbIPDDevice::GetProductName(nsAString& aProductName)
485 {
486  nsAutoString productName;
487  PRBool hasKey;
488  nsresult rv;
489 
490  // Get the vendor name.
491  nsAutoString vendorName;
492  rv = mProperties->HasKey(NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MANUFACTURER),
493  &hasKey);
494  NS_ENSURE_SUCCESS(rv, rv);
495  if (hasKey) {
496  // Get the vendor name.
497  rv = mProperties->GetPropertyAsAString
498  (NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MANUFACTURER),
499  vendorName);
500  NS_ENSURE_SUCCESS(rv, rv);
501  }
502 
503  // Get the device model number, using a default if one is not available.
504  nsAutoString modelNumber;
505  rv = mProperties->HasKey(NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MODEL),
506  &hasKey);
507  NS_ENSURE_SUCCESS(rv, rv);
508  if (hasKey) {
509  // Get the model number.
510  rv = mProperties->GetPropertyAsAString
511  (NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MODEL),
512  modelNumber);
513  NS_ENSURE_SUCCESS(rv, rv);
514  }
515  if (modelNumber.IsEmpty()) {
516  // Get the default model number.
517  modelNumber = SBLocalizedString("device.msc.default.model.number");
518  }
519 
520  // Produce the product name.
521  if (!vendorName.IsEmpty()) {
522  nsTArray<nsString> params;
523  NS_ENSURE_TRUE(params.AppendElement(vendorName), NS_ERROR_OUT_OF_MEMORY);
524  NS_ENSURE_TRUE(params.AppendElement(modelNumber), NS_ERROR_OUT_OF_MEMORY);
525  productName.Assign(SBLocalizedString("device.product.name", params));
526  } else {
527  productName.Assign(modelNumber);
528  }
529 
530  // Return results.
531  aProductName.Assign(productName);
532 
533  return NS_OK;
534 }
535 
536 
541 NS_IMETHODIMP
542 sbIPDDevice::GetControllerId(nsID** aControllerId)
543 {
544  // Validate parameters.
545  NS_ENSURE_ARG_POINTER(aControllerId);
546 
547  // Allocate an nsID.
548  nsID* pId = static_cast<nsID*>(NS_Alloc(sizeof(nsID)));
549  NS_ENSURE_TRUE(pId, NS_ERROR_OUT_OF_MEMORY);
550 
551  // Return the ID.
552  *pId = mControllerID;
553  *aControllerId = pId;
554 
555  return NS_OK;
556 }
557 
558 
563 NS_IMETHODIMP
564 sbIPDDevice::GetId(nsID** aId)
565 {
566  // Validate parameters.
567  NS_ENSURE_ARG_POINTER(aId);
568 
569  // Allocate an nsID.
570  nsID* pId = static_cast<nsID*>(NS_Alloc(sizeof(nsID)));
571  NS_ENSURE_TRUE(pId, NS_ERROR_OUT_OF_MEMORY);
572 
573  // Return the ID.
574  *pId = mDeviceID;
575  *aId = pId;
576 
577  return NS_OK;
578 }
579 
580 
585 NS_IMETHODIMP
586 sbIPDDevice::GetConnected(PRBool* aConnected)
587 {
588  NS_ENSURE_ARG_POINTER(aConnected);
589  *aConnected = mConnected;
590  return NS_OK;
591 }
592 
593 
599 NS_IMETHODIMP
600 sbIPDDevice::GetThreaded(PRBool* aThreaded)
601 {
602  NS_ENSURE_ARG_POINTER(aThreaded);
603  *aThreaded = PR_TRUE;
604  return NS_OK;
605 }
606 
607 
612 NS_IMETHODIMP
613 sbIPDDevice::GetCapabilities(sbIDeviceCapabilities** aCapabilities)
614 {
615  NS_ENSURE_ARG_POINTER(aCapabilities);
616  NS_ADDREF(*aCapabilities = mCapabilities);
617  return NS_OK;
618 }
619 
620 
625 NS_IMETHODIMP
626 sbIPDDevice::GetContent(sbIDeviceContent** aContent)
627 {
628  NS_ENSURE_ARG_POINTER(aContent);
629  NS_ENSURE_STATE(mDeviceContent);
630  NS_ADDREF(*aContent = mDeviceContent);
631  return NS_OK;
632 }
633 
634 
640 NS_IMETHODIMP
642 {
643  return sbBaseDevice::GetDefaultLibrary(aDefaultLibrary);
644 }
645 
646 NS_IMETHODIMP
648 {
649  return sbBaseDevice::SetDefaultLibrary(aDefaultLibrary);
650 }
651 
652 
659 NS_IMETHODIMP
661 {
662  return sbBaseDevice::GetPrimaryLibrary(aPrimaryLibrary);
663 }
664 
665 
670 NS_IMETHODIMP
671 sbIPDDevice::GetParameters(nsIPropertyBag2** aParameters)
672 {
673  // Validate arguments.
674  NS_ENSURE_ARG_POINTER(aParameters);
675 
676  // Function variables.
677  nsresult rv;
678 
679  // Return results.
680  nsCOMPtr<nsIPropertyBag2> parameters = do_QueryInterface(mCreationProperties,
681  &rv);
682  NS_ENSURE_SUCCESS(rv, rv);
683  NS_ADDREF(*aParameters = parameters);
684 
685  return NS_OK;
686 }
687 
688 
693 NS_IMETHODIMP
694 sbIPDDevice::GetProperties(sbIDeviceProperties** aProperties)
695 {
696  // Validate arguments.
697  NS_ENSURE_ARG_POINTER(aProperties);
698 
699  // Return results.
700  NS_ADDREF(*aProperties = mProperties);
701 
702  return NS_OK;
703 }
704 
705 
713 NS_IMETHODIMP
714 sbIPDDevice::GetState(PRUint32* aState)
715 {
716  LOG("Enter: sbIPDDevice::GetState\n");
717  return sbBaseDevice::GetState(aState);
718 }
719 
720 NS_IMETHODIMP
722 {
723  LOG("Enter: sbIPDDevice::SetState\n");
724  return sbBaseDevice::SetState(aState);
725 }
726 
727 NS_IMETHODIMP
729 {
730  return sbBaseDevice::GetPreviousState(aState);
731 }
732 
733 /* pass through to the base class */
734 NS_IMETHODIMP
735 sbIPDDevice::GetIsDirectTranscoding(PRBool* aIsDirect)
736 {
737  return sbBaseDevice::GetIsDirectTranscoding(aIsDirect);
738 }
739 
740 /* pass through to the base class */
741 NS_IMETHODIMP
742 sbIPDDevice::GetIsBusy(PRBool* aIsBusy)
743 {
744  return sbBaseDevice::GetIsBusy(aIsBusy);
745 }
746 
747 /* pass through to the base class */
748 NS_IMETHODIMP
749 sbIPDDevice::GetCanDisconnect(PRBool* aCanDisconnect)
750 {
751  return sbBaseDevice::GetCanDisconnect(aCanDisconnect);
752 }
753 
754 NS_IMETHODIMP sbIPDDevice::SetWarningDialogEnabled(const nsAString & aWarning, PRBool aEnabled)
755 {
756  return sbBaseDevice::SetWarningDialogEnabled(aWarning, aEnabled);
757 }
758 
759 NS_IMETHODIMP sbIPDDevice::GetWarningDialogEnabled(const nsAString & aWarning, PRBool *_retval)
760 {
761  return sbBaseDevice::GetWarningDialogEnabled(aWarning, _retval);
762 }
763 
764 NS_IMETHODIMP sbIPDDevice::ResetWarningDialogs()
765 {
767 }
768 
769 NS_IMETHODIMP sbIPDDevice::OpenInputStream(nsIURI* aURI,
770  nsIInputStream** retval)
771 {
772  return sbBaseDevice::OpenInputStream(aURI, retval);
773 }
774 
775 //------------------------------------------------------------------------------
776 //
777 // iPod device public services.
778 //
779 //------------------------------------------------------------------------------
780 
785 sbIPDDevice::sbIPDDevice(const nsID& aControllerID,
786  nsIPropertyBag* aProperties) :
787 
788  // Preference services.
789  mPrefLock(nsnull),
790  mPrefConnected(PR_FALSE),
791  mIPodPrefs(NULL),
792  mIPodPrefsDirty(PR_FALSE),
793  mSyncPlaylistListDirty(PR_FALSE),
794 
795  // Internal services.
796  mConnectLock(nsnull),
797  mControllerID(aControllerID),
798  mCreationProperties(aProperties),
799  mITDB(NULL),
800  mITDBDirty(PR_FALSE),
801  mITDBDevice(NULL),
802  mConnected(PR_FALSE),
803  mIPDStatus(nsnull)
804 {
805  SB_PRLOG_SETUP(sbIPDDevice);
806 
807  // Log progress.
808  LOG("Enter: sbIPDDevice::sbIPDDevice\n");
809 
810  // Validate arguments.
811  NS_ASSERTION(aProperties, "aProperties is null");
812 }
813 
814 
820 {
821  // Log progress.
822  LOG("Enter: sbIPDDevice::~sbIPDDevice\n");
823 }
824 
825 
826 //------------------------------------------------------------------------------
827 //
828 // iPod device connection services.
829 //
830 // These services are used to connect iPod devices. Since they are a part of
831 // the device connection process, they do not need to operate under the connect
832 // lock.
833 //
834 //------------------------------------------------------------------------------
835 
840 nsresult
841 sbIPDDevice::DBConnect()
842 {
843  // Operate under the request lock.
844  nsAutoMonitor autoDBLock(mDBLock);
845 
846  // Function variables.
847  GError *gError = nsnull;
848  nsresult rv;
849 
850  // Get the utf8 form of the mount path.
851  nsCString mountPath = NS_ConvertUTF16toUTF8(mMountPath);
852 
853  // Initialize the iPod database device data record. */
854  mITDBDevice = itdb_device_new();
855  NS_ENSURE_TRUE(mITDBDevice, NS_ERROR_OUT_OF_MEMORY);
856  itdb_device_set_mountpoint(mITDBDevice, mountPath.get());
857 
858  // If the device file system is not supported, dispatch an event and return
859  // with a failure.
860  if (!IsFileSystemSupported()) {
863  sbIPDVariant(NS_ISUPPORTS_CAST(sbIDevice*, this)).get());
864  NS_ENSURE_SUCCESS(NS_ERROR_FAILURE, NS_ERROR_FAILURE);
865  }
866 
867  // If we've got an HFSPlus filesystem that's read-only we special case
868  // that
869  PRBool hfsplusro;
870  rv = mCreationProperties2->HasKey(NS_LITERAL_STRING("HFSPlusReadOnly"),
871  &hfsplusro);
872  NS_ENSURE_SUCCESS(rv, rv);
873  if (hfsplusro) {
876  sbIPDVariant(NS_ISUPPORTS_CAST(sbIDevice*, this)).get());
877  NS_ENSURE_SUCCESS(NS_ERROR_FAILURE, NS_ERROR_FAILURE);
878  }
879 
880 
881  // If the iPod database file does not exist, initialize the iPod files.
882  gchar* itdbPath = itdb_get_itunesdb_path(mountPath.get());
883  sbAutoGMemPtr autoITDBPath(itdbPath);
884  if (itdbPath == nsnull) {
885  FIELD_LOG(("Missing iTunesDB, creating a new one.\n"));
886  if (!itdb_init_ipod(mountPath.get(), nsnull, "iPod", &gError)) {
887  if (gError) {
888  if (gError->message) {
889  FIELD_LOG(("%s", gError->message));
890  }
891  g_error_free(gError);
892  gError = nsnull;
893  NS_ENSURE_SUCCESS(NS_ERROR_UNEXPECTED, NS_ERROR_UNEXPECTED);
894  }
895  }
896  }
897 
898  // Initialize the sysinfo.
899  rv = InitSysInfo();
900  NS_ENSURE_SUCCESS(rv, rv);
901 
902  // Initialize the iPod database.
903  mITDBDirty = PR_FALSE;
904  mITDB = itdb_parse(mountPath.get(), &gError);
905  if (gError) {
906  if (gError->message) {
907  FIELD_LOG(("%s", gError->message));
908  }
909  g_error_free(gError);
910  gError = NULL;
911  }
912  NS_ENSURE_TRUE(mITDB, NS_ERROR_FAILURE);
913 
914  // Get the master playlist.
915  mMasterPlaylist = itdb_playlist_mpl(mITDB);
916  NS_ENSURE_TRUE(mMasterPlaylist, NS_ERROR_FAILURE);
917 
918  // Convert the playlist name from UTF8 to UTF16 as the device name.
919  NS_ConvertUTF8toUTF16 friendlyName(mMasterPlaylist->name);
920 
921  // Set the device name.
922  rv = mProperties->SetPropertyInternal(NS_LITERAL_STRING("FriendlyName"),
923  sbIPDVariant(friendlyName).get());
924  NS_ENSURE_SUCCESS(rv, rv);
925 
926  return NS_OK;
927 }
928 
929 
934 void
935 sbIPDDevice::DBDisconnect()
936 {
937  // Operate under the request lock.
938  nsAutoMonitor autoDBLock(mDBLock);
939 
940  // Dispose of the iPod database and device data records.
941  if (mITDB)
942  itdb_free(mITDB);
943  mITDB = NULL;
944  mITDBDirty = PR_FALSE;
945  mMasterPlaylist = NULL;
946  if (mITDBDevice)
947  itdb_device_free(mITDBDevice);
948  mITDBDevice = NULL;
949 }
950 
951 
956 nsresult
957 sbIPDDevice::LibraryConnect()
958 {
959  nsresult rv;
960 
961  // Create the device library.
962  nsAutoString libID;
963  libID.AssignLiteral("iPod");
964  libID.Append(mFirewireGUID);
965  libID.AppendLiteral("@devices.library.songbirdnest.com");
966  mDeviceLibrary = new sbIPDLibrary(this);
967  NS_ENSURE_TRUE(mDeviceLibrary, NS_ERROR_OUT_OF_MEMORY);
968  rv = InitializeDeviceLibrary(mDeviceLibrary, libID, nsnull);
969  NS_ENSURE_SUCCESS(rv, rv);
970 
971  // Get an sbIMediaList interface for the device library.
972  mDeviceLibraryML = do_QueryInterface
973  (NS_ISUPPORTS_CAST(sbIDeviceLibrary*, mDeviceLibrary),
974  &rv);
975  NS_ENSURE_SUCCESS(rv, rv);
976 
977  // Add the device library.
978  rv = AddLibrary(mDeviceLibrary);
979  NS_ENSURE_SUCCESS(rv, rv);
980 
981  // Show the device library.
982  //XXXeps should wait for after mount, but need to send an event to make it
983  //work.
984  rv = mDeviceLibrary->SetProperty(NS_LITERAL_STRING(SB_PROPERTY_HIDDEN),
985  NS_LITERAL_STRING("0"));
986  NS_ENSURE_SUCCESS(rv, rv);
987 
988  return NS_OK;
989 }
990 
991 
996 void
997 sbIPDDevice::LibraryDisconnect()
998 {
999  // Remove the device library from the device content and dispose of it.
1000  if (mDeviceLibrary) {
1001  RemoveLibrary(mDeviceLibrary);
1002  FinalizeDeviceLibrary(mDeviceLibrary);
1003  }
1004  mDeviceLibrary = nsnull;
1005  mDeviceLibraryML = nsnull;
1006 }
1007 
1008 
1015 nsresult
1016 sbIPDDevice::InitSysInfo()
1017 {
1018  GError* gError = nsnull;
1019  PRBool success;
1020 
1021  // Set the Firewire GUID value if not set.
1022  if (!mFirewireGUID.IsEmpty()) {
1023  gchar* fwGUID = itdb_device_get_sysinfo(mITDBDevice, "FirewireGuid");
1024  if (!fwGUID) {
1025  // Set the Firewire GUID sysinfo.
1026  itdb_device_set_sysinfo(mITDBDevice,
1027  "FirewireGuid",
1028  NS_ConvertUTF16toUTF8(mFirewireGUID).get());
1029 
1030  // Write the sysinfo file.
1031  success = itdb_device_write_sysinfo(mITDBDevice, &gError);
1032  if (!success) {
1033  if (gError) {
1034  if (gError->message)
1035  FIELD_LOG(("%s", gError->message));
1036  g_error_free(gError);
1037  gError = NULL;
1038  }
1039  NS_ENSURE_TRUE(PR_FALSE, NS_ERROR_FAILURE);
1040  }
1041  } else {
1042  g_free(fwGUID);
1043  }
1044  }
1045 
1046  return NS_OK;
1047 }
1048 
1049 
1050 //------------------------------------------------------------------------------
1051 //
1052 // iPod device statistics services.
1053 //
1054 // These services may only be used within both the connect and request locks.
1055 //
1056 //------------------------------------------------------------------------------
1057 
1065 nsresult
1066 sbIPDDevice::StatsInitialize()
1067 {
1068  // Initialize some of the statistics fields.
1069  mStatsUpdatePeriod = PR_MillisecondsToInterval(IPOD_STATS_UPDATE_PERIOD);
1070  mLastStatsUpdate = PR_IntervalNow();
1071 
1072  return NS_OK;
1073 }
1074 
1075 
1083 void
1084 sbIPDDevice::StatsFinalize()
1085 {
1086 }
1087 
1088 
1096 void
1097 sbIPDDevice::StatsUpdate(PRBool aForceUpdate)
1098 {
1099  // Function variables.
1100  PRUint64 musicSpace = 0;
1101  PRUint64 musicTimeMS = 0;
1102  PRUint32 musicTrackCount = 0;
1103  guint64 capacity;
1104  guint64 free;
1105  guint64 totalUsed;
1106  PRBool success;
1107 
1108  // Do nothing if update is not needed.
1109  PRIntervalTime lastUpdateInterval;
1110  if (!aForceUpdate) {
1111  lastUpdateInterval = PR_IntervalNow() - mLastStatsUpdate;
1112  if (lastUpdateInterval < mStatsUpdatePeriod)
1113  return;
1114  }
1115 
1116  // Update update time.
1117  mLastStatsUpdate = PR_IntervalNow();
1118 
1119  // Collect the track statistics.
1120  GList* trackList;
1121  trackList = mITDB->tracks;
1122  while (trackList) {
1123  // Get the track.
1124  Itdb_Track* track = (Itdb_Track *) trackList->data;
1125  trackList = trackList->next;
1126 
1127  // Update music statistics.
1128  if ((track->mediatype == 0) || (track->mediatype == 1)) {
1129  musicSpace += track->size;
1130  musicTimeMS += track->tracklen;
1131  musicTrackCount++;
1132  }
1133  }
1134 
1135  // Collect device storage statistics.
1136  success = itdb_device_get_storage_info(mITDB->device, &capacity, &free);
1137  NS_ENSURE_TRUE(success, /* void */);
1138  totalUsed = capacity - free;
1139 
1140  // Update the statistics properties.
1141  mProperties->SetPropertyInternal
1142  (NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#capacity"),
1143  sbIPDVariant(capacity).get());
1144  mProperties->SetPropertyInternal
1145  (NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#freeSpace"),
1146  sbIPDVariant(free).get());
1147  mProperties->SetPropertyInternal
1148  (NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#totalUsedSpace"),
1149  sbIPDVariant(totalUsed).get());
1150  mProperties->SetPropertyInternal
1151  (NS_LITERAL_STRING("http://songbirdnest.com/device/1.0#musicUsedSpace"),
1152  sbIPDVariant(musicSpace).get());
1153 }
1154 
1155 
1156 //------------------------------------------------------------------------------
1157 //
1158 // iPod device event services.
1159 //
1160 // These services may only be used within both the connect and request locks.
1161 //
1162 //------------------------------------------------------------------------------
1163 
1177 nsresult
1178 sbIPDDevice::CreateAndDispatchFairPlayEvent(PRUint32 aType,
1179  PRUint32 aUserID,
1180  nsAString& aAccountName,
1181  nsAString& aUserName,
1182  sbIMediaItem* aMediaItem,
1183  PRBool aAsync)
1184 {
1185  nsresult rv;
1186 
1187  // Create the event.
1188  nsRefPtr<sbIPDFairPlayEvent> fairPlayEvent;
1189  rv = sbIPDFairPlayEvent::CreateEvent(getter_AddRefs(fairPlayEvent),
1190  this,
1191  aType,
1192  aUserID,
1193  aAccountName,
1194  aUserName,
1195  aMediaItem);
1196  NS_ENSURE_SUCCESS(rv, rv);
1197 
1198  // Dispatch the event.
1199  nsCOMPtr<sbIDeviceEvent>
1200  event = do_QueryInterface
1201  (NS_ISUPPORTS_CAST(sbIIPDDeviceEvent*, fairPlayEvent), &rv);
1202  NS_ENSURE_SUCCESS(rv, rv);
1203  rv = DispatchEvent(event, aAsync, nsnull);
1204  NS_ENSURE_SUCCESS(rv, rv);
1205 
1206  return NS_OK;
1207 }
1208 
1209 
1210 //------------------------------------------------------------------------------
1211 //
1212 // Internal iPod device services.
1213 //
1214 //------------------------------------------------------------------------------
1215 
1220 nsresult
1222 {
1223  nsresult rv;
1224 
1225  // Initialize the base device object.
1226  rv = sbBaseDevice::Init();
1227  NS_ENSURE_SUCCESS(rv, rv);
1228 
1229  // Create the connect lock.
1230  mConnectLock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "sbIPDDevice::mConnectLock");
1231  NS_ENSURE_TRUE(mConnectLock, NS_ERROR_OUT_OF_MEMORY);
1232 
1233  mDBLock = nsAutoMonitor::NewMonitor("sbIPDDevice::mDBLock");
1234  NS_ENSURE_TRUE(mDBLock, NS_ERROR_OUT_OF_MEMORY);
1235 
1236  // Create an nsIFileProtocolHandler object.
1237  mFileProtocolHandler =
1238  do_CreateInstance("@mozilla.org/network/protocol;1?name=file", &rv);
1239  NS_ENSURE_SUCCESS(rv, rv);
1240 
1241  // Get the property manager service.
1242  mPropertyManager =
1243  do_GetService("@songbirdnest.com/Songbird/Properties/PropertyManager;1",
1244  &rv);
1245  NS_ENSURE_SUCCESS(rv, rv);
1246 
1247  // Get the library manager service.
1248  mLibraryManager =
1249  do_GetService("@songbirdnest.com/Songbird/library/Manager;1", &rv);
1250  NS_ENSURE_SUCCESS(rv, rv);
1251 
1252  // Ensure the iPod device event handler is initialized.
1253  mIPodEventHandler =
1254  do_GetService("@songbirdnest.com/Songbird/IPDEventHandler;1", &rv);
1255  NS_ENSURE_SUCCESS(rv, rv);
1256 
1257  // Get the locale string bundle.
1258  nsCOMPtr<nsIStringBundleService>
1259  stringBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
1260  NS_ENSURE_SUCCESS(rv, rv);
1261  rv = stringBundleService->CreateBundle(IPOD_LOCALE_BUNDLE_PATH,
1262  getter_AddRefs(mLocale));
1263  NS_ENSURE_SUCCESS(rv, rv);
1264 
1265  // Get the device creation properties as an nsIPropertyBag2.
1266  mCreationProperties2 = do_QueryInterface(mCreationProperties, &rv);
1267  NS_ENSURE_SUCCESS(rv, rv);
1268 
1269  // Get the Songbird main library.
1270  rv = mLibraryManager->GetMainLibrary(getter_AddRefs(mSBMainLib));
1271  NS_ENSURE_SUCCESS(rv, rv);
1272  mSBMainML = do_QueryInterface(mSBMainLib, &rv);
1273  NS_ENSURE_SUCCESS(rv, rv);
1274 
1275  // Create the device ID. This depends upon some of the device properties.
1276  rv = CreateDeviceID(&mDeviceID);
1277  NS_ENSURE_SUCCESS(rv, rv);
1278 
1279  // Create and initialize the iPod device status object.
1280  mIPDStatus = new sbIPDStatus(this);
1281  NS_ENSURE_TRUE(mIPDStatus, NS_ERROR_OUT_OF_MEMORY);
1282  rv = mIPDStatus->Initialize();
1283  NS_ENSURE_SUCCESS(rv, rv);
1284 
1285  // Create and initialize the device content object.
1286  mDeviceContent = sbDeviceContent::New();
1287  NS_ENSURE_TRUE(mDeviceContent, NS_ERROR_OUT_OF_MEMORY);
1288  rv = mDeviceContent->Initialize();
1289  NS_ENSURE_SUCCESS(rv, rv);
1290 
1291  // Initialize the iPod mapping services.
1292  rv = MapInitialize();
1293  NS_ENSURE_SUCCESS(rv, rv);
1294 
1295  // Initialize the preference services.
1296  rv = PrefInitialize();
1297  NS_ENSURE_SUCCESS(rv, rv);
1298 
1299  // Initialize the device statistics services.
1300  rv = StatsInitialize();
1301  NS_ENSURE_SUCCESS(rv, rv);
1302 
1303  return NS_OK;
1304 }
1305 
1306 
1311 void
1313 {
1314  // Finalize the device statistics services.
1315  StatsFinalize();
1316 
1317  // Finalize the preference services.
1318  PrefFinalize();
1319 
1320  // Finalize the iPod mapping services.
1321  MapFinalize();
1322 
1323  // Finalize the device content.
1324  if (mDeviceContent)
1325  mDeviceContent->Finalize();
1326  mDeviceContent = nsnull;
1327 
1328  // Finalize the device properties.
1329  if (mProperties)
1330  mProperties->Finalize();
1331  mProperties = nsnull;
1332 
1333  if (mDBLock) {
1334  nsAutoMonitor::DestroyMonitor(mDBLock);
1335  mDBLock = nsnull;
1336  }
1337  // Dispose of the connect lock.
1338  if (mConnectLock)
1339  PR_DestroyRWLock(mConnectLock);
1340  mConnectLock = nsnull;
1341 
1342  // Finalize and destroy the iPod device status object.
1343  if (mIPDStatus) {
1344  mIPDStatus->Finalize();
1345  delete mIPDStatus;
1346  }
1347  mIPDStatus = nsnull;
1348 
1349  // Remove object references.
1350  mCreationProperties = nsnull;
1351  mFileProtocolHandler = nsnull;
1352  mPropertyManager = nsnull;
1353  mLibraryManager = nsnull;
1354  mSBMainLib = nsnull;
1355  mSBMainML = nsnull;
1356  mIPodEventHandler = nsnull;
1357 }
1358 
1359 
1364 nsresult
1366 {
1367  // Create and initialize the device properties.
1368  nsresult rv;
1369  mProperties = new sbIPDProperties(this);
1370  NS_ENSURE_TRUE(mProperties, NS_ERROR_OUT_OF_MEMORY);
1371  rv = mProperties->Initialize();
1372  NS_ENSURE_SUCCESS(rv, rv);
1373 
1375 }
1376 
1377 
1384 nsresult
1385 sbIPDDevice::ImportDatabase()
1386 {
1387  nsresult rv;
1388 
1389  // Mark all device library items as unavailable.
1391  (mDeviceLibrary,
1392  NS_LITERAL_STRING(SB_PROPERTY_AVAILABILITY),
1393  NS_LITERAL_STRING("0"));
1394  NS_ENSURE_SUCCESS(rv, rv);
1395 
1396  // Import all iPod database tracks.
1397  rv = ImportTracks();
1398  NS_ENSURE_SUCCESS(rv, rv);
1399 
1400  // Import all iPod database playlists.
1401  rv = ImportPlaylists();
1402  NS_ENSURE_SUCCESS(rv, rv);
1403 
1404  // Delete all remaining unavailable items.
1405  sbDeviceUtils::DeleteUnavailableItems(mDeviceLibrary);
1406 
1407  return NS_OK;
1408 }
1409 
1410 
1416 nsresult
1417 sbIPDDevice::DBFlush()
1418 {
1419  GError *gError = nsnull;
1420 
1421  // Operate under the request lock.
1422  nsAutoMonitor autoDBLock(mDBLock);
1423 
1424  // Do nothing unless database is dirty.
1425  if (!mITDBDirty)
1426  return NS_OK;
1427 
1428  // Write the iPod device database file.
1429  if (!itdb_write(mITDB, &gError)) {
1430  if (gError) {
1431  if (gError->message)
1432  FIELD_LOG(("%s", gError->message));
1433  g_error_free(gError);
1434  gError = NULL;
1435  }
1436  NS_ENSURE_TRUE(PR_FALSE, NS_ERROR_FAILURE);
1437  }
1438 
1439  // Write the iPod device Shuffle database file.
1440  //XXXeps should only do for Shuffle.
1441  if (!itdb_shuffle_write(mITDB, &gError)) {
1442  if (gError) {
1443  if (gError->message)
1444  FIELD_LOG(("%s", gError->message));
1445  g_error_free(gError);
1446  gError = NULL;
1447  }
1448  NS_ENSURE_TRUE(PR_FALSE, NS_ERROR_FAILURE);
1449  }
1450 
1451  // Database is no longer dirty.
1452  mITDBDirty = PR_FALSE;
1453 
1454  // Force updating of statistics.
1455  StatsUpdate(PR_TRUE);
1456 
1457  return NS_OK;
1458 }
1459 
1460 
1465 nsresult
1466 sbIPDDevice::CapabilitiesConnect()
1467 {
1468  nsresult rv;
1469 
1470  // Create the device capabilities object.
1471  mCapabilities = do_CreateInstance(SONGBIRD_DEVICECAPABILITIES_CONTRACTID,
1472  &rv);
1473  NS_ENSURE_SUCCESS(rv, rv);
1474  rv = mCapabilities->Init();
1475  NS_ENSURE_SUCCESS(rv, rv);
1476 
1477  // Set the device function types.
1478  PRUint32 functionTypeList[] =
1480  rv = mCapabilities->SetFunctionTypes(functionTypeList,
1481  NS_ARRAY_LENGTH(functionTypeList));
1482  NS_ENSURE_SUCCESS(rv, rv);
1483 
1484  // Set the device content types.
1485  PRUint32 contentTypeList[] = { sbIDeviceCapabilities::CONTENT_AUDIO,
1487  rv = mCapabilities->AddContentTypes
1489  contentTypeList,
1490  NS_ARRAY_LENGTH(contentTypeList));
1491  NS_ENSURE_SUCCESS(rv, rv);
1492 
1493  // Set the device formats.
1494  rv = mCapabilities->AddMimeTypes(sbIDeviceCapabilities::CONTENT_AUDIO,
1497  NS_ENSURE_SUCCESS(rv, rv);
1498 
1499  // Complete the device capabilities configuration.
1500  rv = mCapabilities->ConfigureDone();
1501  NS_ENSURE_SUCCESS(rv, rv);
1502 
1503  return NS_OK;
1504 }
1505 
1506 
1515 nsresult
1516 sbIPDDevice::GetIPodID(sbIMediaItem* aMediaItem,
1517  guint64* aIPodID)
1518 {
1519  // Validate arguments.
1520  NS_ASSERTION(aMediaItem, "aMediaItem is null");
1521  NS_ASSERTION(aIPodID, "aIPodID is null");
1522 
1523  // Function variables.
1524  guint64 iPodID;
1525  nsresult rv;
1526 
1527  // Get the iPod ID string.
1528  nsAutoString iPodIDStr;
1529  rv = aMediaItem->GetProperty
1530  (NS_LITERAL_STRING(SB_PROPERTY_DEVICE_PERSISTENT_ID),
1531  iPodIDStr);
1532  NS_ENSURE_SUCCESS(rv, rv);
1533 
1534  // Scan the iPod ID from the string.
1535  int numScanned = PR_sscanf(NS_ConvertUTF16toUTF8(iPodIDStr).get(),
1536  "%llu",
1537  &iPodID);
1538  NS_ENSURE_TRUE(numScanned, NS_ERROR_FAILURE);
1539 
1540  // Return results.
1541  *aIPodID = iPodID;
1542 
1543  return NS_OK;
1544 }
1545 
1546 
1553 nsresult
1554 sbIPDDevice::CreateDeviceID(nsID* aDeviceID)
1555 {
1556  // Validate arguments.
1557  NS_ASSERTION(aDeviceID, "aDeviceID is null");
1558 
1559  // Function variables.
1560  nsresult rv;
1561 
1562  // Get the device parameters.
1563  nsCOMPtr<nsIPropertyBag2> parameters;
1564  rv = GetParameters(getter_AddRefs(parameters));
1565  NS_ENSURE_SUCCESS(rv, rv);
1566 
1567  // Initialize the device ID with zeros.
1568  PRUint8* buffer = (PRUint8*) aDeviceID;
1569  memset(buffer, 0, sizeof(nsID));
1570 
1571  // Fill the device ID with a hash of the device manufacturer, model number,
1572  // and serial number.
1573  PRInt32 offset = 0;
1574  rv = AddNSIDHash(buffer,
1575  offset,
1576  parameters,
1577  NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MANUFACTURER));
1578  NS_WARN_IF_FALSE
1579  (NS_SUCCEEDED(rv),
1580  "Couldn't add the device manufaturer to the device ID hash.");
1581  rv = AddNSIDHash(buffer, offset, parameters,
1582  NS_LITERAL_STRING(SB_DEVICE_PROPERTY_MODEL));
1583  NS_WARN_IF_FALSE
1584  (NS_SUCCEEDED(rv),
1585  "Couldn't add the device model number to the device ID hash.");
1586  rv = AddNSIDHash(buffer, offset, parameters,
1587  NS_LITERAL_STRING(SB_DEVICE_PROPERTY_SERIAL_NUMBER));
1588  NS_WARN_IF_FALSE
1589  (NS_SUCCEEDED(rv),
1590  "Couldn't add the device serial number to the device ID hash.");
1591 
1592  return NS_OK;
1593 }
1594 
1595 
1606 nsresult
1607 sbIPDDevice::AddNSIDHash(unsigned char* aBuffer,
1608  PRInt32& aOffset,
1609  nsIPropertyBag2* aPropBag,
1610  const nsAString& aProp)
1611 {
1612  nsCString value;
1613  nsresult rv = aPropBag->GetPropertyAsACString(aProp, value);
1614  NS_ENSURE_SUCCESS(rv, rv);
1615 
1616  const nsCString::char_type *p, *end;
1617 
1618  for (value.BeginReading(&p, &end); p < end; ++p) {
1619  PRUint32 data = (*p) & 0x7F; // only look at 7 bits
1620  data <<= (aOffset / 7 + 1) % 8;
1621  PRInt32 index = (aOffset + 6) / 8;
1622  if (index > 0)
1623  aBuffer[(index - 1) % sizeof(nsID)] ^= (data & 0xFF00) >> 8;
1624  aBuffer[index % sizeof(nsID)] ^= (data & 0xFF);
1625  aOffset += 7;
1626  }
1627 
1628  return NS_OK;
1629 }
1630 
1631 
1639 PRBool
1640 sbIPDDevice::IsFileSystemSupported()
1641 {
1642  // If the device storage information is available, the file system is
1643  // supported.
1644  guint64 capacity;
1645  guint64 free;
1646  return itdb_device_get_storage_info(mITDBDevice, &capacity, &free);
1647 }
1648 
1649 
1650 // Set up the iPod if it isn't already
1651 nsresult
1652 sbIPDDevice::SetUpIfNeeded()
1653 {
1654  nsresult rv;
1655 
1656  // is the ipod already set up?
1657  PRBool isSetUp;
1658  rv = GetIsSetUp(&isSetUp);
1659  NS_ENSURE_SUCCESS(rv, rv);
1660 
1661  if (!isSetUp) {
1662  // if the device isn't set up yet, then send an event
1664  sbIPDVariant(NS_ISUPPORTS_CAST(sbIDevice*, this)).get());
1665  }
1666  return NS_OK;
1667 }
1668 
1669 
1670 
1671 NS_IMETHODIMP
1672 sbIPDDevice::GetCurrentStatus(sbIDeviceStatus * *aCurrentStatus)
1673 {
1674  NS_ENSURE_ARG(aCurrentStatus);
1675  return mIPDStatus->GetCurrentStatus(aCurrentStatus);
1676 }
1677 
1678 NS_IMETHODIMP sbIPDDevice::Format()
1679 {
1680  return NS_ERROR_NOT_IMPLEMENTED;
1681 }
1682 
1683 NS_IMETHODIMP sbIPDDevice::GetSupportsReformat(PRBool *aCanReformat) {
1684  NS_ENSURE_ARG_POINTER(aCanReformat);
1685  *aCanReformat = PR_FALSE;
1686  return NS_OK;
1687 }
1688 
1689 NS_IMETHODIMP
1691  sbILibraryChangeset* aExportChangeset)
1692 {
1693  return sbBaseDevice::ExportToDevice(aDevLibrary, aExportChangeset);
1694 }
1695 
1696 NS_IMETHODIMP
1697 sbIPDDevice::ImportFromDevice(sbILibrary * aImportToLibrary,
1698  sbILibraryChangeset * aImportChangeset)
1699 {
1700  return sbBaseDevice::ImportFromDevice(aImportToLibrary, aImportChangeset);
1701 }
1702 
static sbDeviceEvent * CreateEvent()
NS_IMETHOD GetPreference(const nsAString &aPrefName, nsIVariant **_retval)
const PRUint32 FUNCTION_AUDIO_PLAYBACK
#define IPOD_STATS_UPDATE_PERIOD
Definition: sbIPDDevice.h:211
nsresult CreateAndDispatchEvent(PRUint32 aType, nsIVariant *aData, PRBool aAsync=PR_TRUE, sbIDeviceEventTarget *aTarget=nsnull)
NS_SCRIPTABLE NS_IMETHOD ResetWarningDialogs(void)
#define SB_PRLOG_SETUP(x)
Definition: sbDebugUtils.h:115
return NS_OK
#define IPOD_LOCALE_BUNDLE_PATH
Definition: sbIPDDevice.h:210
NS_IMETHOD Format(void)
const char * sbIPDSupportedAudioMediaList[]
#define LOG(args)
[UNIMPLEMENTED UNTIL AFTER 0.3]
NS_IMETHOD GetIsDirectTranscoding(PRBool *aIsDirect)
Songbird iPod Device Utility Definitions.
static nsresult BulkSetProperty(sbIMediaList *aMediaList, const nsAString &aPropertyId, const nsAString &aPropertyValue, sbIPropertyArray *aPropertyFilter=nsnull, PRInt32 *aAbortFlag=nsnull)
virtual nsresult InitializeProperties()
NS_IMETHOD GetPrimaryLibrary(sbIDeviceLibrary **aPrimaryLibrary)
nsresult Init()
NS_IMETHOD GetPreviousState(PRUint32 *aState)
NS_SCRIPTABLE NS_IMETHOD SetWarningDialogEnabled(const nsAString &aWarning, PRBool aEnabled)
NS_IMPL_QUERY_INTERFACE2_CI(sbCDDeviceMarshall, sbIDeviceMarshall, sbICDDeviceListener) NS_IMPL_CI_INTERFACE_GETTER2(sbCDDeviceMarshall
NS_SCRIPTABLE NS_IMETHOD OpenInputStream(nsIURI *aURI, nsIInputStream **retval)
nsresult GetCurrentStatus(sbIDeviceStatus **aCurrentStatus)
NS_SCRIPTABLE NS_IMETHOD GetWarningDialogEnabled(const nsAString &aWarning, PRBool *_retval)
var event
void eject()
const NS_ERROR_ABORT
virtual nsresult DeviceSpecificDisconnect()
#define SB_PROPERTY_HIDDEN
PRUint32 sbIPDSupportedMediaListLength
NS_IMPL_THREADSAFE_CI(sbMediaListEnumeratorWrapper)
#define SB_PROPERTY_DEVICE_PERSISTENT_ID
Base iPod device event interface.
NS_IMETHOD SyncLibraries(void)
#define SB_DEVICE_PROPERTY_MANUFACTURER
[UNIMPLEMENTED UNTIL AFTER 0.3]
NS_DECL_ISUPPORTS NS_DECL_SBIDEVICE NS_DECL_NSICLASSINFO sbIPDDevice(const nsID &aControllerID, nsIPropertyBag *aProperties)
NS_IMETHOD Connect()
friend class sbIPDLibrary
Definition: sbIPDDevice.h:261
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
NS_IMETHOD GetState(PRUint32 *aState)
nsresult PushRequest(const PRUint32 aType, sbIMediaItem *aItem=nsnull, sbIMediaList *aList=nsnull, PRUint32 aIndex=PR_UINT32_MAX, PRUint32 aOtherIndex=PR_UINT32_MAX, nsISupports *aData=nsnull)
readonly attribute nsIPropertyBag2 parameters
Definition: sbIDevice.idl:163
#define SONGBIRD_DEVICECAPABILITIES_CONTRACTID
PRUint32 & offset
nsresult ReqProcessingStart()
NS_IMETHOD SupportsMediaItem(sbIMediaItem *aMediaItem, sbIDeviceSupportsItemCallback *aCallback)
void Finalize()
NS_IMETHOD Eject(void)
NS_DECL_ISUPPORTS static NS_DECL_SBIDEVICECONTENT sbDeviceContent * New()
virtual ~sbIPDDevice()
NS_IMETHOD GetDefaultLibrary(sbIDeviceLibrary **aDefaultLibrary)
readonly attribute AString name
Definition: sbIDevice.idl:85
Songbird iPod Device Definitions.
virtual nsresult InitializeProperties()
nsresult PromptForEjectDuringPlayback(PRBool *aEject)
_updateTextAndScrollDataForFrame aContent
Songbird iPod Device FairPlay Event Definitions.
const unsigned long EVENT_IPOD_NOT_INITIALIZED
#define FIELD_LOG(args)
Definition: sbIPDLog.h:126
const unsigned long STATUS_UNKNOWN
NS_IMETHOD Disconnect()
Songbird iPod Device Logging Definitions.
NS_IMETHOD CancelRequests()
Media library abstraction.
Definition: sbILibrary.idl:82
attribute unsigned long state
Definition: sbIDevice.idl:217
NS_IMETHOD GetIsBusy(PRBool *aIsBusy)
NS_IMETHOD ExportToDevice(sbIDeviceLibrary *aDevLibrary, sbILibraryChangeset *aChangeset)
readonly attribute sbIDeviceProperties properties
Definition: sbIDevice.idl:168
nsresult RemoveLibrary(sbIDeviceLibrary *aDevLib)
const unsigned long EVENT_IPOD_HFSPLUS_READ_ONLY
friend class sbIPDProperties
Definition: sbIPDDevice.h:263
NS_IMETHOD GetSupportsReformat(PRBool *_retval)
_updateCookies aName
const unsigned long STATUS_STOPPED
countRef value
Definition: FeedWriter.js:1423
sbIJobCancelable NS_DECL_CLASSINFO(sbGstreamerMediaInspector)
NS_IMETHOD SubmitRequest(PRUint32 aRequest, nsIPropertyBag2 *aRequestParameters)
NS_IMETHOD GetCanDisconnect(PRBool *aCanDisconnect)
const char * sbIPDSupportedMediaList[]
Definition: sbIPDDevice.cpp:93
#define SB_DEVICE_PROPERTY_SERIAL_NUMBER
if(DEBUG_DATAREMOTES)
#define SB_MEDIACOREMANAGER_CONTRACTID
const unsigned long EVENT_IPOD_UNSUPPORTED_FILE_SYSTEM
Interface that defines a single item of media in the system.
nsresult Initialize()
#define SB_PROPERTY_AVAILABILITY
NS_IMPL_CI_INTERFACE_GETTER2(sbDataRemoteWrapper, sbIDataRemote, nsIClassInfo) sbDataRemoteWrapper
nsresult InitializeDeviceLibrary(sbDeviceLibrary *aDevLib, const nsAString &aId, nsIURI *aLibraryLocation)
NS_IMETHOD ImportFromDevice(sbILibrary *aImportToLibrary, sbILibraryChangeset *aImportChangeset)
#define SB_DEVICE_PROPERTY_MODEL
static nsresult DeleteUnavailableItems(sbIMediaList *aMediaList)
restoreWindow aState
NS_IMETHOD SetState(PRUint32 aState)
observe data
Definition: FeedWriter.js:1329
readonly attribute AString productName
Definition: sbIDevice.idl:91
NS_IMETHOD SetPreference(const nsAString &aPrefName, nsIVariant *aPrefValue)
void FinalizeDeviceLibrary(sbIDeviceLibrary *aDevLib)
NS_IMETHOD SetDefaultLibrary(sbIDeviceLibrary *aDefaultLibrary)
PRUint32 sbIPDSupportedAudioMediaListLength
nsresult Initialize()
#define SB_SYNC_PARTNER_PREF
Definition: sbBaseDevice.h:87
nsresult AddLibrary(sbIDeviceLibrary *aDevLib)