sbIPDPlaylist.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 //------------------------------------------------------------------------------
27 //
28 // iPod device playlist services.
29 //
30 // These services may only be used within both the connect and request locks.
31 //
32 //------------------------------------------------------------------------------
33 
39 //------------------------------------------------------------------------------
40 //
41 // iPod device playlist imported services.
42 //
43 //------------------------------------------------------------------------------
44 
45 // Local imports.
46 #include "sbIPDDevice.h"
47 #include "sbIPDLog.h"
48 #include "sbIPDUtils.h"
49 
50 // Songbird imports.
51 #include <sbDeviceUtils.h>
53 #include <sbStringUtils.h>
54 
55 /* Mozilla imports. */
56 #include <nsComponentManagerUtils.h>
57 #include <nsISimpleEnumerator.h>
58 
59 
60 //------------------------------------------------------------------------------
61 //
62 // iPod device playlist import services.
63 //
64 //------------------------------------------------------------------------------
65 
70 nsresult
71 sbIPDDevice::ImportPlaylists()
72 {
73  // Import all of the playlists, skipping the master plalist.
74  GList* playlistList = mITDB->playlists;
75  while (playlistList) {
76  // Check for abort.
77  NS_ENSURE_FALSE(IsRequestAborted(), NS_ERROR_ABORT);
78 
79  // Get the playlist.
80  Itdb_Playlist* playlist = (Itdb_Playlist *) playlistList->data;
81  playlistList = playlistList->next;
82 
83  // Do nothing with the master playlist.
84  if (itdb_playlist_is_mpl(playlist))
85  continue;
86 
87  // Import the playlist.
88  ImportPlaylist(playlist);
89  }
90 
91  return NS_OK;
92 }
93 
94 
102 nsresult
103 sbIPDDevice::ImportPlaylist(Itdb_Playlist* aPlaylist)
104 {
105  // Validate arguments.
106  NS_ASSERTION(aPlaylist, "aPlaylist is null");
107 
108  // Import the playlist into the device Songbird library.
109  return ImportPlaylist(mDeviceLibrary, aPlaylist);
110 }
111 
112 
123 nsresult
124 sbIPDDevice::ImportPlaylist(sbILibrary* aLibrary,
125  Itdb_Playlist* aPlaylist,
126  sbIMediaList** aMediaList)
127 {
128  // Validate arguments.
129  NS_ASSERTION(aLibrary, "aLibrary is null");
130  NS_ASSERTION(aPlaylist, "aPlaylist is null");
131 
132  // Function variables.
133  nsCOMPtr<sbIMediaList> mediaList;
134  nsresult rv;
135 
136  // Log progress.
137  FIELD_LOG(("Importing playlist %s\n", aPlaylist->name));
138 
139  // Check if importing into the device library.
140  PRBool inDeviceLibrary;
141  rv = aLibrary->Equals(mDeviceLibrary, &inDeviceLibrary);
142  NS_ENSURE_SUCCESS(rv, rv);
143 
144  // Ignore library and media list changes for device libraries and set up to
145  // automatically stop ignoring.
146  sbIPDAutoStopIgnoreLibrary autoStopIgnoreLibrary;
147  sbIPDAutoStopIgnoreMediaLists autoStopIgnoreMediaLists;
148  if (inDeviceLibrary) {
149  mLibraryListener->SetIgnoreListener(PR_TRUE);
150  autoStopIgnoreLibrary.Set(mLibraryListener);
152  autoStopIgnoreMediaLists.Set(this);
153  }
154 
155  // If importing into the device library, check if playlist media list already
156  // exists. Clear it out and import into it if so.
157  if (inDeviceLibrary) {
158  nsCOMPtr<sbIMediaItem> mediaItem;
160  (aLibrary,
161  sbAutoString(aPlaylist->id),
162  getter_AddRefs(mediaItem));
163  if (NS_SUCCEEDED(rv)) {
164  mediaList = do_QueryInterface(mediaItem, &rv);
165  NS_ENSURE_SUCCESS(rv, rv);
166  rv = mediaList->Clear();
167  NS_ENSURE_SUCCESS(rv, rv);
168  } else {
169  NS_ENSURE_TRUE(rv == NS_ERROR_NOT_AVAILABLE, rv);
170  }
171  }
172 
173  // Create a new media list if needed.
174  if (!mediaList) {
175  rv = aLibrary->CreateMediaList(NS_LITERAL_STRING("simple"),
176  nsnull,
177  getter_AddRefs(mediaList));
178  NS_ENSURE_SUCCESS(rv, rv);
179  }
180 
181  // Set the media list name.
182  nsAutoString playlistName;
183  playlistName.Assign(NS_ConvertUTF8toUTF16(aPlaylist->name));
184  rv = mediaList->SetName(playlistName);
185  NS_ENSURE_SUCCESS(rv, rv);
186 
187  // Set the device persistent ID and availability if importing into the device
188  // library.
189  if (inDeviceLibrary) {
190  rv = mediaList->SetProperty
191  (NS_LITERAL_STRING(SB_PROPERTY_DEVICE_PERSISTENT_ID),
192  sbAutoString(aPlaylist->id));
193  NS_ENSURE_SUCCESS(rv, rv);
194  rv = mediaList->SetProperty
195  (NS_LITERAL_STRING(SB_PROPERTY_AVAILABILITY),
196  NS_LITERAL_STRING("1"));
197  NS_ENSURE_SUCCESS(rv, rv);
198  }
199 
200  // Stop ignoring library and media list changes for device libraries.
201  if (inDeviceLibrary) {
202  mLibraryListener->SetIgnoreListener(PR_FALSE);
203  autoStopIgnoreLibrary.forget();
204  SetIgnoreMediaListListeners(PR_FALSE);
205  autoStopIgnoreMediaLists.forget();
206  }
207 
208  // Add the playlist tracks to the media list.
209  rv = ImportPlaylistTracks(aPlaylist, mediaList);
210  NS_ENSURE_SUCCESS(rv, rv);
211 
212  // Return imported media list.
213  if (aMediaList)
214  NS_ADDREF(*aMediaList = mediaList);
215 
216  return NS_OK;
217 }
218 
219 
228 nsresult
229 sbIPDDevice::ImportPlaylistTracks(Itdb_Playlist* aPlaylist,
230  sbIMediaList* aMediaList)
231 {
232  // Validate arguments.
233  NS_ASSERTION(aPlaylist, "aPlaylist is null");
234  NS_ASSERTION(aMediaList, "aMediaList is null");
235 
236  // Allocate the track batch and set it up for auto-disposal.
237  Itdb_Track** trackBatch =
238  static_cast<Itdb_Track**>
239  (NS_Alloc(TrackBatchSize * sizeof (Itdb_Track *)));
240  NS_ENSURE_TRUE(trackBatch, NS_ERROR_OUT_OF_MEMORY);
241  sbAutoNSMemPtr autoTrackBatch(trackBatch);
242 
243  // Import all of the playlist tracks.
244  int trackCount = itdb_playlist_tracks_number(aPlaylist);
245  GList* trackList = aPlaylist->members;
246  PRUint32 trackNum = 0;
247  PRUint32 batchCount = 0;
248  while (trackList) {
249  // Check for abort.
250  NS_ENSURE_FALSE(IsRequestAborted(), NS_ERROR_ABORT);
251 
252  // Get the track.
253  Itdb_Track* track = (Itdb_Track *) trackList->data;
254  trackList = trackList->next;
255 
256  // Update status.
257  mIPDStatus->ItemStart(aPlaylist, track, trackNum, trackCount);
258 
259  // Add the track to the batch.
260  trackBatch[batchCount] = track;
261  batchCount++;
262 
263  // Import the track batch.
264  if ((batchCount >= TrackBatchSize) || (!trackList)) {
265  ImportPlaylistTrackBatch(aMediaList, trackBatch, batchCount);
266  batchCount = 0;
267  }
268 
269  // Import next track.
270  trackNum++;
271  }
272 
273  return NS_OK;
274 }
275 
276 
286 nsresult
287 sbIPDDevice::ImportPlaylistTrackBatch(sbIMediaList* aMediaList,
288  Itdb_Track** aTrackBatch,
289  PRUint32 aBatchCount)
290 {
291  // Validate arguments.
292  NS_ASSERTION(aMediaList, "aMediaList is null");
293  NS_ASSERTION(aTrackBatch, "aTrackBatch is null");
294 
295  // Function variables.
296  nsresult rv;
297 
298  // Get the target library and check if it's the device library.
299  nsCOMPtr<sbILibrary> tgtLibrary;
300  PRBool inDeviceLibrary;
301  rv = aMediaList->GetLibrary(getter_AddRefs(tgtLibrary));
302  NS_ENSURE_SUCCESS(rv, rv);
303  rv = tgtLibrary->Equals(mDeviceLibrary, &inDeviceLibrary);
304  NS_ENSURE_SUCCESS(rv, rv);
305 
306  // Ignore library and media list changes for device libraries and set up to
307  // automatically stop ignoring.
308  sbIPDAutoStopIgnoreLibrary autoStopIgnoreLibrary;
309  sbIPDAutoStopIgnoreMediaLists autoStopIgnoreMediaLists;
310  if (inDeviceLibrary) {
311  mLibraryListener->SetIgnoreListener(PR_TRUE);
312  autoStopIgnoreLibrary.Set(mLibraryListener);
314  autoStopIgnoreMediaLists.Set(this);
315  }
316 
317  // Create the track media item array.
318  nsCOMPtr<nsIMutableArray> trackMediaItemArray =
319  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
320  NS_ENSURE_SUCCESS(rv, rv);
321 
322  // Get the track media items.
323  for (PRUint32 i = 0; i < aBatchCount; i++) {
324  // Get the track media item. Skip track on failure.
325  Itdb_Track* track = aTrackBatch[i];
326  nsCOMPtr<sbIMediaItem> mediaItem;
327  if (inDeviceLibrary) {
329  (mDeviceLibrary,
330  sbAutoString(track->dbid),
331  getter_AddRefs(mediaItem));
332  } else {
334  (mDeviceLibrary,
335  sbAutoString(track->dbid),
336  getter_AddRefs(mediaItem));
337  }
338  if (NS_SUCCEEDED(rv))
339  trackMediaItemArray->AppendElement(mediaItem, PR_FALSE);
340  }
341  nsCOMPtr<nsISimpleEnumerator> trackMediaItemEnum;
342  rv = trackMediaItemArray->Enumerate(getter_AddRefs(trackMediaItemEnum));
343  NS_ENSURE_SUCCESS(rv, rv);
344 
345  // Add the track media items.
346  rv = aMediaList->AddSome(trackMediaItemEnum);
347  NS_ENSURE_SUCCESS(rv, rv);
348 
349  return NS_OK;
350 }
351 
352 
353 //------------------------------------------------------------------------------
354 //
355 // iPod device playlist manipulation services.
356 //
357 //------------------------------------------------------------------------------
358 
367 nsresult
368 sbIPDDevice::PlaylistAdd(sbIMediaList* aMediaList,
369  Itdb_Playlist** aPlaylist)
370 {
371  //XXXeps add support for adding from non-dev playlist.
372  // Validate arguments.
373  NS_ASSERTION(aMediaList, "aMediaList is null");
374  NS_ASSERTION(aPlaylist, "aPlaylist is null");
375 
376  // Function variables.
377  nsresult rv;
378 
379  // Get the playlist name.
380  nsAutoString playlistName;
381  rv = aMediaList->GetName(playlistName);
382  NS_ENSURE_SUCCESS(rv, rv);
383 
384  // Create the iPod playlist and add it to the iPod database.
385  Itdb_Playlist* playlist = itdb_playlist_new
386  (NS_ConvertUTF16toUTF8(playlistName).get(),
387  FALSE);
388  NS_ENSURE_TRUE(playlist, NS_ERROR_OUT_OF_MEMORY);
389  itdb_playlist_add(mITDB, playlist, -1);
390 
391  // Set the media list device persistent ID to the new playlist ID.
392  mLibraryListener->IgnoreMediaItem(aMediaList);
393  rv = aMediaList->SetProperty
394  (NS_LITERAL_STRING(SB_PROPERTY_DEVICE_PERSISTENT_ID),
395  sbAutoString(playlist->id));
396  mLibraryListener->UnignoreMediaItem(aMediaList);
397  NS_ENSURE_SUCCESS(rv, rv);
398 
399  // Mark the iPod database as dirty.
400  mITDBDirty = PR_TRUE;
401 
402  // Return results.
403  *aPlaylist = playlist;
404 
405  return NS_OK;
406 }
407 
408 
414 nsresult
415 sbIPDDevice::PlaylistDelete(sbIMediaList* aMediaList)
416 {
417  // Validate arguments.
418  NS_ASSERTION(aMediaList, "aMediaList is null");
419 
420  // Function variables.
421  nsresult rv;
422 
423  // Get the iPod playlist to delete.
424  Itdb_Playlist* playlist;
425  rv = GetPlaylist(aMediaList, &playlist);
426  NS_ENSURE_SUCCESS(rv, rv);
427 
428  // Remove playlist from the iPod.
429  itdb_playlist_remove(playlist);
430 
431  // Mark the iPod database as dirty.
432  mITDBDirty = PR_TRUE;
433 
434  return NS_OK;
435 }
436 
437 
447 nsresult
448 sbIPDDevice::PlaylistUpdateProperties(sbIMediaList* aMediaList,
449  Itdb_Playlist* aPlaylist)
450 {
451  // Validate arguments.
452  NS_ASSERTION(aMediaList, "aMediaList is null");
453 
454  // Function variables.
455  nsresult rv;
456 
457  // Get the iPod playlist.
458  Itdb_Playlist* playlist = aPlaylist;
459  if (!playlist) {
460  rv = GetPlaylist(aMediaList, &playlist);
461  NS_ENSURE_SUCCESS(rv, rv);
462  }
463 
464  // Get the playlist name and arrange for auto-cleanup.
465  nsAutoString nsPlaylistName;
466  gchar* cPlaylistName;
467  rv = aMediaList->GetName(nsPlaylistName);
468  NS_ENSURE_SUCCESS(rv, rv);
469  cPlaylistName = g_strdup(NS_ConvertUTF16toUTF8(nsPlaylistName).get());
470  NS_ENSURE_TRUE(cPlaylistName, NS_ERROR_OUT_OF_MEMORY);
471  sbAutoGMemPtr autoCPlaylistName(cPlaylistName);
472 
473  // Update the playlist name if it's changed.
474  if (strcmp(cPlaylistName, playlist->name)) {
475  if (playlist->name)
476  g_free(playlist->name);
477  playlist->name = cPlaylistName;
478  autoCPlaylistName.forget();
479  }
480 
481  // Mark the iPod database as dirty.
482  mITDBDirty = PR_TRUE;
483 
484  return NS_OK;
485 }
486 
487 
500 nsresult
501 sbIPDDevice::PlaylistAddTrack(sbIMediaList* aMediaList,
502  sbIMediaItem* aMediaItem,
503  PRUint32 aIndex)
504 {
505  // Validate arguments.
506  NS_ASSERTION(aMediaList, "aMediaList is null");
507  NS_ASSERTION(aMediaItem, "aMediaItem is null");
508 
509  // Function variables.
510  nsresult rv;
511 
512  // Get the target iPod playlist.
513  Itdb_Playlist* playlist;
514  rv = GetPlaylist(aMediaList, &playlist);
515  NS_ENSURE_SUCCESS(rv, rv);
516 
517  // Get the target iPod track.
518  Itdb_Track* track;
519  rv = GetTrack(aMediaItem, &track);
520  NS_ENSURE_SUCCESS(rv, rv);
521 
522  // Add the track to the playlist.
523  itdb_playlist_add_track(playlist, track, aIndex);
524 
525  // Mark the iPod database as dirty.
526  mITDBDirty = PR_TRUE;
527 
528  return NS_OK;
529 }
530 
531 
544 nsresult
545 sbIPDDevice::PlaylistRemoveTrack(sbIMediaList* aMediaList,
546  sbIMediaItem* aMediaItem,
547  PRUint32 aIndex)
548 {
549  // Validate arguments.
550  NS_ASSERTION(aMediaList, "aMediaList is null");
551  NS_ASSERTION(aMediaItem, "aMediaItem is null");
552 
553  // Function variables.
554  nsresult rv;
555 
556  // Get the target iPod playlist.
557  Itdb_Playlist* playlist;
558  rv = GetPlaylist(aMediaList, &playlist);
559  NS_ENSURE_SUCCESS(rv, rv);
560 
561  // Remove the track from the playlist.
562  //XXXeps libgpod does not provide a direct interface for doing this.
563  GList* members = playlist->members;
564  GList* trackMember = g_list_nth(members, aIndex);
565  NS_ENSURE_TRUE(trackMember, NS_ERROR_INVALID_ARG);
566  playlist->members = g_list_delete_link(members, trackMember);
567 
568  // Mark the iPod database as dirty.
569  mITDBDirty = PR_TRUE;
570 
571  return NS_OK;
572 }
573 
578 nsresult
579 sbIPDDevice::PlaylistWipe(sbIMediaList * aMediaList) {
580  // Get the target iPod playlist.
581  Itdb_Playlist* playlist;
582  nsresult rv = GetPlaylist(aMediaList, &playlist);
583  NS_ENSURE_SUCCESS(rv, rv);
584 
585  // Set the members to an empty list and free the old one
586  GList* members = playlist->members;
587  playlist->members = g_list_alloc();
588  g_list_free(members);
589 
590  // Mark the iPod database as dirty.
591  mITDBDirty = PR_TRUE;
592 
593  return NS_OK;
594 }
595 
608 nsresult
609 sbIPDDevice::PlaylistMoveTrack(sbIMediaList* aMediaList,
610  PRUint32 aIndexFrom,
611  PRUint32 aIndexTo)
612 {
613  // Validate arguments.
614  NS_ASSERTION(aMediaList, "aMediaList is null");
615 
616  // Function variables.
617  nsresult rv;
618 
619  // Get the target iPod playlist.
620  Itdb_Playlist* playlist;
621  rv = GetPlaylist(aMediaList, &playlist);
622  NS_ENSURE_SUCCESS(rv, rv);
623 
624  // Get the target iPod track.
625  GList* members = playlist->members;
626  GList* trackMember = g_list_nth(members, aIndexFrom);
627  NS_ENSURE_TRUE(trackMember, NS_ERROR_INVALID_ARG);
628  Itdb_Track* track = (Itdb_Track *) trackMember->data;
629 
630  // Remove the track from the current index in the playlist.
631  //XXXeps libgpod does not provide a direct interface for doing this.
632  playlist->members = g_list_delete_link(members, trackMember);
633 
634  // Add the track to the new index in the playlist.
635  itdb_playlist_add_track(playlist, track, aIndexTo);
636 
637  // Mark the iPod database as dirty.
638  mITDBDirty = PR_TRUE;
639 
640  return NS_OK;
641 }
642 
643 
644 //------------------------------------------------------------------------------
645 //
646 // iPod device on-the-go playlist services.
647 //
648 //------------------------------------------------------------------------------
649 
655 nsresult
656 sbIPDDevice::ProcessOTGPlaylists()
657 {
658  nsresult rv;
659 
660  // Check for on-the-go playlists and process them.
661  PRBool otgPlaylistsPresent = PR_FALSE;
662  PRUint32 otgPlaylistIndex = 1;
663  GList* playlistList = mITDB->playlists;
664  while (playlistList) {
665  // Check for abort.
666  NS_ENSURE_FALSE(IsRequestAborted(), NS_ERROR_ABORT);
667 
668  // Get the playlist.
669  Itdb_Playlist* playlist = (Itdb_Playlist *) playlistList->data;
670  playlistList = playlistList->next;
671 
672  // If the playlist is an on-the-go playlist, set its name. Remove
673  // playlist on failure. Increment the playlist index regardless to
674  // match index shown on iPod.
675  if (playlist->is_otg) {
676  // Set the playlist name. Remove it on failure.
677  otgPlaylistsPresent = PR_TRUE;
678  rv = SetOTGPlaylistName(playlist, otgPlaylistIndex);
679  if (NS_FAILED(rv))
680  itdb_playlist_remove(playlist);
681  otgPlaylistIndex++;
682 
683  // Mark the iPod database as dirty.
684  mITDBDirty = PR_TRUE;
685  }
686  }
687 
688  return NS_OK;
689 }
690 
691 
700 nsresult
701 sbIPDDevice::SetOTGPlaylistName(Itdb_Playlist* aPlaylist,
702  PRUint32 aPlaylistIndex)
703 {
704  // Validate arguments.
705  NS_ASSERTION(aPlaylist, "aPlaylist is null");
706 
707  // Function variables.
708  nsresult rv;
709 
710  // Produce the playlist name.
711  nsAutoString playlistName;
712  sbAutoString playlistIndex(aPlaylistIndex);
713  const PRUnichar *stringList[1] = { playlistIndex.get() };
714  rv = mLocale->FormatStringFromName
715  (NS_LITERAL_STRING("on_the_go.playlist_name").get(),
716  stringList,
717  1,
718  getter_Copies(playlistName));
719  NS_ENSURE_SUCCESS(rv, rv);
720 
721  // Set the playlist name.
722  gchar *cPlaylistName = g_strdup(NS_ConvertUTF16toUTF8(playlistName).get());
723  NS_ENSURE_TRUE(cPlaylistName, NS_ERROR_OUT_OF_MEMORY);
724  if (aPlaylist->name)
725  g_free(aPlaylist->name);
726  aPlaylist->name = cPlaylistName;
727 
728  // Mark the iPod database as dirty.
729  mITDBDirty = PR_TRUE;
730 
731  return NS_OK;
732 }
733 
734 
735 //------------------------------------------------------------------------------
736 //
737 // iPod device playlist services.
738 //
739 //------------------------------------------------------------------------------
740 
749 nsresult
750 sbIPDDevice::GetPlaylist(sbIMediaItem* aMediaItem,
751  Itdb_Playlist** aPlaylist)
752 {
753  // Validate arguments.
754  NS_ASSERTION(aMediaItem, "aMediaItem is null");
755  NS_ASSERTION(aPlaylist, "aPlaylist is null");
756 
757  // Function variables.
758  Itdb_Playlist* playlist;
759  nsresult rv;
760 
761  // Get the iPod ID.
762  guint64 iPodID;
763  rv = GetIPodID(aMediaItem, &iPodID);
764  NS_ENSURE_SUCCESS(rv, rv);
765 
766  // Get the playlist.
767  playlist = itdb_playlist_by_id(mITDB, iPodID);
768  NS_ENSURE_TRUE(playlist, NS_ERROR_NOT_AVAILABLE);
769 
770  // Return results.
771  *aPlaylist = playlist;
772 
773  return NS_OK;
774 }
775 
static nsresult GetOriginMediaItemByDevicePersistentId(sbILibrary *aLibrary, const nsAString &aDevicePersistentId, sbIMediaItem **aItem)
return NS_OK
Songbird iPod Device Utility Definitions.
void ItemStart(PRInt32 aItemNum=-1, PRInt32 aItemCount=-1)
const NS_ERROR_ABORT
#define SB_PROPERTY_DEVICE_PERSISTENT_ID
nsRefPtr< sbBaseDeviceLibraryListener > mLibraryListener
Definition: sbBaseDevice.h:693
A brief description of the contents of this interface.
virtual PRBool IsRequestAborted()
Songbird iPod Device Definitions.
#define FIELD_LOG(args)
Definition: sbIPDLog.h:126
Songbird iPod Device Logging Definitions.
Media library abstraction.
Definition: sbILibrary.idl:82
nsresult SetIgnoreMediaListListeners(PRBool aIgnoreListener)
static nsresult GetMediaItemByDevicePersistentId(sbILibrary *aLibrary, const nsAString &aDevicePersistentId, sbIMediaItem **aItem)
if(DEBUG_DATAREMOTES)
Interface that defines a single item of media in the system.
#define SB_PROPERTY_AVAILABILITY
_getSelectedPageStyle s i