sbMediacoreManager.cpp
Go to the documentation of this file.
1 /* vim: set sw=2 :miv */
2 /*
3  *=BEGIN SONGBIRD GPL
4  *
5  * This file is part of the Songbird web player.
6  *
7  * Copyright(c) 2005-2010 POTI, Inc.
8  * http://www.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 #include "sbMediacoreManager.h"
27 
28 #include <nsIAppStartupNotifier.h>
29 #include <nsIClassInfoImpl.h>
30 #include <nsIDOMDocument.h>
31 #include <nsIDOMElement.h>
32 #include <nsIDOMEventTarget.h>
33 #include <nsIDOMWindow.h>
34 #include <nsIDOMXULElement.h>
35 #include <nsIMutableArray.h>
36 #include <nsIObserverService.h>
37 #include <nsIProgrammingLanguage.h>
38 #include <nsISupportsPrimitives.h>
39 #include <nsIThread.h>
40 
41 #include <nsArrayUtils.h>
42 #include <nsAutoLock.h>
43 #include <nsAutoPtr.h>
44 #include <nsComponentManagerUtils.h>
45 #include <nsMemory.h>
46 #include <nsServiceManagerUtils.h>
47 #include <nsThreadUtils.h>
48 
49 #include <prprf.h>
50 
51 #include <sbIMediacore.h>
52 #include <sbIMediacoreBalanceControl.h>
53 #include <sbIMediacoreCapabilities.h>
54 #include <sbIMediacoreFactory.h>
55 #include <sbIMediacorePlaybackControl.h>
56 #include <sbIMediacoreSequencer.h>
57 #include <sbIMediacoreSimpleEqualizer.h>
58 #include <sbIMediacoreVolumeControl.h>
59 #include <sbIMediacoreVotingParticipant.h>
60 
61 #include <sbIPrompter.h>
62 #include <sbIWindowWatcher.h>
63 
65 #include <sbMediacoreVotingChain.h>
66 
68 
69 #include "sbMediacoreDataRemotes.h"
70 #include "sbMediacoreSequencer.h"
71 
72 /* observer topics */
73 #define NS_PROFILE_STARTUP_OBSERVER_ID "profile-after-change"
74 #define NS_QUIT_APPLICATION_GRANTED_OBSERVER_ID "quit-application-granted"
75 #define NS_PROFILE_SHUTDOWN_OBSERVER_ID "profile-before-change"
76 
77 /* default size of hashtable for active core instances */
78 #define SB_CORE_HASHTABLE_SIZE (4)
79 #define SB_FACTORY_HASHTABLE_SIZE (4)
80 
81 /* default base instance name */
82 #define SB_CORE_BASE_NAME "mediacore"
83 #define SB_CORE_NAME_SUFFIX "@core.songbirdnest.com"
84 
85 #define SB_EQUALIZER_DEFAULT_BAND_COUNT \
86  sbBaseMediacoreMultibandEqualizer::EQUALIZER_BAND_COUNT_DEFAULT
87 
88 #define SB_EQUALIZER_BANDS \
89  sbBaseMediacoreMultibandEqualizer::EQUALIZER_BANDS_10
90 
91 #define SB_EQUALIZER_DEFAULT_BAND_GAIN (0.0)
92 
93 /* primary video window chrome url */
94 #define SB_PVW_CHROME_URL "chrome://songbird/content/xul/videoWindow.xul"
95 /* primary video window name, this doesn't need to be localizable */
96 #define SB_PVW_NAME "VideoWindow"
97 /* primary video window element id */
98 #define SB_PVW_ELEMENT_ID "video-box"
99 
104 #ifdef PR_LOGGING
105 static PRLogModuleInfo* gMediacoreManager = nsnull;
106 #define TRACE(args) PR_LOG(gMediacoreManager, PR_LOG_DEBUG, args)
107 #define LOG(args) PR_LOG(gMediacoreManager, PR_LOG_WARN, args)
108 #else
109 #define TRACE(args) /* nothing */
110 #define LOG(args) /* nothing */
111 #endif
112 
125  nsIClassInfo,
126  nsIObserver)
127 NS_IMPL_CI_INTERFACE_GETTER5(sbMediacoreManager,
128  sbIMediacoreManager,
129  sbIMediacoreEventTarget,
130  sbIMediacoreFactoryRegistrar,
131  sbIMediacoreVoting,
132  nsISupportsWeakReference)
133 
134 NS_DECL_CLASSINFO(sbMediacoreManager)
135 NS_IMPL_THREADSAFE_CI(sbMediacoreManager)
136 
141 sbMediacoreManager::sbMediacoreManager()
142 : mMonitor(nsnull)
143 , mLastCore(0)
144 , mFullscreen(PR_FALSE)
145 , mVideoWindowMonitor(nsnull)
146 , mLastVideoWindow(0)
147 {
148  mBaseEventTarget = new sbBaseMediacoreEventTarget(this);
149  // mBaseEventTarget being null is handled on access
150  NS_WARN_IF_FALSE(mBaseEventTarget, "mBaseEventTarget is null, may be out of memory");
151 
152 #ifdef PR_LOGGING
153  if (!gMediacoreManager)
154  gMediacoreManager = PR_NewLogModule("sbMediacoreManager");
155 #endif
156 
157  TRACE(("sbMediacoreManager[0x%x] - Created", this));
158 }
159 
161 {
162  TRACE(("sbMediacoreManager[0x%x] - Destroyed", this));
163 
164  if(mMonitor) {
165  nsAutoMonitor::DestroyMonitor(mMonitor);
166  }
167 
168  if(mVideoWindowMonitor) {
169  nsAutoMonitor::DestroyMonitor(mVideoWindowMonitor);
170  }
171 }
172 
173 template<class T>
174 PLDHashOperator appendElementToArray(T* aData, void* aArray)
175 {
176  nsIMutableArray *array = (nsIMutableArray*)aArray;
177  nsresult rv;
178  nsCOMPtr<nsISupports> supports = do_QueryInterface(aData, &rv);
179  NS_ENSURE_SUCCESS(rv, PL_DHASH_STOP);
180 
181  rv = array->AppendElement(aData, false);
182  NS_ENSURE_SUCCESS(rv, PL_DHASH_STOP);
183 
184  return PL_DHASH_NEXT;
185 }
186 
187 template<class T>
188 PLDHashOperator sbMediacoreManager::EnumerateIntoArrayStringKey(
189  const nsAString& aKey,
190  T* aData,
191  void* aArray)
192 {
193  TRACE(("sbMediacoreManager[0x%x] - EnumerateIntoArray (String)"));
194  return appendElementToArray(aData, aArray);
195 }
196 
197 template<class T>
198 PLDHashOperator sbMediacoreManager::EnumerateIntoArrayISupportsKey(
199  nsISupports* aKey,
200  T* aData,
201  void* aArray)
202 {
203  TRACE(("sbMediacoreManager[0x%x] - EnumerateIntoArray (nsISupports)"));
204  return appendElementToArray(aData, aArray);
205 }
206 
207 template<class T>
208 PLDHashOperator sbMediacoreManager::EnumerateIntoArrayUint32Key(
209  const PRUint32 &aKey,
210  T* aData,
211  void* aArray)
212 {
213  TRACE(("sbMediacoreManager[0x%x] - EnumerateIntoArray (PRUint32)"));
214  return appendElementToArray(aData, aArray);
215 }
216 
217 nsresult
219 {
220  TRACE(("sbMediacoreManager[0x%x] - Init", this));
221 
222  mMonitor = nsAutoMonitor::NewMonitor("sbMediacoreManager::mMonitor");
223  NS_ENSURE_TRUE(mMonitor, NS_ERROR_OUT_OF_MEMORY);
224 
226  nsAutoMonitor::NewMonitor("sbMediacoreManager::mVideoWindowMonitor");
227  NS_ENSURE_TRUE(mVideoWindowMonitor, NS_ERROR_OUT_OF_MEMORY);
228 
229  PRBool success = mCores.Init(SB_CORE_HASHTABLE_SIZE);
230  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
231 
232  success = mFactories.Init(SB_FACTORY_HASHTABLE_SIZE);
233  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
234 
235  // Register all factories.
236  nsresult rv = NS_ERROR_UNEXPECTED;
237 
238  nsCOMPtr<nsISimpleEnumerator> categoryEnum;
239 
240  nsCOMPtr<nsICategoryManager> cm =
241  do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
242  NS_ENSURE_SUCCESS(rv, rv);
243 
244  rv = cm->EnumerateCategory(SB_MEDIACORE_FACTORY_CATEGORY,
245  getter_AddRefs(categoryEnum));
246  NS_ENSURE_SUCCESS(rv, rv);
247 
248  PRBool hasMore = PR_FALSE;
249  while (NS_SUCCEEDED(categoryEnum->HasMoreElements(&hasMore)) &&
250  hasMore) {
251 
252  nsCOMPtr<nsISupports> ptr;
253  if (NS_SUCCEEDED(categoryEnum->GetNext(getter_AddRefs(ptr))) &&
254  ptr) {
255 
256  nsCOMPtr<nsISupportsCString> stringValue(do_QueryInterface(ptr));
257 
258  nsCString factoryName;
259  nsresult rv = NS_ERROR_UNEXPECTED;
260 
261  if (stringValue &&
262  NS_SUCCEEDED(stringValue->GetData(factoryName))) {
263 
264  char * contractId;
265  rv = cm->GetCategoryEntry(SB_MEDIACORE_FACTORY_CATEGORY,
266  factoryName.get(), &contractId);
267  NS_ENSURE_SUCCESS(rv, rv);
268 
269  nsCOMPtr<sbIMediacoreFactory> factory =
270  do_CreateInstance(contractId , &rv);
271  NS_Free(contractId);
272  NS_ENSURE_SUCCESS(rv, rv);
273 
274  rv = RegisterFactory(factory);
275  NS_ENSURE_SUCCESS(rv, rv);
276  }
277  }
278  }
279 
280  nsRefPtr<sbMediacoreSequencer> sequencer;
281  NS_NEWXPCOM(sequencer, sbMediacoreSequencer);
282  NS_ENSURE_TRUE(sequencer, NS_ERROR_OUT_OF_MEMORY);
283 
284  rv = sequencer->Init();
285  NS_ENSURE_SUCCESS(rv, rv);
286 
288 
290  NS_ENSURE_SUCCESS(rv, rv);
291 
293  NS_ENSURE_SUCCESS(rv, rv);
294 
295  rv = InitVideoDataRemotes();
296  NS_ENSURE_SUCCESS(rv, rv);
297 
298  return NS_OK;
299 }
300 
301 nsresult
303 {
304  TRACE(("sbMediacoreManager[0x%x] - PreShutdown", this));
305  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
306 
307  nsAutoMonitor mon(mMonitor);
308 
309  if(mPrimaryCore) {
310  nsCOMPtr<sbIMediacoreStatus> status;
311 
312  nsresult rv = GetStatus(getter_AddRefs(status));
313  NS_ENSURE_SUCCESS(rv, rv);
314 
315  PRUint32 state = sbIMediacoreStatus::STATUS_UNKNOWN;
316  rv = status->GetState(&state);
317  NS_ENSURE_SUCCESS(rv, rv);
318 
320  nsCOMPtr<sbIMediacorePlaybackControl> playbackControl;
321  rv = GetPlaybackControl(getter_AddRefs(playbackControl));
322  NS_ENSURE_SUCCESS(rv, rv);
323 
324  rv = playbackControl->Stop();
325  NS_ENSURE_SUCCESS(rv, rv);
326  }
327  }
328 
329  return NS_OK;
330 }
331 
332 nsresult
334 {
335  TRACE(("sbMediacoreManager[0x%x] - Shutdown", this));
336  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
337 
338  nsAutoMonitor mon(mMonitor);
339 
340  nsresult rv;
341  if (mSequencer) {
342  rv = mSequencer->Stop(PR_TRUE);
343  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to stop sequencer.");
344  mSequencer = nsnull;
345  }
346 
348  rv = mDataRemoteEqualizerEnabled->Unbind();
349  NS_ENSURE_SUCCESS(rv, rv);
350  }
351 
353  rv = mDataRemoteFaceplateVolume->Unbind();
354  NS_ENSURE_SUCCESS(rv, rv);
355  }
356 
358  rv = mDataRemoteFaceplateMute->Unbind();
359  NS_ENSURE_SUCCESS(rv, rv);
360  }
361 
363  rv = mDataRemoteVideoFullscreen->Unbind();
364  NS_ENSURE_SUCCESS(rv, rv);
365  }
366 
367  nsCOMPtr<nsIMutableArray> mutableArray =
368  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
369  NS_ENSURE_SUCCESS(rv, rv);
370 
371  if (mDataRemoteEqualizerBands.IsInitialized()) {
372  mDataRemoteEqualizerBands.EnumerateRead(sbMediacoreManager::EnumerateIntoArrayUint32Key,
373  mutableArray.get());
374  }
375 
376  PRUint32 length = 0;
377  rv = mutableArray->GetLength(&length);
378  NS_ENSURE_SUCCESS(rv, rv);
379 
380  for(PRUint32 current = 0; current < length; ++current) {
381  nsCOMPtr<sbIDataRemote> dataRemote = do_QueryElementAt(mutableArray, current, &rv);
382  NS_ENSURE_SUCCESS(rv, rv);
383 
384  rv = dataRemote->Unbind();
385  NS_ENSURE_SUCCESS(rv, rv);
386  }
387 
388  rv = mutableArray->Clear();
389  NS_ENSURE_SUCCESS(rv, rv);
390 
391  mCores.EnumerateRead(sbMediacoreManager::EnumerateIntoArrayStringKey,
392  mutableArray.get());
393 
394  rv = mutableArray->GetLength(&length);
395  NS_ENSURE_SUCCESS(rv, rv);
396 
397  for(PRUint32 current = 0; current < length; ++current) {
398  nsCOMPtr<sbIMediacore> core = do_QueryElementAt(mutableArray, current, &rv);
399  NS_ENSURE_SUCCESS(rv, rv);
400 
401  rv = core->Shutdown();
402  NS_ASSERTION(NS_SUCCEEDED(rv),
403  "Failed to Shutdown a Mediacore. This may cause problems during final shutdown.");
404  }
405 
406  mPrimaryCore = nsnull;
407 
408  mFactories.Clear();
409  mCores.Clear();
410 
411  return NS_OK;
412 }
413 
414 nsresult
416 {
417  TRACE(("sbMediacoreManager[0x%x] - GenerateInstanceName", this));
418  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
419 
420  nsAutoMonitor mon(mMonitor);
421 
422  aInstanceName.AssignLiteral(SB_CORE_BASE_NAME);
423 
424  aInstanceName.AppendInt(mLastCore);
425  ++mLastCore;
426 
427  aInstanceName.AppendLiteral(SB_CORE_NAME_SUFFIX);
428 
429  return NS_OK;
430 }
431 
432 nsresult
434  nsIChannel *aChannel,
435  sbIMediacoreVotingChain **_retval)
436 {
437  TRACE(("sbMediacoreManager[0x%x] - VoteWithURIOrChannel", this));
438  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
439  NS_ENSURE_TRUE(aURI || aChannel, NS_ERROR_INVALID_ARG);
440 
441  nsRefPtr<sbMediacoreVotingChain> votingChain;
442  NS_NEWXPCOM(votingChain, sbMediacoreVotingChain);
443  NS_ENSURE_TRUE(votingChain, NS_ERROR_OUT_OF_MEMORY);
444 
445  nsresult rv = votingChain->Init();
446  NS_ENSURE_SUCCESS(rv, rv);
447 
448  nsCOMPtr<nsIArray> instances;
449 
450  // First go through the active instances to see if one of them
451  // can handle what we wish to play.
452  rv = GetInstances(getter_AddRefs(instances));
453  NS_ENSURE_SUCCESS(rv, rv);
454 
455  PRUint32 length = 0;
456  rv = instances->GetLength(&length);
457  NS_ENSURE_SUCCESS(rv, rv);
458 
459  PRUint32 found = 0;
460  for(PRUint32 current = 0; current < length; ++current) {
461  nsCOMPtr<sbIMediacoreVotingParticipant> votingParticipant =
462  do_QueryElementAt(instances, current, &rv);
463  NS_ENSURE_SUCCESS(rv, rv);
464 
465  PRUint32 result = 0;
466 
467  if(aURI) {
468  rv = votingParticipant->VoteWithURI(aURI, &result);
469  NS_ENSURE_SUCCESS(rv, rv);
470  }
471  else {
472  rv = votingParticipant->VoteWithChannel(aChannel, &result);
473  NS_ENSURE_SUCCESS(rv, rv);
474  }
475 
476  if(result > 0) {
477  nsCOMPtr<sbIMediacore> mediacore =
478  do_QueryInterface(votingParticipant, &rv);
479  NS_ENSURE_SUCCESS(rv, rv);
480 
481  rv = votingChain->AddVoteResult(result, mediacore);
482  NS_ENSURE_SUCCESS(rv, rv);
483 
484  ++found;
485  }
486  }
487 
488  // Always prefer already instantiated objects, even if they may potentially
489  // have a lower rank than registered factories.
490  if(found) {
491  NS_ADDREF(*_retval = votingChain);
492  return NS_OK;
493  }
494 
495  // If we haven't seen anything that can play this yet, try going through
496  // all the factories, create a core and have it vote.
497  nsCOMPtr<nsIArray> factories;
498  rv = GetFactories(getter_AddRefs(factories));
499  NS_ENSURE_SUCCESS(rv, rv);
500 
501  length = 0;
502  rv = factories->GetLength(&length);
503  NS_ENSURE_SUCCESS(rv, rv);
504 
505  for(PRUint32 current = 0; current < length; ++current) {
506  nsCOMPtr<sbIMediacoreFactory> factory =
507  do_QueryElementAt(factories, current, &rv);
508  NS_ENSURE_SUCCESS(rv, rv);
509 
510  nsString mediacoreInstanceName;
511  GenerateInstanceName(mediacoreInstanceName);
512 
513  nsCOMPtr<sbIMediacore> mediacore;
514  rv = CreateMediacoreWithFactory(factory,
515  mediacoreInstanceName,
516  getter_AddRefs(mediacore));
517 #if defined(DEBUG)
518  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create mediacore.");
519 #endif
520 
521  // Creation of core failed. Just move along to the next one.
522  // This can often happen if dependecies for the mediacore are missing.
523  if(NS_FAILED(rv)) {
524  continue;
525  }
526 
527  nsCOMPtr<sbIMediacoreVotingParticipant> votingParticipant =
528  do_QueryInterface(mediacore, &rv);
529  NS_ENSURE_SUCCESS(rv, rv);
530 
531  PRUint32 result = 0;
532 
533  if(aURI) {
534  rv = votingParticipant->VoteWithURI(aURI, &result);
535  NS_ENSURE_SUCCESS(rv, rv);
536  }
537  else {
538  rv = votingParticipant->VoteWithChannel(aChannel, &result);
539  NS_ENSURE_SUCCESS(rv, rv);
540  }
541 
542  if(result > 0) {
543  rv = votingChain->AddVoteResult(result, mediacore);
544  NS_ENSURE_SUCCESS(rv, rv);
545  }
546  }
547 
548  NS_ADDREF(*_retval = votingChain);
549 
550  return NS_OK;
551 }
552 
553 // ----------------------------------------------------------------------------
554 // sbBaseMediacoreMultibandEqualizer overrides
555 // ----------------------------------------------------------------------------
556 
557 /*virtual*/ nsresult
559 {
560  nsresult rv = NS_ERROR_UNEXPECTED;
561 
562  nsString nullString;
563  nullString.SetIsVoid(PR_TRUE);
564 
565  PRBool success = mDataRemoteEqualizerBands.Init(10);
566  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
567 
569  do_CreateInstance("@songbirdnest.com/Songbird/DataRemote;1", &rv);
570  NS_ENSURE_SUCCESS(rv, rv);
571 
572  rv = mDataRemoteEqualizerEnabled->Init(
573  NS_LITERAL_STRING(SB_MEDIACORE_DATAREMOTE_EQ_ENABLED),
574  nullString);
575  NS_ENSURE_SUCCESS(rv, rv);
576 
577  nsString eqEnabledStr;
578  rv = mDataRemoteEqualizerEnabled->GetStringValue(eqEnabledStr);
579  NS_ENSURE_SUCCESS(rv, rv);
580 
581  PRBool eqEnabled = PR_FALSE;
582  if(!eqEnabledStr.IsEmpty()) {
583  rv = mDataRemoteEqualizerEnabled->GetBoolValue(&eqEnabled);
584  NS_ENSURE_SUCCESS(rv, rv);
585  }
586 
588 
589  rv = mDataRemoteEqualizerEnabled->SetBoolValue(mEqEnabled);
590  NS_ENSURE_SUCCESS(rv, rv);
591 
592  LOG(("[sbMediacoreManager] - Initializing eq enabled from data remote, enabled: %s",
593  eqEnabled ? "true" : "false"));
594 
595  // Initialize the eq band data remotes
596  for(PRUint32 i = 0; i < SB_EQUALIZER_DEFAULT_BAND_COUNT; ++i) {
597  nsCOMPtr<sbIMediacoreEqualizerBand> band;
598  rv = GetBand(i, getter_AddRefs(band));
599  NS_ENSURE_SUCCESS(rv, rv);
600  }
601 
602  return NS_OK;
603 }
604 
605 /*virtual*/ nsresult
607 {
608  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
609 
610  nsresult rv = NS_ERROR_UNEXPECTED;
611  nsAutoMonitor mon(mMonitor);
612 
613  if(mPrimaryCore) {
614  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
615  do_QueryInterface(mPrimaryCore, &rv);
616  NS_ENSURE_SUCCESS(rv, rv);
617 
618  mon.Exit();
619 
620  rv = equalizer->SetEqEnabled(aEqEnabled);
621  NS_ENSURE_SUCCESS(rv, rv);
622 
623  // If the EQ wasn't enabled before, set the bands.
624  if(!mEqEnabled && aEqEnabled) {
625  nsCOMPtr<nsISimpleEnumerator> bands;
626  rv = GetBands(getter_AddRefs(bands));
627  NS_ENSURE_SUCCESS(rv, rv);
628 
629  rv = equalizer->SetBands(bands);
630  NS_ENSURE_SUCCESS(rv, rv);
631  }
632  }
633  else {
634  mon.Exit();
635  }
636 
637  rv = mDataRemoteEqualizerEnabled->SetBoolValue(aEqEnabled);
638  NS_ENSURE_SUCCESS(rv, rv);
639 
640  return NS_OK;
641 }
642 
643 /*virtual*/ nsresult
645 {
646  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
647 
648  nsresult rv = NS_ERROR_UNEXPECTED;
649  nsAutoMonitor mon(mMonitor);
650 
651  if(mPrimaryCore) {
652  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
653  do_QueryInterface(mPrimaryCore, &rv);
654  NS_ENSURE_SUCCESS(rv, rv);
655 
656  mon.Exit();
657 
658  rv = equalizer->GetBandCount(aBandCount);
659  NS_ENSURE_SUCCESS(rv, rv);
660  }
661  else {
662  mon.Exit();
663  *aBandCount = SB_EQUALIZER_DEFAULT_BAND_COUNT;
664  }
665 
666  return NS_OK;
667 }
668 
669 /*virtual*/ nsresult
671 {
672  NS_ENSURE_ARG_RANGE(aBandIndex, 0, SB_EQUALIZER_DEFAULT_BAND_COUNT);
673  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
674 
675  nsresult rv = NS_ERROR_UNEXPECTED;
676  nsAutoMonitor mon(mMonitor);
677 
678  if(mPrimaryCore) {
679  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
680  do_QueryInterface(mPrimaryCore, &rv);
681  NS_ENSURE_SUCCESS(rv, rv);
682 
683  mon.Exit();
684 
685  nsCOMPtr<sbIMediacoreEqualizerBand> band;
686  rv = equalizer->GetBand(aBandIndex, getter_AddRefs(band));
687  NS_ENSURE_SUCCESS(rv, rv);
688 
689  PRUint32 bandIndex = 0, bandFrequency = 0;
690  double bandGain = 0.0;
691 
692  rv = band->GetValues(&bandIndex, &bandFrequency, &bandGain);
693  NS_ENSURE_SUCCESS(rv, rv);
694 
695  rv = aBand->Init(bandIndex, bandFrequency, bandGain);
696  NS_ENSURE_SUCCESS(rv, rv);
697  }
698  else {
699  nsCOMPtr<sbIDataRemote> bandRemote;
700  rv = GetAndEnsureEQBandHasDataRemote(aBandIndex, getter_AddRefs(bandRemote));
701  NS_ENSURE_SUCCESS(rv, rv);
702 
703  nsString bandRemoteValue;
704  rv = bandRemote->GetStringValue(bandRemoteValue);
705  NS_ENSURE_SUCCESS(rv, rv);
706 
707  NS_ConvertUTF16toUTF8 gainStr(bandRemoteValue);
708  PRFloat64 gain = 0;
709 
710  if((PR_sscanf(gainStr.BeginReading(), "%lg", &gain) != 1) ||
711  (gain > 1.0 || gain < -1.0)) {
714  gainStr);
715  rv = bandRemote->SetStringValue(NS_ConvertUTF8toUTF16(gainStr));
716  NS_ENSURE_SUCCESS(rv, rv);
717  }
718 
719  rv = aBand->Init(aBandIndex, SB_EQUALIZER_BANDS[aBandIndex], gain);
720  NS_ENSURE_SUCCESS(rv, rv);
721  }
722 
723  return NS_OK;
724 }
725 
726 /*virtual*/ nsresult
728 {
729  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
730 
731  nsresult rv = NS_ERROR_UNEXPECTED;
732  nsAutoMonitor mon(mMonitor);
733 
734  if(mPrimaryCore) {
735  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
736  do_QueryInterface(mPrimaryCore, &rv);
737  NS_ENSURE_SUCCESS(rv, rv);
738 
739  mon.Exit();
740 
741  rv = equalizer->SetBand(aBand);
742  NS_ENSURE_SUCCESS(rv, rv);
743  }
744  else {
745  mon.Exit();
746  }
747 
749  NS_ENSURE_SUCCESS(rv, rv);
750 
751  return NS_OK;
752 }
753 
754 nsresult
756  sbIDataRemote **aRemote)
757 {
758  NS_ENSURE_ARG_RANGE(aBandIndex, 0, SB_EQUALIZER_DEFAULT_BAND_COUNT);
759  NS_ENSURE_ARG_POINTER(aRemote);
760  NS_ENSURE_TRUE(mDataRemoteEqualizerBands.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
761 
762  nsresult rv = NS_ERROR_UNEXPECTED;
763  nsCOMPtr<sbIDataRemote> bandRemote;
764  PRBool success = mDataRemoteEqualizerBands.Get(aBandIndex, getter_AddRefs(bandRemote));
765 
766  if(!success) {
767  rv = CreateDataRemoteForEqualizerBand(aBandIndex, getter_AddRefs(bandRemote));
768  NS_ENSURE_SUCCESS(rv, rv);
769  }
770 
771  bandRemote.forget(aRemote);
772 
773  return NS_OK;
774 }
775 
776 nsresult
778 {
779  NS_ENSURE_ARG_POINTER(aBand);
780  NS_ENSURE_TRUE(mDataRemoteEqualizerBands.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
781 
782  PRUint32 bandIndex = 0, bandFrequency = 0;
783  double bandGain = 0.0;
784 
785  nsresult rv = aBand->GetValues(&bandIndex, &bandFrequency, &bandGain);
786  NS_ENSURE_SUCCESS(rv, rv);
787 
788  nsCOMPtr<sbIDataRemote> bandRemote;
789  PRBool success = mDataRemoteEqualizerBands.Get(bandIndex, getter_AddRefs(bandRemote));
790 
791  if(!success) {
792  rv = CreateDataRemoteForEqualizerBand(bandIndex, getter_AddRefs(bandRemote));
793  NS_ENSURE_SUCCESS(rv, rv);
794  }
795 
796  nsCString bandGainStr;
797  SB_ConvertFloatEqGainToJSStringValue(bandGain, bandGainStr);
798 
799  NS_ConvertUTF8toUTF16 gainStr(bandGainStr);
800  rv = bandRemote->SetStringValue(gainStr);
801  NS_ENSURE_SUCCESS(rv, rv);
802 
803  return NS_OK;
804 }
805 
806 nsresult
808  sbIDataRemote **aRemote)
809 {
810  NS_ENSURE_ARG_RANGE(aBandIndex, 0, SB_EQUALIZER_DEFAULT_BAND_COUNT);
811  NS_ENSURE_ARG_POINTER(aRemote);
812  NS_ENSURE_TRUE(mDataRemoteEqualizerBands.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
813 
814  nsresult rv = NS_ERROR_UNEXPECTED;
815 
816  nsString nullString;
817  nullString.SetIsVoid(PR_TRUE);
818 
819  nsCOMPtr<sbIDataRemote> bandRemote =
820  do_CreateInstance("@songbirdnest.com/Songbird/DataRemote;1", &rv);
821  NS_ENSURE_SUCCESS(rv, rv);
822 
823  nsString bandRemoteName(NS_LITERAL_STRING(SB_MEDIACORE_DATAREMOTE_EQ_BAND_PREFIX));
824  bandRemoteName.AppendInt(aBandIndex);
825 
826  rv = bandRemote->Init(bandRemoteName, nullString);
827  NS_ENSURE_SUCCESS(rv, rv);
828 
829  PRBool success = mDataRemoteEqualizerBands.Put(aBandIndex, bandRemote);
830  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
831 
832  bandRemote.forget(aRemote);
833 
834  return NS_OK;
835 }
836 
837 nsresult
839 {
840  nsresult rv = NS_ERROR_UNEXPECTED;
841 
842  nsString nullString;
843  nullString.SetIsVoid(PR_TRUE);
844 
846  do_CreateInstance("@songbirdnest.com/Songbird/DataRemote;1", &rv);
847  NS_ENSURE_SUCCESS(rv, rv);
848 
849  rv = mDataRemoteVideoFullscreen->Init(
850  NS_LITERAL_STRING(SB_MEDIACORE_DATAREMOTE_VIDEO_FULLSCREEN), nullString);
851  NS_ENSURE_SUCCESS(rv, rv);
852 
853  rv = mDataRemoteVideoFullscreen->SetBoolValue(PR_FALSE);
854  NS_ENSURE_SUCCESS(rv, rv);
855 
856  return NS_OK;
857 }
858 
859 nsresult
861 {
862  nsAutoMonitor mon(mVideoWindowMonitor);
863  mVideoWindow = nsnull;
864  return NS_OK;
865 }
866 
867 // ----------------------------------------------------------------------------
868 // sbBaseMediacoreVolumeControl overrides
869 // ----------------------------------------------------------------------------
870 
871 /*virtual*/ nsresult
873 {
874  nsString nullString;
875  nullString.SetIsVoid(PR_TRUE);
876 
877  nsresult rv = NS_ERROR_UNEXPECTED;
879  do_CreateInstance("@songbirdnest.com/Songbird/DataRemote;1", &rv);
880  NS_ENSURE_SUCCESS(rv, rv);
881 
882  rv = mDataRemoteFaceplateVolume->Init(
883  NS_LITERAL_STRING(SB_MEDIACORE_DATAREMOTE_FACEPLATE_VOLUME),
884  nullString);
885  NS_ENSURE_SUCCESS(rv, rv);
886 
887  nsString volumeStr;
888  rv = mDataRemoteFaceplateVolume->GetStringValue(volumeStr);
889  NS_ENSURE_SUCCESS(rv, rv);
890 
891  NS_ConvertUTF16toUTF8 volStr(volumeStr);
892  PRFloat64 volume = 0;
893 
894  if((PR_sscanf(volStr.BeginReading(), "%lg", &volume) != 1) ||
895  (volume > 1 || volume < 0)) {
896  volume = 0.5;
897  }
898 
899  mVolume = volume;
900 
901  LOG(("[sbMediacoreManager] - Initializing volume from data remote, volume: %s",
902  volStr.BeginReading()));
903 
905  NS_ENSURE_SUCCESS(rv, rv);
906 
908  do_CreateInstance("@songbirdnest.com/Songbird/DataRemote;1", &rv);
909  NS_ENSURE_SUCCESS(rv, rv);
910 
911  rv = mDataRemoteFaceplateMute->Init(
912  NS_LITERAL_STRING(SB_MEDIACORE_DATAREMOTE_FACEPLATE_MUTE),
913  nullString);
914  NS_ENSURE_SUCCESS(rv, rv);
915 
916  nsString muteStr;
917  rv = mDataRemoteFaceplateMute->GetStringValue(muteStr);
918  NS_ENSURE_SUCCESS(rv, rv);
919 
920  PRBool mute = PR_FALSE;
921  if(!muteStr.IsEmpty()) {
922  rv = mDataRemoteFaceplateMute->GetBoolValue(&mute);
923  NS_ENSURE_SUCCESS(rv, rv);
924  }
925 
926  mMute = mute;
927 
928  rv = mDataRemoteFaceplateMute->SetBoolValue(mMute);
929  NS_ENSURE_SUCCESS(rv, rv);
930 
931  LOG(("[sbMediacoreManager] - Initializing mute from data remote, mute: %d",
932  mute));
933 
934  return NS_OK;
935 }
936 
937 /*virtual*/ nsresult
939 {
940  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
941 
942  nsresult rv = NS_ERROR_UNEXPECTED;
943  nsAutoMonitor mon(mMonitor);
944 
945  if(mPrimaryCore) {
946  nsCOMPtr<sbIMediacoreVolumeControl> volumeControl =
947  do_QueryInterface(mPrimaryCore, &rv);
948  NS_ENSURE_SUCCESS(rv, rv);
949 
950  mon.Exit();
951 
952  rv = volumeControl->SetMute(aMute);
953  NS_ENSURE_SUCCESS(rv, rv);
954  }
955  else {
956  mon.Exit();
957  }
958 
959  rv = mDataRemoteFaceplateMute->SetBoolValue(aMute);
960  NS_ENSURE_SUCCESS(rv, rv);
961 
962  return NS_OK;
963 }
964 
965 /*virtual*/ nsresult
967 {
968  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
969 
970  nsresult rv = NS_ERROR_UNEXPECTED;
971 
972  nsAutoMonitor mon(mMonitor);
973 
974  if(mPrimaryCore) {
975 
976  nsCOMPtr<sbIMediacoreVolumeControl> volumeControl =
977  do_QueryInterface(mPrimaryCore, &rv);
978  NS_ENSURE_SUCCESS(rv, rv);
979 
980  mon.Exit();
981 
982  rv = volumeControl->SetVolume(aVolume);
983  NS_ENSURE_SUCCESS(rv, rv);
984  }
985  else {
986  mon.Exit();
987  }
988 
989  rv = SetVolumeDataRemote(aVolume);
990  NS_ENSURE_SUCCESS(rv, rv);
991 
992  return NS_OK;
993 }
994 
995 nsresult
997 {
998  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
999  NS_ENSURE_STATE(mDataRemoteFaceplateVolume);
1000 
1001  nsCString volume;
1002  SB_ConvertFloatVolToJSStringValue(aVolume, volume);
1003 
1004  NS_ConvertUTF8toUTF16 volumeStr(volume);
1005  nsresult rv = mDataRemoteFaceplateVolume->SetStringValue(volumeStr);
1006  NS_ENSURE_SUCCESS(rv, rv);
1007 
1008  return NS_OK;
1009 }
1010 
1011 // ----------------------------------------------------------------------------
1012 // sbIMediacoreManager Interface
1013 // ----------------------------------------------------------------------------
1014 
1015 NS_IMETHODIMP
1016 sbMediacoreManager::GetPrimaryCore(sbIMediacore * *aPrimaryCore)
1017 {
1018  TRACE(("sbMediacoreManager[0x%x] - GetPrimaryCore", this));
1019  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1020  NS_ENSURE_ARG_POINTER(aPrimaryCore);
1021 
1022  nsAutoMonitor mon(mMonitor);
1023  NS_IF_ADDREF(*aPrimaryCore = mPrimaryCore);
1024 
1025  return NS_OK;
1026 }
1027 NS_IMETHODIMP
1028 sbMediacoreManager::GetBalanceControl(
1029  sbIMediacoreBalanceControl * *aBalanceControl)
1030 {
1031  TRACE(("sbMediacoreManager[0x%x] - GetBalanceControl", this));
1032  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1033  NS_ENSURE_ARG_POINTER(aBalanceControl);
1034 
1035  *aBalanceControl = nsnull;
1036 
1037  nsAutoMonitor mon(mMonitor);
1038 
1039  if(!mPrimaryCore) {
1040  return nsnull;
1041  }
1042 
1043  nsresult rv = NS_ERROR_UNEXPECTED;
1044  nsCOMPtr<sbIMediacoreBalanceControl> balanceControl =
1045  do_QueryInterface(mPrimaryCore, &rv);
1046  NS_ENSURE_SUCCESS(rv, rv);
1047 
1048  balanceControl.forget(aBalanceControl);
1049 
1050  return NS_OK;
1051 }
1052 
1053 NS_IMETHODIMP
1054 sbMediacoreManager::GetVolumeControl(
1055  sbIMediacoreVolumeControl * *aVolumeControl)
1056 {
1057  TRACE(("sbMediacoreManager[0x%x] - GetVolumeControl", this));
1058  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1059  NS_ENSURE_ARG_POINTER(aVolumeControl);
1060 
1061  nsAutoMonitor mon(mMonitor);
1062 
1063  nsresult rv = NS_ERROR_UNEXPECTED;
1064  nsCOMPtr<sbIMediacoreVolumeControl> volumeControl =
1065  do_QueryInterface(NS_ISUPPORTS_CAST(sbIMediacoreManager *, this), &rv);
1066  NS_ENSURE_SUCCESS(rv, rv);
1067 
1068  volumeControl.forget(aVolumeControl);
1069 
1070  return NS_OK;
1071 }
1072 
1073 NS_IMETHODIMP
1074 sbMediacoreManager::GetEqualizer(
1075  sbIMediacoreMultibandEqualizer * *aEqualizer)
1076 {
1077  TRACE(("sbMediacoreManager[0x%x] - GetEqualizer", this));
1078  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1079  NS_ENSURE_ARG_POINTER(aEqualizer);
1080 
1081  *aEqualizer = nsnull;
1082 
1083  nsAutoMonitor mon(mMonitor);
1084 
1085  nsresult rv = NS_ERROR_UNEXPECTED;
1086  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
1087  do_QueryInterface(NS_ISUPPORTS_CAST(sbIMediacoreManager *, this), &rv);
1088  NS_ENSURE_SUCCESS(rv, rv);
1089 
1090  equalizer.forget(aEqualizer);
1091 
1092  return NS_OK;
1093 }
1094 
1095 NS_IMETHODIMP
1096 sbMediacoreManager::GetPlaybackControl(
1097  sbIMediacorePlaybackControl * *aPlaybackControl)
1098 {
1099  TRACE(("sbMediacoreManager[0x%x] - GetPlaybackControl", this));
1100  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1101  NS_ENSURE_ARG_POINTER(aPlaybackControl);
1102 
1103  *aPlaybackControl = nsnull;
1104 
1105  nsAutoMonitor mon(mMonitor);
1106 
1107  if(!mPrimaryCore) {
1108  return NS_OK;
1109  }
1110 
1111  nsresult rv = NS_ERROR_UNEXPECTED;
1112  nsCOMPtr<sbIMediacorePlaybackControl> playbackControl =
1113  do_QueryInterface(mPrimaryCore, &rv);
1114  NS_ENSURE_SUCCESS(rv, rv);
1115 
1116  playbackControl.forget(aPlaybackControl);
1117 
1118  return NS_OK;
1119 }
1120 
1121 NS_IMETHODIMP
1122 sbMediacoreManager::GetCapabilities(
1123  sbIMediacoreCapabilities * *aCapabilities)
1124 {
1125  TRACE(("sbMediacoreManager[0x%x] - GetCapabilities", this));
1126  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1127  NS_ENSURE_ARG_POINTER(aCapabilities);
1128 
1129  *aCapabilities = nsnull;
1130 
1131  nsAutoMonitor mon(mMonitor);
1132 
1133  if(!mPrimaryCore) {
1134  return NS_OK;
1135  }
1136 
1137  nsresult rv = NS_ERROR_UNEXPECTED;
1138  nsCOMPtr<sbIMediacoreCapabilities> volumeControl =
1139  do_QueryInterface(mPrimaryCore, &rv);
1140  NS_ENSURE_SUCCESS(rv, rv);
1141 
1142  volumeControl.forget(aCapabilities);
1143 
1144  return NS_OK;
1145 }
1146 
1147 NS_IMETHODIMP
1148 sbMediacoreManager::GetStatus(sbIMediacoreStatus * *aStatus)
1149 {
1150  TRACE(("sbMediacoreManager[0x%x] - GetStatus", this));
1151  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1152  NS_ENSURE_ARG_POINTER(aStatus);
1153 
1154  nsresult rv = NS_ERROR_UNEXPECTED;
1155  nsAutoMonitor mon(mMonitor);
1156  nsCOMPtr<sbIMediacoreStatus> status =
1157  do_QueryInterface(mSequencer, &rv);
1158  NS_ENSURE_SUCCESS(rv, rv);
1159 
1160  status.forget(aStatus);
1161 
1162  return NS_OK;
1163 }
1164 
1165 NS_IMETHODIMP
1166 sbMediacoreManager::GetVideo(sbIMediacoreVideoWindow * *aVideo)
1167 {
1168  TRACE(("sbMediacoreManager[0x%x] - GetVideo", this));
1169  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1170  NS_ENSURE_ARG_POINTER(aVideo);
1171 
1172  *aVideo = nsnull;
1173 
1174  nsAutoMonitor mon(mMonitor);
1175 
1176  if(!mPrimaryCore) {
1177  return NS_OK;
1178  }
1179 
1180  nsresult rv = NS_ERROR_UNEXPECTED;
1181  nsCOMPtr<sbIMediacoreVideoWindow> videoWindow =
1182  do_QueryInterface(NS_ISUPPORTS_CAST(sbIMediacoreManager *, this), &rv);
1183  NS_ENSURE_SUCCESS(rv, rv);
1184 
1185  videoWindow.forget(aVideo);
1186 
1187  return NS_OK;
1188 }
1189 
1190 NS_IMETHODIMP
1191 sbMediacoreManager::GetSequencer(
1192  sbIMediacoreSequencer * *aSequencer)
1193 {
1194  TRACE(("sbMediacoreManager[0x%x] - GetSequencer", this));
1195  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1196  NS_ENSURE_ARG_POINTER(aSequencer);
1197 
1198  nsresult rv = NS_ERROR_UNEXPECTED;
1199  nsAutoMonitor mon(mMonitor);
1200  nsCOMPtr<sbIMediacoreSequencer> sequencer =
1201  do_QueryInterface(mSequencer, &rv);
1202  NS_ENSURE_SUCCESS(rv, rv);
1203 
1204  sequencer.forget(aSequencer);
1205 
1206  return NS_OK;
1207 }
1208 
1209 NS_IMETHODIMP
1210 sbMediacoreManager::SetSequencer(
1211  sbIMediacoreSequencer * aSequencer)
1212 {
1213  TRACE(("sbMediacoreManager[0x%x] - SetSequencer", this));
1214  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1215 
1216  return NS_ERROR_NOT_IMPLEMENTED;
1217 }
1218 
1219 NS_IMETHODIMP
1220 sbMediacoreManager::GetPrimaryVideoWindow(PRBool aCreate,
1221  PRUint32 aWidthHint,
1222  PRUint32 aHeightHint,
1223  sbIMediacoreVideoWindow **aVideo)
1224 {
1225  TRACE(("sbMediacoreManager[0x%x] - GetVideoWindow", this));
1226  NS_ENSURE_TRUE(mVideoWindowMonitor, NS_ERROR_NOT_INITIALIZED);
1227  NS_ENSURE_ARG_POINTER(aVideo);
1228 
1229  nsresult rv = NS_ERROR_UNEXPECTED;
1230  *aVideo = nsnull;
1231 
1232  PRBool hintValid = PR_FALSE;
1233  if(aWidthHint > 0 && aHeightHint > 0) {
1234  hintValid = PR_TRUE;
1235  }
1236 
1237  {
1238  nsAutoMonitor mon(mVideoWindowMonitor);
1239 
1240  if(mVideoWindow) {
1241  nsCOMPtr<sbIMediacoreVideoWindow> videoWindow =
1242  do_QueryInterface(NS_ISUPPORTS_CAST(sbIMediacoreManager *, this), &rv);
1243  NS_ENSURE_SUCCESS(rv, rv);
1244 
1245  videoWindow.forget(aVideo);
1246 
1247  return NS_OK;
1248  }
1249 
1250  if(!aCreate) {
1251  return NS_OK;
1252  }
1253  }
1254 
1255  nsCOMPtr<sbIPrompter> prompter =
1256  do_GetService(SONGBIRD_PROMPTER_CONTRACTID, &rv);
1257  NS_ENSURE_SUCCESS(rv, rv);
1258 
1259  rv = prompter->SetParentWindowType(NS_LITERAL_STRING("Songbird:Main"));
1260  NS_ENSURE_SUCCESS(rv, rv);
1261 
1262  rv = prompter->SetWaitForWindow(PR_TRUE);
1263  NS_ENSURE_SUCCESS(rv, rv);
1264 
1265  // Make a unique window name. This circumvents race conditions that can
1266  // occur while a window is requested and the video window is currently
1267  // closing by avoiding reuse of the closing window.
1268  nsString windowName;
1269  windowName.AssignLiteral(SB_PVW_NAME);
1270  windowName.AppendInt(mLastVideoWindow++);
1271 
1272  nsCOMPtr<nsIDOMWindow> domWindow;
1273  rv = prompter->OpenWindow(nsnull,
1274  NS_LITERAL_STRING(SB_PVW_CHROME_URL),
1275  windowName,
1276  NS_LITERAL_STRING("chrome,centerscreen,resizable"),
1277  nsnull,
1278  getter_AddRefs(domWindow));
1279  NS_ENSURE_SUCCESS(rv, rv);
1280 
1281  // If we're not on the main thread, we'll have to proxy calls
1282  // to quite a few objects.
1283  PRBool mainThread = NS_IsMainThread();
1284  nsCOMPtr<nsIThread> target;
1285 
1286  rv = NS_GetMainThread(getter_AddRefs(target));
1287  NS_ENSURE_SUCCESS(rv, rv);
1288 
1289  // Now we have to wait for the window to finish loading before we
1290  // continue. If we don't let it finish loading we will never be
1291  // able to find the correct element in the window.
1292  if(!mainThread) {
1293  // If we're not on the main thread we can use the songbird window
1294  // watcher to wait for a window of type "Songbird:Core" to come up.
1295  nsCOMPtr<sbIWindowWatcher> windowWatcher =
1296  do_GetService(SB_WINDOWWATCHER_CONTRACTID, &rv);
1297  NS_ENSURE_SUCCESS(rv, rv);
1298 
1299  rv = windowWatcher->WaitForWindow(NS_LITERAL_STRING("Songbird:Core"));
1300  NS_ENSURE_SUCCESS(rv, rv);
1301 
1302  nsCOMPtr<nsIDOMWindow> grip;
1303  domWindow.swap(grip);
1304 
1305  rv = do_GetProxyForObject(target,
1306  NS_GET_IID(nsIDOMWindow),
1307  grip,
1308  NS_PROXY_SYNC | NS_PROXY_ALWAYS,
1309  getter_AddRefs(domWindow));
1310  NS_ENSURE_SUCCESS(rv, rv);
1311 
1312  nsCOMPtr<nsIDOMEventTarget> domTarget = do_QueryInterface(domWindow, &rv);
1313  NS_ENSURE_SUCCESS(rv, rv);
1314 
1315  nsCOMPtr<nsIDOMEventTarget> proxiedDomTarget;
1316  rv = do_GetProxyForObject(target,
1317  NS_GET_IID(nsIDOMEventTarget),
1318  domTarget,
1319  NS_PROXY_SYNC | NS_PROXY_ALWAYS,
1320  getter_AddRefs(proxiedDomTarget));
1321  NS_ENSURE_SUCCESS(rv, rv);
1322 
1323  nsRefPtr<sbMediacoreVideoWindowListener> videoWindowListener;
1324  NS_NEWXPCOM(videoWindowListener, sbMediacoreVideoWindowListener);
1325  NS_ENSURE_TRUE(videoWindowListener, NS_ERROR_OUT_OF_MEMORY);
1326 
1327  rv = videoWindowListener->Init(this, domTarget);
1328  NS_ENSURE_SUCCESS(rv, rv);
1329 
1330  rv = proxiedDomTarget->AddEventListener(NS_LITERAL_STRING("unload"),
1331  videoWindowListener,
1332  PR_FALSE);
1333  NS_ENSURE_SUCCESS(rv, rv);
1334  }
1335  else {
1336  // On the main thread, we'll have to add a listener to the window
1337  // and process events on the main thread while we wait for the video
1338  // window to finish loading.
1339  nsRefPtr<sbMediacoreVideoWindowListener> videoWindowListener;
1340  NS_NEWXPCOM(videoWindowListener, sbMediacoreVideoWindowListener);
1341  NS_ENSURE_TRUE(videoWindowListener, NS_ERROR_OUT_OF_MEMORY);
1342 
1343  nsCOMPtr<nsIDOMEventTarget> domTarget = do_QueryInterface(domWindow, &rv);
1344  NS_ENSURE_SUCCESS(rv, rv);
1345 
1346  rv = videoWindowListener->Init(this, domTarget);
1347  NS_ENSURE_SUCCESS(rv, rv);
1348 
1349  rv = domTarget->AddEventListener(NS_LITERAL_STRING("resize"),
1350  videoWindowListener,
1351  PR_FALSE);
1352  NS_ENSURE_SUCCESS(rv, rv);
1353 
1354  PRBool processed = PR_FALSE;
1355  while(!videoWindowListener->IsWindowReady()) {
1356  rv = target->ProcessNextEvent(PR_FALSE, &processed);
1357  NS_ENSURE_SUCCESS(rv, rv);
1358  }
1359 
1360  rv = domTarget->RemoveEventListener(NS_LITERAL_STRING("resize"),
1361  videoWindowListener,
1362  PR_FALSE);
1363  NS_ENSURE_SUCCESS(rv, rv);
1364 
1365  // If the window isn't ready yet, error out.
1366  NS_ENSURE_TRUE(videoWindowListener->IsWindowReady(), NS_ERROR_FAILURE);
1367 
1368  rv = domTarget->AddEventListener(NS_LITERAL_STRING("unload"),
1369  videoWindowListener,
1370  PR_FALSE);
1371  NS_ENSURE_SUCCESS(rv, rv);
1372  }
1373 
1374  nsCOMPtr<nsIDOMDocument> domDoc;
1375 
1376  rv = domWindow->GetDocument(getter_AddRefs(domDoc));
1377  NS_ENSURE_SUCCESS(rv, rv);
1378 
1379  if(!mainThread) {
1380  nsCOMPtr<nsIDOMDocument> grip;
1381  domDoc.swap(grip);
1382 
1383  rv = do_GetProxyForObject(target,
1384  NS_GET_IID(nsIDOMDocument),
1385  grip,
1386  NS_PROXY_SYNC | NS_PROXY_ALWAYS,
1387  getter_AddRefs(domDoc));
1388  NS_ENSURE_SUCCESS(rv, rv);
1389  }
1390 
1391  nsCOMPtr<nsIDOMElement> domElement;
1392  rv = domDoc->GetElementById(NS_LITERAL_STRING(SB_PVW_ELEMENT_ID),
1393  getter_AddRefs(domElement));
1394  NS_ENSURE_SUCCESS(rv, rv);
1395 
1396  NS_ENSURE_TRUE(domElement, NS_ERROR_UNEXPECTED);
1397 
1398  nsCOMPtr<nsIDOMXULElement> domXulElement =
1399  do_QueryInterface(domElement, &rv);
1400  NS_ENSURE_SUCCESS(rv, rv);
1401 
1402  {
1403  nsAutoMonitor mon(mVideoWindowMonitor);
1404  domXulElement.swap(mVideoWindow);
1405  }
1406 
1407  nsCOMPtr<sbIMediacoreVideoWindow> videoWindow =
1408  do_QueryInterface(NS_ISUPPORTS_CAST(sbIMediacoreManager *, this), &rv);
1409  NS_ENSURE_SUCCESS(rv, rv);
1410 
1411  videoWindow.forget(aVideo);
1412 
1413  return NS_OK;
1414 }
1415 
1416 // ----------------------------------------------------------------------------
1417 // sbPIMediacoreManager Interface
1418 // ----------------------------------------------------------------------------
1419 
1420 NS_IMETHODIMP
1421 sbMediacoreManager::SetPrimaryCore(sbIMediacore * aPrimaryCore)
1422 {
1423  TRACE(("sbMediacoreManager[0x%x] - SetPrimaryCore", this));
1424  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1425  NS_ENSURE_ARG_POINTER(aPrimaryCore);
1426 
1427  nsAutoMonitor mon(mMonitor);
1428  mPrimaryCore = aPrimaryCore;
1429 
1430  nsresult rv = NS_ERROR_UNEXPECTED;
1431 
1432  nsCOMPtr<sbIMediacoreVolumeControl> volumeControl =
1433  do_QueryInterface(mPrimaryCore, &rv);
1434  NS_ENSURE_SUCCESS(rv, rv);
1435 
1436  // No equalizer interface on the primary core is not a fatal error.
1437  nsCOMPtr<sbIMediacoreMultibandEqualizer> equalizer =
1438  do_QueryInterface(mPrimaryCore, &rv);
1439  if(NS_FAILED(rv)) {
1440  equalizer = nsnull;
1441  }
1442  mon.Exit();
1443 
1444  nsAutoMonitor volMon(sbBaseMediacoreVolumeControl::mMonitor);
1445 
1446  rv = volumeControl->SetVolume(mVolume);
1447  NS_ENSURE_SUCCESS(rv, rv);
1448 
1449  rv = volumeControl->SetMute(mMute);
1450  NS_ENSURE_SUCCESS(rv, rv);
1451 
1452  volMon.Exit();
1453 
1454  if(equalizer) {
1455  nsAutoMonitor eqMon(sbBaseMediacoreMultibandEqualizer::mMonitor);
1456 
1457  PRBool eqEnabled = mEqEnabled;
1458  rv = equalizer->SetEqEnabled(mEqEnabled);
1459  NS_ENSURE_SUCCESS(rv, rv);
1460 
1461  eqMon.Exit();
1462 
1463  if(eqEnabled) {
1464  nsCOMPtr<nsISimpleEnumerator> bands;
1465  rv = GetBands(getter_AddRefs(bands));
1466  NS_ENSURE_SUCCESS(rv, rv);
1467 
1468  rv = equalizer->SetBands(bands);
1469  NS_ENSURE_SUCCESS(rv, rv);
1470  }
1471  }
1472 
1473  return NS_OK;
1474 }
1475 
1476 // ----------------------------------------------------------------------------
1477 // sbIMediacoreFactoryRegistrar Interface
1478 // ----------------------------------------------------------------------------
1479 
1480 NS_IMETHODIMP
1481 sbMediacoreManager::GetFactories(nsIArray * *aFactories)
1482 {
1483  TRACE(("sbMediacoreManager[0x%x] - GetFactories", this));
1484  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1485  NS_ENSURE_ARG_POINTER(aFactories);
1486 
1487  nsresult rv = NS_ERROR_UNEXPECTED;
1488 
1489  nsCOMPtr<nsIMutableArray> mutableArray =
1490  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1491  NS_ENSURE_SUCCESS(rv, rv);
1492 
1493  nsAutoMonitor mon(mMonitor);
1494  mFactories.EnumerateRead(sbMediacoreManager::EnumerateIntoArrayISupportsKey,
1495  mutableArray.get());
1496 
1497  PRUint32 length = 0;
1498  rv = mutableArray->GetLength(&length);
1499  NS_ENSURE_SUCCESS(rv, rv);
1500 
1501  if(length < mFactories.Count()) {
1502  return NS_ERROR_FAILURE;
1503  }
1504 
1505  nsCOMPtr<nsIArray> array = do_QueryInterface(mutableArray, &rv);
1506  NS_ENSURE_SUCCESS(rv, rv);
1507 
1508  array.forget(aFactories);
1509 
1510  return NS_OK;
1511 }
1512 
1513 NS_IMETHODIMP
1514 sbMediacoreManager::GetInstances(nsIArray * *aInstances)
1515 {
1516  TRACE(("sbMediacoreManager[0x%x] - GetInstances", this));
1517  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1518  NS_ENSURE_ARG_POINTER(aInstances);
1519 
1520  nsresult rv = NS_ERROR_UNEXPECTED;
1521 
1522  nsCOMPtr<nsIMutableArray> mutableArray =
1523  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1524  NS_ENSURE_SUCCESS(rv, rv);
1525 
1526  nsAutoMonitor mon(mMonitor);
1527 
1528  mCores.EnumerateRead(sbMediacoreManager::EnumerateIntoArrayStringKey,
1529  mutableArray.get());
1530 
1531  PRUint32 length = 0;
1532  rv = mutableArray->GetLength(&length);
1533  NS_ENSURE_SUCCESS(rv, rv);
1534 
1535  if(length < mCores.Count()) {
1536  return NS_ERROR_FAILURE;
1537  }
1538 
1539  rv = CallQueryInterface(mutableArray, aInstances);
1540  NS_ENSURE_SUCCESS(rv, rv);
1541 
1542  return NS_OK;
1543 }
1544 
1545 NS_IMETHODIMP
1546 sbMediacoreManager::CreateMediacore(const nsAString & aContractID,
1547  const nsAString & aInstanceName,
1548  sbIMediacore **_retval)
1549 {
1550  TRACE(("sbMediacoreManager[0x%x] - CreateMediacore", this));
1551  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1552  NS_ENSURE_ARG_POINTER(_retval);
1553 
1554  nsresult rv = NS_ERROR_UNEXPECTED;
1555  NS_ConvertUTF16toUTF8 contractId(aContractID);
1556 
1557  nsCOMPtr<sbIMediacoreFactory> coreFactory =
1558  do_CreateInstance(contractId.BeginReading(), &rv);
1559  NS_ENSURE_SUCCESS(rv, rv);
1560 
1561  nsCOMPtr<sbIMediacore> core;
1562  rv = GetMediacore(aInstanceName, getter_AddRefs(core));
1563 
1564  if(NS_SUCCEEDED(rv)) {
1565  core.forget(_retval);
1566  return NS_OK;
1567  }
1568 
1569  nsAutoMonitor mon(mMonitor);
1570 
1571  rv = coreFactory->Create(aInstanceName, _retval);
1572  NS_ENSURE_SUCCESS(rv, rv);
1573 
1574  PRBool success = mCores.Put(aInstanceName, *_retval);
1575  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
1576 
1577  return NS_OK;
1578 }
1579 
1580 NS_IMETHODIMP
1581 sbMediacoreManager::CreateMediacoreWithFactory(sbIMediacoreFactory *aFactory,
1582  const nsAString & aInstanceName,
1583  sbIMediacore **_retval)
1584 {
1585  TRACE(("sbMediacoreManager[0x%x] - CreateMediacoreWithFactory", this));
1586  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1587  NS_ENSURE_ARG_POINTER(aFactory);
1588  NS_ENSURE_ARG_POINTER(_retval);
1589 
1590  nsCOMPtr<sbIMediacore> core;
1591  nsresult rv = GetMediacore(aInstanceName, getter_AddRefs(core));
1592 
1593  if(NS_SUCCEEDED(rv)) {
1594  core.forget(_retval);
1595  return NS_OK;
1596  }
1597 
1598  rv = aFactory->Create(aInstanceName, _retval);
1599  NS_ENSURE_SUCCESS(rv, rv);
1600 
1601  PRBool success = mCores.Put(aInstanceName, *_retval);
1602  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
1603 
1604  return NS_OK;
1605 }
1606 
1607 NS_IMETHODIMP
1608 sbMediacoreManager::GetMediacore(const nsAString & aInstanceName,
1609  sbIMediacore **_retval)
1610 {
1611  TRACE(("%s[%p] (%s)", __FUNCTION__, this,
1612  NS_ConvertUTF16toUTF8(aInstanceName).get()));
1613  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1614  NS_ENSURE_ARG_POINTER(_retval);
1615 
1616  nsCOMPtr<sbIMediacore> core;
1617 
1618  nsAutoMonitor mon(mMonitor);
1619 
1620  PRBool success = mCores.Get(aInstanceName, getter_AddRefs(core));
1621  NS_ENSURE_TRUE(success, NS_ERROR_NOT_AVAILABLE);
1622 
1623  core.forget(_retval);
1624 
1625  return NS_OK;
1626 }
1627 
1628 NS_IMETHODIMP
1629 sbMediacoreManager::DestroyMediacore(const nsAString & aInstanceName)
1630 {
1631  TRACE(("sbMediacoreManager[0x%x] - DestroyMediacore", this));
1632  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1633 
1634  nsCOMPtr<sbIMediacore> core;
1635 
1636  nsAutoMonitor mon(mMonitor);
1637 
1638  PRBool success = mCores.Get(aInstanceName, getter_AddRefs(core));
1639  NS_ENSURE_TRUE(success, NS_ERROR_NOT_AVAILABLE);
1640  NS_ENSURE_TRUE(core, NS_ERROR_UNEXPECTED);
1641 
1642  nsresult rv = core->Shutdown();
1643  NS_ENSURE_SUCCESS(rv, rv);
1644 
1645  mCores.Remove(aInstanceName);
1646 
1647  return NS_OK;
1648 }
1649 
1650 NS_IMETHODIMP
1651 sbMediacoreManager::RegisterFactory(sbIMediacoreFactory *aFactory)
1652 {
1653  TRACE(("sbMediacoreManager[0x%x] - RegisterFactory", this));
1654  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1655  NS_ENSURE_ARG_POINTER(aFactory);
1656 
1657  nsAutoMonitor mon(mMonitor);
1658 
1659  PRBool success = mFactories.Put(aFactory, aFactory);
1660  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
1661 
1662  return NS_OK;
1663 }
1664 
1665 NS_IMETHODIMP
1666 sbMediacoreManager::UnregisterFactory(sbIMediacoreFactory *aFactory)
1667 {
1668  TRACE(("sbMediacoreManager[0x%x] - UnregisterFactory", this));
1669  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1670  NS_ENSURE_ARG_POINTER(aFactory);
1671 
1672  nsAutoMonitor mon(mMonitor);
1673 
1674  mFactories.Remove(aFactory);
1675 
1676  return NS_OK;
1677 }
1678 
1679 
1680 // ----------------------------------------------------------------------------
1681 // sbIMediacoreVideoWindow Interface
1682 // ----------------------------------------------------------------------------
1683 
1684 NS_IMETHODIMP
1685 sbMediacoreManager::GetFullscreen(PRBool *aFullscreen)
1686 {
1687  TRACE(("sbMediacoreManager[0x%x] - GetFullscreen", this));
1688  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1689  NS_ENSURE_ARG_POINTER(aFullscreen);
1690 
1691  nsAutoMonitor mon(mMonitor);
1692 
1693  if(mPrimaryCore) {
1694  nsresult rv = NS_ERROR_UNEXPECTED;;
1695 
1696  nsCOMPtr<sbIMediacoreVideoWindow> videoWindow =
1697  do_QueryInterface(mPrimaryCore, &rv);
1698 
1699  if(NS_SUCCEEDED(rv)) {
1700  rv = videoWindow->GetFullscreen(aFullscreen);
1701  NS_ENSURE_SUCCESS(rv, rv);
1702 
1703  // If for some reason we get out of sync we should update now.
1704  if(*aFullscreen != mFullscreen) {
1705  mFullscreen = *aFullscreen;
1706 
1707  rv = mDataRemoteVideoFullscreen->SetBoolValue(mFullscreen);
1708  NS_ENSURE_SUCCESS(rv, rv);
1709  }
1710 
1711  return NS_OK;
1712  }
1713  }
1714 
1715  *aFullscreen = mFullscreen;
1716 
1717  return NS_OK;
1718 }
1719 
1720 NS_IMETHODIMP
1721 sbMediacoreManager::SetFullscreen(PRBool aFullscreen)
1722 {
1723  TRACE(("sbMediacoreManager[0x%x] - SetFullscreen", this));
1724  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1725 
1726  nsresult rv = NS_ERROR_UNEXPECTED;
1727 
1728  nsAutoMonitor mon(mMonitor);
1729  if(mPrimaryCore) {
1730  nsCOMPtr<sbIMediacoreVideoWindow> videoWindow =
1731  do_QueryInterface(mPrimaryCore, &rv);
1732 
1733  if(NS_SUCCEEDED(rv)) {
1734  rv = videoWindow->SetFullscreen(aFullscreen);
1735  NS_ENSURE_SUCCESS(rv, rv);
1736  }
1737  }
1738 
1739  mFullscreen = aFullscreen;
1740 
1741  rv = mDataRemoteVideoFullscreen->SetBoolValue(mFullscreen);
1742  NS_ENSURE_SUCCESS(rv, rv);
1743 
1744  return NS_OK;
1745 }
1746 
1747 NS_IMETHODIMP
1748 sbMediacoreManager::GetVideoWindow(nsIDOMXULElement * *aVideoWindow)
1749 {
1750  TRACE(("sbMediacoreManager[0x%x] - GetVideoWindow", this));
1751  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1752  NS_ENSURE_ARG_POINTER(aVideoWindow);
1753 
1754  nsAutoMonitor mon(mMonitor);
1755  NS_IF_ADDREF(*aVideoWindow = mVideoWindow);
1756 
1757  return NS_OK;
1758 }
1759 
1760 NS_IMETHODIMP
1761 sbMediacoreManager::SetVideoWindow(nsIDOMXULElement * aVideoWindow)
1762 {
1763  TRACE(("sbMediacoreManager[0x%x] - SetVideoWindow", this));
1764  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
1765  NS_ENSURE_ARG_POINTER(aVideoWindow);
1766 
1767  nsAutoMonitor mon(mMonitor);
1768  mVideoWindow = aVideoWindow;
1769 
1770  return NS_OK;
1771 }
1772 
1773 
1774 // ----------------------------------------------------------------------------
1775 // sbIMediacoreVoting Interface
1776 // ----------------------------------------------------------------------------
1777 
1778 NS_IMETHODIMP
1779 sbMediacoreManager::VoteWithURI(nsIURI *aURI,
1780  sbIMediacoreVotingChain **_retval)
1781 {
1782  TRACE(("sbMediacoreManager[0x%x] - VoteWithURI", this));
1783  NS_ENSURE_ARG_POINTER(aURI);
1784  NS_ENSURE_ARG_POINTER(_retval);
1785 
1786  nsresult rv = VoteWithURIOrChannel(aURI, nsnull, _retval);
1787  NS_ENSURE_SUCCESS(rv, rv);
1788 
1789  return NS_OK;
1790 }
1791 
1792 NS_IMETHODIMP
1793 sbMediacoreManager::VoteWithChannel(nsIChannel *aChannel,
1794  sbIMediacoreVotingChain **_retval)
1795 {
1796  TRACE(("sbMediacoreManager[0x%x] - VoteWithChannel", this));
1797  NS_ENSURE_ARG_POINTER(aChannel);
1798  NS_ENSURE_ARG_POINTER(_retval);
1799 
1800  nsresult rv = VoteWithURIOrChannel(nsnull, aChannel, _retval);
1801  NS_ENSURE_SUCCESS(rv, rv);
1802 
1803  return NS_OK;
1804 }
1805 
1806 
1807 // ----------------------------------------------------------------------------
1808 // nsIObserver Interface
1809 // ----------------------------------------------------------------------------
1810 
1811 NS_IMETHODIMP sbMediacoreManager::Observe(nsISupports *aSubject,
1812  const char *aTopic,
1813  const PRUnichar *aData)
1814 {
1815  TRACE(("sbMediacoreManager[0x%x] - Observe", this));
1816 
1817  nsresult rv = NS_ERROR_UNEXPECTED;
1818 
1819  if (!strcmp(aTopic, APPSTARTUP_CATEGORY)) {
1820  // listen for profile startup and profile shutdown messages
1821  nsCOMPtr<nsIObserverService> obsSvc =
1822  do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
1823  NS_ENSURE_SUCCESS(rv, rv);
1824 
1825  nsCOMPtr<nsIObserver> observer =
1826  do_QueryInterface(NS_ISUPPORTS_CAST(nsIObserver*, this), &rv);
1827  NS_ENSURE_SUCCESS(rv, rv);
1828 
1829  rv = obsSvc->AddObserver(observer, NS_PROFILE_STARTUP_OBSERVER_ID, PR_FALSE);
1830  NS_ENSURE_SUCCESS(rv, rv);
1831 
1832  rv = obsSvc->AddObserver(observer, NS_QUIT_APPLICATION_GRANTED_OBSERVER_ID, PR_FALSE);
1833  NS_ENSURE_SUCCESS(rv, rv);
1834 
1835  rv = obsSvc->AddObserver(observer, NS_PROFILE_SHUTDOWN_OBSERVER_ID, PR_FALSE);
1836  NS_ENSURE_SUCCESS(rv, rv);
1837 
1838  }
1839  else if (!strcmp(NS_PROFILE_STARTUP_OBSERVER_ID, aTopic)) {
1840 
1841  // Called after the profile has been loaded, so prefs and such are available
1842  rv = Init();
1843  NS_ENSURE_SUCCESS(rv, rv);
1844 
1845  }
1846  else if (!strcmp(NS_QUIT_APPLICATION_GRANTED_OBSERVER_ID, aTopic)) {
1847 
1848  // Called when the request to shutdown has been granted
1849  // We can't watch the -requested notification since it may not always be
1850  // fired :(
1851 
1852  // Pre-shutdown.
1853 
1854  // Remove the observer so we don't get called a second time, since we are
1855  // shutting down anyways this should not cause problems.
1856  nsCOMPtr<nsIObserverService> obsSvc =
1857  do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
1858  NS_ENSURE_SUCCESS(rv, rv);
1859 
1860  nsCOMPtr<nsIObserver> observer =
1861  do_QueryInterface(NS_ISUPPORTS_CAST(nsIObserver*, this), &rv);
1862  NS_ENSURE_SUCCESS(rv, rv);
1863 
1864  rv = obsSvc->RemoveObserver(observer, NS_QUIT_APPLICATION_GRANTED_OBSERVER_ID);
1865  NS_ENSURE_SUCCESS(rv, rv);
1866 
1867  rv = PreShutdown();
1868  NS_ENSURE_SUCCESS(rv, rv);
1869  }
1870  else if (!strcmp(NS_PROFILE_SHUTDOWN_OBSERVER_ID, aTopic)) {
1871 
1872  // Final shutdown.
1873 
1874  // remove all the observers
1875  nsCOMPtr<nsIObserverService> obsSvc =
1876  do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
1877  NS_ENSURE_SUCCESS(rv, rv);
1878 
1879  nsCOMPtr<nsIObserver> observer =
1880  do_QueryInterface(NS_ISUPPORTS_CAST(nsIObserver*, this), &rv);
1881  NS_ENSURE_SUCCESS(rv, rv);
1882 
1883  rv = obsSvc->RemoveObserver(observer, NS_PROFILE_STARTUP_OBSERVER_ID);
1884  NS_ENSURE_SUCCESS(rv, rv);
1885 
1886  rv = obsSvc->RemoveObserver(observer, NS_PROFILE_SHUTDOWN_OBSERVER_ID);
1887  NS_ENSURE_SUCCESS(rv, rv);
1888 
1889  rv = Shutdown();
1890  NS_ENSURE_SUCCESS(rv, rv);
1891  }
1892 
1893  return NS_OK;
1894 }
1895 
1896 NS_IMETHODIMP
1897 sbMediacoreManager::CreateEvent(PRUint32 aType,
1898  sbIMediacore *aOrigin,
1899  nsIVariant *aData,
1900  sbIMediacoreError *aError,
1901  sbIMediacoreEvent **retval)
1902 {
1903  NS_ENSURE_ARG_POINTER(aOrigin);
1904  NS_ENSURE_ARG_POINTER(retval);
1905 
1906  return sbMediacoreEvent::CreateEvent(aType, aError, aData, aOrigin, retval);
1907 }
1908 
1909 // Forwarding functions for sbIMediacoreEventTarget interface
1910 
1911 NS_IMETHODIMP
1912 sbMediacoreManager::DispatchEvent(sbIMediacoreEvent *aEvent,
1913  PRBool aAsync,
1914  PRBool* _retval)
1915 {
1916  return mBaseEventTarget ? mBaseEventTarget->DispatchEvent(aEvent, aAsync, _retval) : NS_ERROR_NULL_POINTER;
1917 }
1918 
1919 NS_IMETHODIMP
1920 sbMediacoreManager::AddListener(sbIMediacoreEventListener *aListener)
1921 {
1922  return mBaseEventTarget ? mBaseEventTarget->AddListener(aListener) : NS_ERROR_NULL_POINTER;
1923 }
1924 
1925 NS_IMETHODIMP
1926 sbMediacoreManager::RemoveListener(sbIMediacoreEventListener *aListener)
1927 {
1928  return mBaseEventTarget ? mBaseEventTarget->RemoveListener(aListener) : NS_ERROR_NULL_POINTER;
1929 }
1930 
1931 //-----------------------------------------------------------------------------
1932 // sbMediacoreVideoWindowListener class
1933 //-----------------------------------------------------------------------------
1938 
1939 sbMediacoreVideoWindowListener::sbMediacoreVideoWindowListener()
1940 : mWindowReady(PR_FALSE)
1941 {
1942 }
1943 
1945 {
1946 }
1947 
1948 nsresult
1950  nsIDOMEventTarget *aTarget)
1951 {
1952  NS_ENSURE_ARG_POINTER(aManager);
1953  NS_ENSURE_ARG_POINTER(aTarget);
1954 
1955  mManager = aManager;
1956  mTarget = aTarget;
1957 
1958  return NS_OK;
1959 }
1960 
1961 NS_IMETHODIMP
1962 sbMediacoreVideoWindowListener::HandleEvent(nsIDOMEvent *aEvent)
1963 {
1964  NS_ENSURE_TRUE(mManager, NS_ERROR_NOT_INITIALIZED);
1965 
1966  nsString eventType;
1967  nsresult rv = aEvent->GetType(eventType);
1968  NS_ENSURE_SUCCESS(rv, rv);
1969 
1970  if(eventType.EqualsLiteral("resize")) {
1971  mWindowReady = PR_TRUE;
1972  }
1973  else if(eventType.EqualsLiteral("unload")) {
1974  rv = mManager->VideoWindowUnloaded();
1975  NS_ENSURE_SUCCESS(rv, rv);
1976 
1977  nsCOMPtr<nsIDOMEventListener> grip(this);
1978  rv = mTarget->RemoveEventListener(NS_LITERAL_STRING("unload"),
1979  this,
1980  PR_FALSE);
1981  NS_ENSURE_SUCCESS(rv, rv);
1982  }
1983 
1984  return NS_OK;
1985 }
1986 
1987 PRBool
1989 {
1990  return mWindowReady;
1991 }
NS_IMPL_QUERY_INTERFACE1(sbMediacoreVideoWindowListener, nsIDOMEventListener) sbMediacoreVideoWindowListener
return NS_OK
nsCOMPtr< sbIDataRemote > mDataRemoteFaceplateVolume
#define SB_MEDIACORE_DATAREMOTE_FACEPLATE_VOLUME
nsInterfaceHashtableMT< nsUint32HashKey, sbIDataRemote > mDataRemoteEqualizerBands
#define NS_PROFILE_STARTUP_OBSERVER_ID
virtual nsresult OnInitBaseMediacoreVolumeControl()
#define SB_CORE_HASHTABLE_SIZE
#define SB_MEDIACORE_DATAREMOTE_FACEPLATE_MUTE
virtual nsresult OnGetBandCount(PRUint32 *aBandCount)
inArray array
nsCOMPtr< nsIDOMEventTarget > mTarget
#define SB_EQUALIZER_BANDS
void SB_ConvertFloatVolToJSStringValue(PRFloat64 aVol, nsACString &aStrVol)
readonly attribute sbIMediacoreMultibandEqualizer equalizer
readonly attribute sbIMediacoreStatus status
virtual nsresult OnSetEqEnabled(PRBool aEqEnabled)
virtual nsresult OnSetBand(sbIMediacoreEqualizerBand *aBand)
attribute sbIMediacoreSequencer sequencer
NS_IMPL_THREADSAFE_CI(sbMediaListEnumeratorWrapper)
nsresult Init(sbMediacoreManager *aManager, nsIDOMEventTarget *aTarget)
nsresult SetAndEnsureEQBandHasDataRemote(sbIMediacoreEqualizerBand *aBand)
nsresult do_GetProxyForObject(nsIEventTarget *aTarget, REFNSIID aIID, nsISupports *aObj, PRInt32 aProxyType, void **aProxyObject)
#define TRACE(args)
readonly attribute sbIMediacoreBalanceControl balanceControl
void SB_ConvertFloatEqGainToJSStringValue(double aGain, nsCString &aGainStr)
nsCOMPtr< sbIDataRemote > mDataRemoteFaceplateMute
#define SONGBIRD_PROMPTER_CONTRACTID
nsresult GetAndEnsureEQBandHasDataRemote(PRUint32 aBandIndex, sbIDataRemote **aRemote)
An interface for accessing, and binding to, stored data.
PRMonitor * mVideoWindowMonitor
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
readonly attribute sbIMediacorePlaybackControl playbackControl
#define SB_MEDIACORE_DATAREMOTE_VIDEO_FULLSCREEN
nsresult VoteWithURIOrChannel(nsIURI *aURI, nsIChannel *aChannel, sbIMediacoreVotingChain **_retval)
Definition of the sbIMediacoreEvent interface.
#define SB_PVW_ELEMENT_ID
#define SB_WINDOWWATCHER_CONTRACTID
const nsIDOMWindow
attribute boolean eqEnabled
Whether the EQ is enabled or not.
#define SB_MEDIACORE_DATAREMOTE_EQ_BAND_PREFIX
attribute nsIDOMXULElement videoWindow
DOM XUL Element used as the video box.
#define SB_EQUALIZER_DEFAULT_BAND_GAIN
#define SB_EQUALIZER_DEFAULT_BAND_COUNT
nsCOMPtr< sbIDataRemote > mDataRemoteEqualizerEnabled
nsInterfaceHashtableMT< nsISupportsHashKey, sbIMediacoreFactory > mFactories
#define SB_MEDIACORE_FACTORY_CATEGORY
#define NS_PROFILE_SHUTDOWN_OBSERVER_ID
const nsIChannel
const unsigned long STATUS_UNKNOWN
attribute nsISimpleEnumerator bands
Enumerator containing all available bands.
#define SB_CORE_BASE_NAME
virtual nsresult OnSetMute(PRBool aMute)
Songbird Mediacore Voting Chain Definition.
PLDHashOperator appendElementToArray(T *aData, void *aArray)
static nsresult CreateEvent(PRUint32 aType, sbIMediacoreError *aError, nsIVariant *aData, sbIMediacore *aOrigin, sbIMediacoreEvent **retval)
#define SB_PVW_NAME
nsCOMPtr< sbIMediacore > mPrimaryCore
nsCOMPtr< nsIDOMXULElement > mVideoWindow
#define SB_PVW_CHROME_URL
StringArrayEnumerator prototype hasMore
const unsigned long STATUS_STOPPED
sbIJobCancelable NS_DECL_CLASSINFO(sbGstreamerMediaInspector)
NS_INTERFACE_MAP_END NS_IMPL_CI_INTERFACE_GETTER5(sbLocalDatabaseMediaItem, nsIClassInfo, nsISupportsWeakReference, nsIRequestObserver, sbILibraryResource, sbIMediaItem) sbLocalDatabaseMediaItem
#define NS_QUIT_APPLICATION_GRANTED_OBSERVER_ID
nsInterfaceHashtableMT< nsStringHashKey, sbIMediacore > mCores
#define SB_MEDIACORE_DATAREMOTE_EQ_ENABLED
nsresult CreateDataRemoteForEqualizerBand(PRUint32 aBandIndex, sbIDataRemote **aRemote)
nsresult GenerateInstanceName(nsAString &aInstanceName)
readonly attribute sbIMediacoreVolumeControl volumeControl
virtual nsresult OnInitBaseMediacoreMultibandEqualizer()
#define LOG(args)
_getSelectedPageStyle s i
#define SB_FACTORY_HASHTABLE_SIZE
nsRefPtr< sbMediacoreManager > mManager
nsresult SetVolumeDataRemote(PRFloat64 aVolume)
virtual nsresult OnGetBand(PRUint32 aBandIndex, sbIMediacoreEqualizerBand *aBand)
nsIDOMEventListener
#define SB_CORE_NAME_SUFFIX
function dataRemote(aKey, aRoot)
nsAutoPtr< sbBaseMediacoreEventTarget > mBaseEventTarget
let observer
NS_IMPL_QUERY_INTERFACE11_CI(sbMediacoreManager, sbIMediacoreManager, sbPIMediacoreManager, sbIMediacoreEventTarget, sbIMediacoreFactoryRegistrar, sbIMediacoreVideoWindow, sbIMediacoreMultibandEqualizer, sbIMediacoreVolumeControl, sbIMediacoreVoting, nsISupportsWeakReference, nsIClassInfo, nsIObserver) NS_IMPL_CI_INTERFACE_GETTER5(sbMediacoreManager
var cm
_updateTextAndScrollDataForFrame aData
nsCOMPtr< sbIDataRemote > mDataRemoteVideoFullscreen
virtual nsresult OnSetVolume(PRFloat64 aVolume)
nsCOMPtr< sbIMediacoreSequencer > mSequencer