sbMediaItemWatcher.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 //
5 // BEGIN SONGBIRD GPL
6 //
7 // This file is part of the Songbird web player.
8 //
9 // Copyright(c) 2005-2008 POTI, Inc.
10 // http://songbirdnest.com
11 //
12 // This file may be licensed under the terms of of the
13 // GNU General Public License Version 2 (the "GPL").
14 //
15 // Software distributed under the License is distributed
16 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
17 // express or implied. See the GPL for the specific language
18 // governing rights and limitations.
19 //
20 // You should have received a copy of the GPL along with this
21 // program. If not, go to http://www.gnu.org/licenses/gpl.html
22 // or write to the Free Software Foundation, Inc.,
23 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 //
25 // END SONGBIRD GPL
26 //
27 */
28 
29 //------------------------------------------------------------------------------
30 //------------------------------------------------------------------------------
31 //
32 // Media item watcher.
33 //
34 //------------------------------------------------------------------------------
35 //------------------------------------------------------------------------------
36 
42 //------------------------------------------------------------------------------
43 //
44 // Media item watcher imported services.
45 //
46 //------------------------------------------------------------------------------
47 
48 // Self imports.
49 #include "sbMediaItemWatcher.h"
50 
51 // Songbird imports.
52 #include <sbILibrary.h>
53 #include <sbIPropertyArray.h>
54 
55 #include <sbStandardProperties.h>
56 
57 #include <sbDebugUtils.h>
58 
59 
60 //------------------------------------------------------------------------------
61 //
62 // nsISupports implementation.
63 //
64 //------------------------------------------------------------------------------
65 
69 
70 
71 //------------------------------------------------------------------------------
72 //
73 // sbIMediaItemWatcher implementation.
74 //
75 //------------------------------------------------------------------------------
76 
77 
89 NS_IMETHODIMP
90 sbMediaItemWatcher::Watch(sbIMediaItem* aMediaItem,
91  sbIMediaItemListener* aListener,
92  sbIPropertyArray* aPropertyIDs)
93 {
94  TRACE_FUNCTION("");
95  // Validate arguments.
96  NS_ENSURE_ARG_POINTER(aMediaItem);
97  NS_ENSURE_ARG_POINTER(aListener);
98 
99  // Function variables.
100  nsresult rv;
101 
102  // Set the watched media item and its listener.
103  mWatchedMediaItem = aMediaItem;
104  mListener = aListener;
105  mWatchedPropertyIDs = aPropertyIDs;
106 
107  // Get the watched media item library as an sbIMediaList.
108  nsCOMPtr<sbILibrary> library;
109  rv = mWatchedMediaItem->GetLibrary(getter_AddRefs(library));
110  NS_ENSURE_SUCCESS(rv, rv);
111  mWatchedLibraryML = do_QueryInterface(library, &rv);
112  NS_ENSURE_SUCCESS(rv, rv);
113 
114  // Listen to media item related events in its library.
115  rv = mWatchedLibraryML->AddListener
116  (this,
117  PR_FALSE,
122  mWatchedPropertyIDs);
123  NS_ENSURE_SUCCESS(rv, rv);
124 
125  // Get the watched media item properties.
126  rv = GetWatchedMediaItemProperties(mWatchedMediaItemProperties);
127  NS_ENSURE_SUCCESS(rv, rv);
128 
129  return NS_OK;
130 }
131 
132 
137 NS_IMETHODIMP
138 sbMediaItemWatcher::Cancel()
139 {
140  TRACE_FUNCTION("mBatchLevel=%i", mBatchLevel);
141  NS_WARN_IF_FALSE(mBatchLevel > 0,
142  "sbMediaItemWatcher::Cancel called during a batch");
143  // Stop listening to library.
144  if (mWatchedLibraryML)
145  mWatchedLibraryML->RemoveListener(this);
146 
147  // Clear object references.
148  mWatchedMediaItem = nsnull;
149  mListener = nsnull;
150  mWatchedPropertyIDs = nsnull;
151  mWatchedLibraryML = nsnull;
152 
153  return NS_OK;
154 }
155 
156 
157 //------------------------------------------------------------------------------
158 //
159 // sbIMediaListListener implementation.
160 //
161 //------------------------------------------------------------------------------
162 
173 NS_IMETHODIMP
174 sbMediaItemWatcher::OnItemAdded(sbIMediaList* aMediaList,
175  sbIMediaItem* aMediaItem,
176  PRUint32 aIndex,
177  PRBool* _retval)
178 {
179  TRACE_FUNCTION("");
180  NS_ENSURE_ARG_POINTER(_retval);
181  *_retval = PR_TRUE;
182  return NS_OK;
183 }
184 
185 
196 NS_IMETHODIMP
197 sbMediaItemWatcher::OnBeforeItemRemoved(sbIMediaList* aMediaList,
198  sbIMediaItem* aMediaItem,
199  PRUint32 aIndex,
200  PRBool* _retval)
201 {
202  TRACE_FUNCTION("");
203  NS_ENSURE_ARG_POINTER(_retval);
204  *_retval = PR_TRUE;
205  return NS_OK;
206 }
207 
208 
219 NS_IMETHODIMP
220 sbMediaItemWatcher::OnAfterItemRemoved(sbIMediaList* aMediaList,
221  sbIMediaItem* aMediaItem,
222  PRUint32 aIndex,
223  PRBool* _retval)
224 {
225  TRACE_FUNCTION("");
226  // Validate arguments.
227  NS_ENSURE_ARG_POINTER(aMediaItem);
228  NS_ENSURE_ARG_POINTER(_retval);
229 
230  // Do nothing if in a batch.
231  if (mBatchLevel > 0) {
232  *_retval = PR_TRUE;
233  return NS_OK;
234  }
235 
236  // Handle item removed events.
237  if (aMediaItem == mWatchedMediaItem)
238  mListener->OnItemRemoved(mWatchedMediaItem);
239 
240  // Keep calling.
241  *_retval = PR_FALSE;
242 
243  return NS_OK;
244 }
245 
246 
258 NS_IMETHODIMP
259 sbMediaItemWatcher::OnItemUpdated(sbIMediaList* aMediaList,
260  sbIMediaItem* aMediaItem,
261  sbIPropertyArray* aProperties,
262  PRBool* _retval)
263 {
264  TRACE_FUNCTION("");
265  // Validate arguments.
266  NS_ENSURE_ARG_POINTER(aMediaItem);
267  NS_ENSURE_ARG_POINTER(_retval);
268 
269  // Function variables.
270  nsresult rv;
271 
272  #if PR_LOGGING
273  {
274  nsString props, src;
275  rv = aProperties->ToString(props);
276  if (NS_FAILED(rv)) props.AssignLiteral("<ERROR>");
277  rv = aMediaItem->GetProperty(NS_LITERAL_STRING(SB_PROPERTY_CONTENTURL),
278  src);
279  if (NS_FAILED(rv)) src.AssignLiteral("<ERROR>");
280  TRACE("item %s updated: %s",
281  NS_ConvertUTF16toUTF8(src).get(),
282  NS_ConvertUTF16toUTF8(props).get());
283  }
284  #endif /* PR_LOGGING */
285 
286  // Do nothing if in a batch.
287  if (mBatchLevel > 0) {
288  TRACE("In a batch, skipping");
289  *_retval = PR_TRUE;
290  return NS_OK;
291  }
292 
293  // Handle item updated events.
294  if (aMediaItem == mWatchedMediaItem) {
295  rv = DoItemUpdated();
296  TRACE("called: %08x", rv);
297  NS_ENSURE_SUCCESS(rv, rv);
298  }
299 
300  // Keep calling.
301  *_retval = PR_FALSE;
302 
303  return NS_OK;
304 }
305 
306 
317 NS_IMETHODIMP
318 sbMediaItemWatcher::OnItemMoved(sbIMediaList* aMediaList,
319  PRUint32 aFromIndex,
320  PRUint32 aToIndex,
321  PRBool* _retval)
322 {
323  TRACE_FUNCTION("");
324  NS_ENSURE_ARG_POINTER(_retval);
325  *_retval = PR_TRUE;
326  return NS_OK;
327 }
328 
329 
340 NS_IMETHODIMP
341 sbMediaItemWatcher::OnBeforeListCleared(sbIMediaList* aMediaList,
342  PRBool aExcludeLists,
343  PRBool* _retval)
344 {
345  TRACE_FUNCTION("");
346  NS_ENSURE_ARG_POINTER(_retval);
347  *_retval = PR_TRUE;
348  return NS_OK;
349 }
350 
351 
362 NS_IMETHODIMP
363 sbMediaItemWatcher::OnListCleared(sbIMediaList* aMediaList,
364  PRBool aExcludeLists,
365  PRBool* _retval)
366 {
367  TRACE_FUNCTION("");
368  // Validate arguments.
369  NS_ENSURE_ARG_POINTER(_retval);
370 
371  // Do nothing if in a batch.
372  if (mBatchLevel > 0) {
373  *_retval = PR_TRUE;
374  return NS_OK;
375  }
376 
377  // Handle item removed events.
378  if (mWatchedMediaItem) {
379  mListener->OnItemRemoved(mWatchedMediaItem);
380  }
381 
382  // Keep calling.
383  *_retval = PR_FALSE;
384 
385  return NS_OK;
386 }
387 
388 
400 NS_IMETHODIMP
401 sbMediaItemWatcher::OnBatchBegin(sbIMediaList* aMediaList)
402 {
403  TRACE_FUNCTION("");
404  // Increment the batch level.
405  mBatchLevel++;
406 
407  return NS_OK;
408 }
409 
410 
422 NS_IMETHODIMP
423 sbMediaItemWatcher::OnBatchEnd(sbIMediaList* aMediaList)
424 {
425  TRACE_FUNCTION("");
426  nsresult rv;
427 
428  // Decrement the batch level. Do nothing more if still in a batch.
429  if (mBatchLevel > 0)
430  mBatchLevel--;
431  if (mBatchLevel > 0)
432  return NS_OK;
433 
434  if (!mWatchedMediaItem) {
435  NS_WARNING("sbMediaItemWatcher::OnBatchEnd");
436  return NS_OK;
437  }
438  // Get current watched media item properties.
439  nsAutoString properties;
440  rv = GetWatchedMediaItemProperties(properties);
441  NS_ENSURE_SUCCESS(rv, rv);
442 
443  // Check if watched media item was updated.
444  if (!properties.Equals(mWatchedMediaItemProperties)) {
445  rv = DoItemUpdated(properties);
446  NS_ENSURE_SUCCESS(rv, rv);
447  }
448 
449  // Handle item removed events.
450  PRBool contains;
451  rv = mWatchedLibraryML->Contains(mWatchedMediaItem, &contains);
452  NS_ENSURE_SUCCESS(rv, rv);
453  if (!contains)
454  mListener->OnItemRemoved(mWatchedMediaItem);
455 
456  return NS_OK;
457 }
458 
459 
460 //------------------------------------------------------------------------------
461 //
462 // Public services.
463 //
464 //------------------------------------------------------------------------------
465 
471  mBatchLevel(0)
472 {
474  TRACE_FUNCTION("");
475 }
476 
477 
483 {
484  TRACE_FUNCTION("");
485  // Ensure the watcher is cancelled.
486  Cancel();
487 }
488 
489 
490 //------------------------------------------------------------------------------
491 //
492 // Internal services.
493 //
494 //------------------------------------------------------------------------------
495 
500 nsresult
501 sbMediaItemWatcher::DoItemUpdated()
502 {
503  nsresult rv;
504 
505  // Get current watched media item properties.
506  nsAutoString properties;
507  rv = GetWatchedMediaItemProperties(properties);
508  NS_ENSURE_SUCCESS(rv, rv);
509 
510  // Handle the item updated event.
511  rv = DoItemUpdated(properties);
512  NS_ENSURE_SUCCESS(rv, rv);
513 
514  return NS_OK;
515 }
516 
517 
525 nsresult
526 sbMediaItemWatcher::DoItemUpdated(nsAString& aItemProperties)
527 {
528  // Update the watched media item properties.
529  mWatchedMediaItemProperties.Assign(aItemProperties);
530 
531  // Notify the listener.
532  if (mWatchedMediaItem) {
533  mListener->OnItemUpdated(mWatchedMediaItem);
534  }
535 
536  return NS_OK;
537 }
538 
539 
546 nsresult
547 sbMediaItemWatcher::GetWatchedMediaItemProperties(nsAString& aProperties)
548 {
549  NS_ENSURE_TRUE(mWatchedMediaItem, NS_ERROR_NOT_AVAILABLE);
550 
551  nsresult rv;
552 
553  // Get the watched media item properties.
554  nsCOMPtr<sbIPropertyArray> propertyArray;
555  rv = mWatchedMediaItem->GetProperties(mWatchedPropertyIDs,
556  getter_AddRefs(propertyArray));
557  NS_ENSURE_SUCCESS(rv, rv);
558  rv = propertyArray->ToString(aProperties);
559  NS_ENSURE_SUCCESS(rv, rv);
560 
561  return NS_OK;
562 }
563 
#define SB_PRLOG_SETUP(x)
Definition: sbDebugUtils.h:115
return NS_OK
Interface for the media item watcher. The media item watcher may be used to watch for changes to a sp...
NS_DECL_ISUPPORTS NS_DECL_SBIMEDIAITEMWATCHER NS_DECL_SBIMEDIALISTLISTENER sbMediaItemWatcher()
A brief description of the contents of this interface.
NS_IMPL_ISUPPORTS2(sbMediaItemWatcher, sbIMediaItemWatcher, sbIMediaListListener) NS_IMETHODIMP sbMediaItemWatcher
Watch for changes to the media item specified by aMediaItem and call the listener specified by aListe...
const unsigned long LISTENER_FLAGS_BATCHEND
Interface used to listen to changes to a media list.
const unsigned long LISTENER_FLAGS_BATCHBEGIN
function TRACE(s)
const unsigned long LISTENER_FLAGS_AFTERITEMREMOVED
#define TRACE_FUNCTION(...)
Definition: sbDebugUtils.h:118
Interface for media item listeners.
Songbird Media Item Watcher Definitions.
Interface that defines a single item of media in the system.
const unsigned long LISTENER_FLAGS_ITEMUPDATED
#define SB_PROPERTY_CONTENTURL
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...