dom/speakermanager/SpeakerManager.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "SpeakerManager.h"
     6 #include "nsIDOMClassInfo.h"
     7 #include "nsIDOMEvent.h"
     8 #include "nsIDOMEventListener.h"
     9 #include "SpeakerManagerService.h"
    10 #include "nsIPermissionManager.h"
    11 #include "nsIInterfaceRequestorUtils.h"
    12 #include "nsIDocShell.h"
    13 #include "AudioChannelService.h"
    15 namespace mozilla {
    16 namespace dom {
    18 NS_IMPL_QUERY_INTERFACE_INHERITED(SpeakerManager, DOMEventTargetHelper,
    19                                   nsIDOMEventListener)
    20 NS_IMPL_ADDREF_INHERITED(SpeakerManager, DOMEventTargetHelper)
    21 NS_IMPL_RELEASE_INHERITED(SpeakerManager, DOMEventTargetHelper)
    23 SpeakerManager::SpeakerManager()
    24   : mForcespeaker(false)
    25   , mVisible(false)
    26 {
    27   SetIsDOMBinding();
    28   SpeakerManagerService *service =
    29     SpeakerManagerService::GetSpeakerManagerService();
    30   if (service) {
    31     service->RegisterSpeakerManager(this);
    32   }
    33 }
    35 SpeakerManager::~SpeakerManager()
    36 {
    37   SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
    38   if (service) {
    39     service->UnRegisterSpeakerManager(this);
    40   }
    41   nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner());
    42   NS_ENSURE_TRUE_VOID(target);
    44   target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
    45                                     this,
    46                                     /* useCapture = */ true);
    47 }
    49 bool
    50 SpeakerManager::Speakerforced()
    51 {
    52   // If a background app calls forcespeaker=true that doesn't change anything.
    53   // 'speakerforced' remains false everywhere.
    54   if (mForcespeaker && !mVisible) {
    55     return false;
    56   }
    57   SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
    58   if (service) {
    59     return service->GetSpeakerStatus();
    60   }
    61   return false;
    62 }
    64 bool
    65 SpeakerManager::Forcespeaker()
    66 {
    67   return mForcespeaker;
    68 }
    70 void
    71 SpeakerManager::SetForcespeaker(bool aEnable)
    72 {
    73   SpeakerManagerService *service = SpeakerManagerService::GetSpeakerManagerService();
    74   if (service) {
    75     service->ForceSpeaker(aEnable, mVisible);
    76   }
    77   mForcespeaker = aEnable;
    78 }
    80 void
    81 SpeakerManager::DispatchSimpleEvent(const nsAString& aStr)
    82 {
    83   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
    84   nsresult rv = CheckInnerWindowCorrectness();
    85   if (NS_FAILED(rv)) {
    86     return;
    87   }
    89   nsCOMPtr<nsIDOMEvent> event;
    90   rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
    91   if (NS_FAILED(rv)) {
    92     NS_WARNING("Failed to create the error event!!!");
    93     return;
    94   }
    95   rv = event->InitEvent(aStr, false, false);
    97   if (NS_FAILED(rv)) {
    98     NS_WARNING("Failed to init the error event!!!");
    99     return;
   100   }
   102   event->SetTrusted(true);
   104   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   105   if (NS_FAILED(rv)) {
   106     NS_ERROR("Failed to dispatch the event!!!");
   107     return;
   108   }
   109 }
   111 void
   112 SpeakerManager::Init(nsPIDOMWindow* aWindow)
   113 {
   114   BindToOwner(aWindow);
   116   nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
   117   NS_ENSURE_TRUE_VOID(docshell);
   118   docshell->GetIsActive(&mVisible);
   120   nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
   121   NS_ENSURE_TRUE_VOID(target);
   123   target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
   124                                  this,
   125                                  /* useCapture = */ true,
   126                                  /* wantsUntrusted = */ false);
   127 }
   129 nsPIDOMWindow*
   130 SpeakerManager::GetParentObject() const
   131 {
   132   return GetOwner();
   133 }
   135 /* static */ already_AddRefed<SpeakerManager>
   136 SpeakerManager::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
   137 {
   138   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal.GetAsSupports());
   139   if (!sgo) {
   140     aRv.Throw(NS_ERROR_FAILURE);
   141     return nullptr;
   142   }
   144   nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aGlobal.GetAsSupports());
   145   if (!ownerWindow) {
   146     aRv.Throw(NS_ERROR_FAILURE);
   147     return nullptr;
   148   }
   150   nsCOMPtr<nsIPermissionManager> permMgr =
   151     do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
   152   NS_ENSURE_TRUE(permMgr, nullptr);
   154   uint32_t permission = nsIPermissionManager::DENY_ACTION;
   155   nsresult rv =
   156     permMgr->TestPermissionFromWindow(ownerWindow, "speaker-control",
   157                                       &permission);
   158   NS_ENSURE_SUCCESS(rv, nullptr);
   160   if (permission != nsIPermissionManager::ALLOW_ACTION) {
   161     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
   162     return nullptr;
   163   }
   165   nsRefPtr<SpeakerManager> object = new SpeakerManager();
   166   object->Init(ownerWindow);
   167   return object.forget();
   168 }
   170 JSObject*
   171 SpeakerManager::WrapObject(JSContext* aCx)
   172 {
   173   return MozSpeakerManagerBinding::Wrap(aCx, this);
   174 }
   176 NS_IMETHODIMP
   177 SpeakerManager::HandleEvent(nsIDOMEvent* aEvent)
   178 {
   179   nsAutoString type;
   180   aEvent->GetType(type);
   182   if (!type.EqualsLiteral("visibilitychange")) {
   183     return NS_ERROR_FAILURE;
   184   }
   186   nsCOMPtr<nsIDocShell> docshell = do_GetInterface(GetOwner());
   187   NS_ENSURE_TRUE(docshell, NS_ERROR_FAILURE);
   188   docshell->GetIsActive(&mVisible);
   190   // If an app that has called forcespeaker=true is switched
   191   // from the background to the foreground 'speakerforced'
   192   // switches to true in all apps. I.e. the app doesn't have to
   193   // call forcespeaker=true again when it comes into foreground.
   194   SpeakerManagerService *service =
   195     SpeakerManagerService::GetSpeakerManagerService();
   196   if (service && mVisible && mForcespeaker) {
   197     service->ForceSpeaker(mForcespeaker, mVisible);
   198   }
   199   // If an application that has called forcespeaker=true, but no audio is
   200   // currently playing in the app itself, if application switch to
   201   // the background, we switch 'speakerforced' to false.
   202   if (!mVisible && mForcespeaker) {
   203     AudioChannelService* audioChannelService =
   204       AudioChannelService::GetAudioChannelService();
   205     if (audioChannelService && !audioChannelService->AnyAudioChannelIsActive()) {
   206       service->ForceSpeaker(false, mVisible);
   207     }
   208   }
   209   return NS_OK;
   210 }
   212 void
   213 SpeakerManager::SetAudioChannelActive(bool isActive)
   214 {
   215   if (!isActive && !mVisible) {
   216     SpeakerManagerService *service =
   217       SpeakerManagerService::GetSpeakerManagerService();
   218     if (service) {
   219       service->ForceSpeaker(false, mVisible);
   220     }
   221   }
   222 }
   224 } // namespace dom
   225 } // namespace mozilla

mercurial