mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
9fd132e8a3
- Bug 1153248, re-enable a bunch of tests that now work with e10s, r=billm (c7d1a1d95) - Bug 1113086 - AudioChannel policy in Browser API - patch 1 - BrowserElementAudioChannel, r=ehsan (b25164d4f) - Bug 1158798 - Properly initialize the LookAndFeel cache in the child. r=mstange. (0f4232b5c) - Bug 1113086 - AudioChannel policy in Browser API - patch 2 - IPC communication between AudioChannelServices, r=ehsan (a2132f4d4) - Bug 1113086 - AudioChannel policy in Browser API - patch 3 - right management of audiochannel-activity events in child processes, r=ehsan (d1bd88e79) - Bug 1150727 - Enable software vsync refresh driver on Linux. r=kats (a991d3c25) - Bug 1113086 - AudioChannel policy in Browser API - patch 4 - Muted by default, e=alwu (a8978ef69) - Bug 1167064 - Patch3: Update mochitests for switching to Bluetooth APIv2. r=bz (f02729d0d) - Bug 1113086 - AudioChannel policy in Browser API - patch 5 - nsTObserverArray instead hashtables, r=ehsan, r=alwu (8f9aa5d4f) - Bug 1113086 - AudioChannel policy in Browser API - patch 6 - media-playback has to be dispatched async, r=alwu (da4da2207) - Bug 1113086 - AudioChannel policy in Browser API - patch 7 - Support non-app iframe, r=alwu (7078c3df5) - Bug 1174733 - Browser API: iframe.executeScript. r=kanru, r=bholley (5e19f9186) - Bug 1146355: Prepare build system to support Bluetooth APIs v1 and v2, r=shuang (ffe7bf5ef) - Bug 1156716: Build GATT backend as part of Bluetooth v1, r=joliu (033da499a) - Bug 1168343 - Remove the improper MOZ_ASSERT in |BluetoothServiceBluedroid::BondStateChangedNotification|. r=shuang (10d398b57) - Bug 1128386 - Handle |STATUS_FAIL| in |BondStateChangedNotification()|. r=tzimmermann (0bb76982f) - Bug 1164498: Remove |DispatchBluetoothReply| from |BluetoothServiceBluedroid|, r=btian (c027eb350) - Bug 1167064 - Patch1: Switch to bluetooth APIv2. r=shuang (37c775331) - Bug 1153717 - [Stingray] Update document reference link on InputPort API. r=baku, a=NPOTB (550bd985d) - Bug 1179718 - Rename CheckPermissions to CheckAnyPermissions. r=bz (b8e4bf1b7) - Bug 1152702 - Fix upper bounds of ContiguousEnumSerializer for BluetoothStatus and BluetoothSspVariant. r=tzimmermann (30ec5dc1a) - Bug 1162893 - Fix BluetoothGattWriteType serialization problem. f=elin, r=jocelyn (d36e089da) - Bug 1152631 - We no longer display category data for platform data in call tree, r=jsantell (6e2e877a0) - Bug 1164338 - Tests that the style markers have restyleHints. r=pbrosset (d6c357832) - Bug 1058898 - Enable e10s tests on the performance tool. r=vp (18c8324c3) - Bug 814497 - Fix nsScriptErrorWithStack constructor. r=ehsan (8096b8a8a) - Bug 814497 followup: Add missing 'override' keyword to nsScriptErrorWithStack method 'GetStack'. rs=ehsan (30889b974)
487 lines
14 KiB
C++
487 lines
14 KiB
C++
/* 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 "BrowserElementAudioChannel.h"
|
|
|
|
#include "mozilla/Services.h"
|
|
#include "mozilla/dom/BrowserElementAudioChannelBinding.h"
|
|
#include "mozilla/dom/DOMRequest.h"
|
|
#include "mozilla/dom/ToJSValue.h"
|
|
#include "AudioChannelService.h"
|
|
#include "nsIBrowserElementAPI.h"
|
|
#include "nsIDocShell.h"
|
|
#include "nsIDOMDOMRequest.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsISupportsPrimitives.h"
|
|
#include "nsITabParent.h"
|
|
#include "nsPIDOMWindow.h"
|
|
|
|
namespace {
|
|
|
|
void
|
|
AssertIsInMainProcess()
|
|
{
|
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
NS_IMPL_ADDREF_INHERITED(BrowserElementAudioChannel, DOMEventTargetHelper)
|
|
NS_IMPL_RELEASE_INHERITED(BrowserElementAudioChannel, DOMEventTargetHelper)
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BrowserElementAudioChannel)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(BrowserElementAudioChannel,
|
|
DOMEventTargetHelper,
|
|
mFrameLoader,
|
|
mFrameWindow,
|
|
mTabParent,
|
|
mBrowserElementAPI)
|
|
|
|
BrowserElementAudioChannel::BrowserElementAudioChannel(
|
|
nsPIDOMWindow* aWindow,
|
|
nsIFrameLoader* aFrameLoader,
|
|
nsIBrowserElementAPI* aAPI,
|
|
AudioChannel aAudioChannel)
|
|
: DOMEventTargetHelper(aWindow)
|
|
, mFrameLoader(aFrameLoader)
|
|
, mBrowserElementAPI(aAPI)
|
|
, mAudioChannel(aAudioChannel)
|
|
, mState(eStateUnknown)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
MOZ_ASSERT(mFrameLoader);
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
if (obs) {
|
|
nsAutoString name;
|
|
AudioChannelService::GetAudioChannelString(aAudioChannel, name);
|
|
|
|
nsAutoCString topic;
|
|
topic.Assign("audiochannel-activity-");
|
|
topic.Append(NS_ConvertUTF16toUTF8(name));
|
|
|
|
obs->AddObserver(this, topic.get(), true);
|
|
}
|
|
}
|
|
|
|
BrowserElementAudioChannel::~BrowserElementAudioChannel()
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
if (obs) {
|
|
nsAutoString name;
|
|
AudioChannelService::GetAudioChannelString(mAudioChannel, name);
|
|
|
|
nsAutoCString topic;
|
|
topic.Assign("audiochannel-activity-");
|
|
topic.Append(NS_ConvertUTF16toUTF8(name));
|
|
|
|
obs->RemoveObserver(this, topic.get());
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
BrowserElementAudioChannel::Initialize()
|
|
{
|
|
nsCOMPtr<nsIDocShell> docShell;
|
|
nsresult rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
if (docShell) {
|
|
nsCOMPtr<nsPIDOMWindow> window = docShell->GetWindow();
|
|
if (!window) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mFrameWindow = window->GetScriptableTop();
|
|
mFrameWindow = mFrameWindow->GetOuterWindow();
|
|
return NS_OK;
|
|
}
|
|
|
|
rv = mFrameLoader->GetTabParent(getter_AddRefs(mTabParent));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
MOZ_ASSERT(mTabParent);
|
|
return NS_OK;
|
|
}
|
|
|
|
JSObject*
|
|
BrowserElementAudioChannel::WrapObject(JSContext *aCx,
|
|
JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return BrowserElementAudioChannelBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
AudioChannel
|
|
BrowserElementAudioChannel::Name() const
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
return mAudioChannel;
|
|
}
|
|
|
|
namespace {
|
|
|
|
class BaseRunnable : public nsRunnable
|
|
{
|
|
protected:
|
|
nsCOMPtr<nsPIDOMWindow> mParentWindow;
|
|
nsCOMPtr<nsPIDOMWindow> mFrameWindow;
|
|
nsRefPtr<DOMRequest> mRequest;
|
|
AudioChannel mAudioChannel;
|
|
|
|
virtual void DoWork(AudioChannelService* aService,
|
|
JSContext* aCx) = 0;
|
|
|
|
public:
|
|
BaseRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel)
|
|
: mParentWindow(aParentWindow)
|
|
, mFrameWindow(aFrameWindow)
|
|
, mRequest(aRequest)
|
|
, mAudioChannel(aAudioChannel)
|
|
{}
|
|
|
|
NS_IMETHODIMP Run() override
|
|
{
|
|
nsRefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
|
|
MOZ_ASSERT(service);
|
|
|
|
AutoJSAPI jsapi;
|
|
if (!jsapi.Init(mParentWindow)) {
|
|
mRequest->FireError(NS_ERROR_FAILURE);
|
|
return NS_OK;
|
|
}
|
|
|
|
DoWork(service, jsapi.cx());
|
|
return NS_OK;
|
|
}
|
|
};
|
|
|
|
class GetVolumeRunnable final : public BaseRunnable
|
|
{
|
|
public:
|
|
GetVolumeRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel)
|
|
: BaseRunnable(aParentWindow, aFrameWindow, aRequest, aAudioChannel)
|
|
{}
|
|
|
|
protected:
|
|
virtual void DoWork(AudioChannelService* aService, JSContext* aCx) override
|
|
{
|
|
float volume = aService->GetAudioChannelVolume(mFrameWindow, mAudioChannel);
|
|
|
|
JS::Rooted<JS::Value> value(aCx);
|
|
if (!ToJSValue(aCx, volume, &value)) {
|
|
mRequest->FireError(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
mRequest->FireSuccess(value);
|
|
}
|
|
};
|
|
|
|
class GetMutedRunnable final : public BaseRunnable
|
|
{
|
|
public:
|
|
GetMutedRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel)
|
|
: BaseRunnable(aParentWindow, aFrameWindow, aRequest, aAudioChannel)
|
|
{}
|
|
|
|
protected:
|
|
virtual void DoWork(AudioChannelService* aService, JSContext* aCx) override
|
|
{
|
|
bool muted = aService->GetAudioChannelMuted(mFrameWindow, mAudioChannel);
|
|
|
|
JS::Rooted<JS::Value> value(aCx);
|
|
if (!ToJSValue(aCx, muted, &value)) {
|
|
mRequest->FireError(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
mRequest->FireSuccess(value);
|
|
}
|
|
};
|
|
|
|
class IsActiveRunnable final : public BaseRunnable
|
|
{
|
|
bool mActive;
|
|
bool mValueKnown;
|
|
|
|
public:
|
|
IsActiveRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel,
|
|
bool aActive)
|
|
: BaseRunnable(aParentWindow, aFrameWindow, aRequest, aAudioChannel)
|
|
, mActive(aActive)
|
|
, mValueKnown(true)
|
|
{}
|
|
|
|
IsActiveRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel)
|
|
: BaseRunnable(aParentWindow, aFrameWindow, aRequest, aAudioChannel)
|
|
, mActive(true)
|
|
, mValueKnown(false)
|
|
{}
|
|
|
|
protected:
|
|
virtual void DoWork(AudioChannelService* aService, JSContext* aCx) override
|
|
{
|
|
if (!mValueKnown) {
|
|
mActive = aService->IsAudioChannelActive(mFrameWindow, mAudioChannel);
|
|
}
|
|
|
|
JS::Rooted<JS::Value> value(aCx);
|
|
if (!ToJSValue(aCx, mActive, &value)) {
|
|
mRequest->FireError(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
mRequest->FireSuccess(value);
|
|
}
|
|
};
|
|
|
|
class FireSuccessRunnable final : public BaseRunnable
|
|
{
|
|
public:
|
|
FireSuccessRunnable(nsPIDOMWindow* aParentWindow, nsPIDOMWindow* aFrameWindow,
|
|
DOMRequest* aRequest, AudioChannel aAudioChannel)
|
|
: BaseRunnable(aParentWindow, aFrameWindow, aRequest, aAudioChannel)
|
|
{}
|
|
|
|
protected:
|
|
virtual void DoWork(AudioChannelService* aService, JSContext* aCx) override
|
|
{
|
|
JS::Rooted<JS::Value> value(aCx);
|
|
mRequest->FireSuccess(value);
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
already_AddRefed<dom::DOMRequest>
|
|
BrowserElementAudioChannel::GetVolume(ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
if (!mFrameWindow) {
|
|
nsCOMPtr<nsIDOMDOMRequest> request;
|
|
aRv = mBrowserElementAPI->GetAudioChannelVolume((uint32_t)mAudioChannel,
|
|
getter_AddRefs(request));
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget().downcast<DOMRequest>();
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new GetVolumeRunnable(GetOwner(), mFrameWindow, domRequest, mAudioChannel);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
already_AddRefed<dom::DOMRequest>
|
|
BrowserElementAudioChannel::SetVolume(float aVolume, ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
if (!mFrameWindow) {
|
|
nsCOMPtr<nsIDOMDOMRequest> request;
|
|
aRv = mBrowserElementAPI->SetAudioChannelVolume((uint32_t)mAudioChannel,
|
|
aVolume,
|
|
getter_AddRefs(request));
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget().downcast<DOMRequest>();
|
|
}
|
|
|
|
nsRefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
|
|
MOZ_ASSERT(service);
|
|
|
|
service->SetAudioChannelVolume(mFrameWindow, mAudioChannel, aVolume);
|
|
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
nsCOMPtr<nsIRunnable> runnable = new FireSuccessRunnable(GetOwner(),
|
|
mFrameWindow,
|
|
domRequest,
|
|
mAudioChannel);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
already_AddRefed<dom::DOMRequest>
|
|
BrowserElementAudioChannel::GetMuted(ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
if (!mFrameWindow) {
|
|
nsCOMPtr<nsIDOMDOMRequest> request;
|
|
aRv = mBrowserElementAPI->GetAudioChannelMuted((uint32_t)mAudioChannel,
|
|
getter_AddRefs(request));
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget().downcast<DOMRequest>();
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new GetMutedRunnable(GetOwner(), mFrameWindow, domRequest, mAudioChannel);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
already_AddRefed<dom::DOMRequest>
|
|
BrowserElementAudioChannel::SetMuted(bool aMuted, ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
if (!mFrameWindow) {
|
|
nsCOMPtr<nsIDOMDOMRequest> request;
|
|
aRv = mBrowserElementAPI->SetAudioChannelMuted((uint32_t)mAudioChannel,
|
|
aMuted,
|
|
getter_AddRefs(request));
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget().downcast<DOMRequest>();
|
|
}
|
|
|
|
nsRefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
|
|
MOZ_ASSERT(service);
|
|
|
|
service->SetAudioChannelMuted(mFrameWindow, mAudioChannel, aMuted);
|
|
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
nsCOMPtr<nsIRunnable> runnable = new FireSuccessRunnable(GetOwner(),
|
|
mFrameWindow,
|
|
domRequest,
|
|
mAudioChannel);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
already_AddRefed<dom::DOMRequest>
|
|
BrowserElementAudioChannel::IsActive(ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
AssertIsInMainProcess();
|
|
|
|
if (mState != eStateUnknown) {
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new IsActiveRunnable(GetOwner(), mFrameWindow, domRequest, mAudioChannel,
|
|
mState == eStateActive);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
if (!mFrameWindow) {
|
|
nsCOMPtr<nsIDOMDOMRequest> request;
|
|
aRv = mBrowserElementAPI->IsAudioChannelActive((uint32_t)mAudioChannel,
|
|
getter_AddRefs(request));
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget().downcast<DOMRequest>();
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
|
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
new IsActiveRunnable(GetOwner(), mFrameWindow, domRequest, mAudioChannel);
|
|
NS_DispatchToMainThread(runnable);
|
|
|
|
return domRequest.forget();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BrowserElementAudioChannel::Observe(nsISupports* aSubject, const char* aTopic,
|
|
const char16_t* aData)
|
|
{
|
|
nsAutoString name;
|
|
AudioChannelService::GetAudioChannelString(mAudioChannel, name);
|
|
|
|
nsAutoCString topic;
|
|
topic.Assign("audiochannel-activity-");
|
|
topic.Append(NS_ConvertUTF16toUTF8(name));
|
|
|
|
if (strcmp(topic.get(), aTopic)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// Message received from the child.
|
|
if (!mFrameWindow) {
|
|
if (mTabParent == aSubject) {
|
|
ProcessStateChanged(aData);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
|
if (NS_WARN_IF(!wrapper)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
uint64_t windowID;
|
|
nsresult rv = wrapper->GetData(&windowID);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
if (windowID != mFrameWindow->WindowID()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
ProcessStateChanged(aData);
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
BrowserElementAudioChannel::ProcessStateChanged(const char16_t* aData)
|
|
{
|
|
nsAutoString value(aData);
|
|
mState = value.EqualsASCII("active") ? eStateActive : eStateInactive;
|
|
DispatchTrustedEvent(NS_LITERAL_STRING("activestatechanged"));
|
|
}
|
|
|
|
} // dom namespace
|
|
} // mozilla namespace
|