gecko/dom/speakermanager/SpeakerManagerService.cpp

225 lines
6.3 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeakerManagerService.h"
#include "SpeakerManagerServiceChild.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/unused.h"
#include "mozilla/dom/ContentParent.h"
#include "nsIPropertyBag2.h"
#include "nsThreadUtils.h"
#include "nsServiceManagerUtils.h"
#include "AudioChannelService.h"
#include <cutils/properties.h>
#define NS_AUDIOMANAGER_CONTRACTID "@mozilla.org/telephony/audiomanager;1"
#include "nsIAudioManager.h"
using namespace mozilla;
using namespace mozilla::dom;
StaticRefPtr<SpeakerManagerService> gSpeakerManagerService;
// static
SpeakerManagerService*
SpeakerManagerService::GetOrCreateSpeakerManagerService()
{
MOZ_ASSERT(NS_IsMainThread());
if (!XRE_IsParentProcess()) {
return SpeakerManagerServiceChild::GetOrCreateSpeakerManagerService();
}
// If we already exist, exit early
if (gSpeakerManagerService) {
return gSpeakerManagerService;
}
// Create new instance, register, return
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi
2015-10-17 22:24:48 -07:00
RefPtr<SpeakerManagerService> service = new SpeakerManagerService();
gSpeakerManagerService = service;
return gSpeakerManagerService;
}
SpeakerManagerService*
SpeakerManagerService::GetSpeakerManagerService()
{
MOZ_ASSERT(NS_IsMainThread());
if (!XRE_IsParentProcess()) {
return SpeakerManagerServiceChild::GetSpeakerManagerService();
}
return gSpeakerManagerService;
}
void
SpeakerManagerService::Shutdown()
{
if (!XRE_IsParentProcess()) {
return SpeakerManagerServiceChild::Shutdown();
}
if (gSpeakerManagerService) {
gSpeakerManagerService = nullptr;
}
}
NS_IMPL_ISUPPORTS(SpeakerManagerService, nsIObserver)
void
SpeakerManagerService::ForceSpeaker(bool aEnable, uint64_t aChildId)
{
TurnOnSpeaker(aEnable);
if (aEnable) {
mSpeakerStatusSet.Put(aChildId);
}
Notify();
return;
}
void
SpeakerManagerService::ForceSpeaker(bool aEnable, bool aVisible)
{
// b2g main process without oop
TurnOnSpeaker(aEnable && aVisible);
mVisible = aVisible;
mOrgSpeakerStatus = aEnable;
Notify();
}
void
SpeakerManagerService::TurnOnSpeaker(bool aOn)
{
nsCOMPtr<nsIAudioManager> audioManager = do_GetService(NS_AUDIOMANAGER_CONTRACTID);
NS_ENSURE_TRUE_VOID(audioManager);
int32_t phoneState;
audioManager->GetPhoneState(&phoneState);
int32_t forceuse = (phoneState == nsIAudioManager::PHONE_STATE_IN_CALL ||
phoneState == nsIAudioManager::PHONE_STATE_IN_COMMUNICATION)
? nsIAudioManager::USE_COMMUNICATION : nsIAudioManager::USE_MEDIA;
if (aOn) {
audioManager->SetForceForUse(forceuse, nsIAudioManager::FORCE_SPEAKER);
} else {
audioManager->SetForceForUse(forceuse, nsIAudioManager::FORCE_NONE);
}
}
bool
SpeakerManagerService::GetSpeakerStatus()
{
char propQemu[PROPERTY_VALUE_MAX];
property_get("ro.kernel.qemu", propQemu, "");
if (!strncmp(propQemu, "1", 1)) {
return mOrgSpeakerStatus;
}
nsCOMPtr<nsIAudioManager> audioManager = do_GetService(NS_AUDIOMANAGER_CONTRACTID);
NS_ENSURE_TRUE(audioManager, false);
int32_t usage;
audioManager->GetForceForUse(nsIAudioManager::USE_MEDIA, &usage);
return usage == nsIAudioManager::FORCE_SPEAKER;
}
void
SpeakerManagerService::Notify()
{
// Parent Notify to all the child processes.
nsTArray<ContentParent*> children;
ContentParent::GetAll(children);
for (uint32_t i = 0; i < children.Length(); i++) {
Unused << children[i]->SendSpeakerManagerNotify();
}
for (uint32_t i = 0; i < mRegisteredSpeakerManagers.Length(); i++) {
mRegisteredSpeakerManagers[i]->
DispatchSimpleEvent(NS_LITERAL_STRING("speakerforcedchange"));
}
}
void
SpeakerManagerService::SetAudioChannelActive(bool aIsActive)
{
if (!aIsActive && !mVisible) {
ForceSpeaker(!mOrgSpeakerStatus, mVisible);
}
}
NS_IMETHODIMP
SpeakerManagerService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, "ipc:content-shutdown")) {
nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
if (!props) {
NS_WARNING("ipc:content-shutdown message without property bag as subject");
return NS_OK;
}
uint64_t childID = 0;
nsresult rv = props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"),
&childID);
if (NS_SUCCEEDED(rv)) {
// If the audio has paused by audiochannel,
// the enable flag should be false and don't need to handle.
if (mSpeakerStatusSet.Contains(childID)) {
TurnOnSpeaker(false);
mSpeakerStatusSet.Remove(childID);
}
if (mOrgSpeakerStatus) {
TurnOnSpeaker(!mOrgSpeakerStatus);
mOrgSpeakerStatus = false;
}
} else {
NS_WARNING("ipc:content-shutdown message without childID property");
}
} else if (!strcmp(aTopic, "xpcom-will-shutdown")) {
// Note that we need to do this before xpcom-shutdown, since the
// AudioChannelService cannot be used past that point.
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi
2015-10-17 22:24:48 -07:00
RefPtr<AudioChannelService> audioChannelService =
AudioChannelService::GetOrCreate();
if (audioChannelService) {
audioChannelService->UnregisterSpeakerManager(this);
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, "ipc:content-shutdown");
obs->RemoveObserver(this, "xpcom-will-shutdown");
}
Shutdown();
}
return NS_OK;
}
SpeakerManagerService::SpeakerManagerService()
: mOrgSpeakerStatus(false),
mVisible(false)
{
MOZ_COUNT_CTOR(SpeakerManagerService);
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(this, "ipc:content-shutdown", false);
obs->AddObserver(this, "xpcom-will-shutdown", false);
}
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi
2015-10-17 22:24:48 -07:00
RefPtr<AudioChannelService> audioChannelService =
AudioChannelService::GetOrCreate();
if (audioChannelService) {
audioChannelService->RegisterSpeakerManager(this);
}
}
SpeakerManagerService::~SpeakerManagerService()
{
MOZ_COUNT_DTOR(SpeakerManagerService);
}