mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1167465 - Exposing Allowed Audio Channels in System App's Window, r=alwu, r=fabrice
This commit is contained in:
parent
71920a9550
commit
5bd948cce6
@ -498,6 +498,11 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"system-app-only-audio-channels-in-app": {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"killswitch": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
|
@ -45,6 +45,24 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(BrowserElementAudioChannel,
|
||||
mTabParent,
|
||||
mBrowserElementAPI)
|
||||
|
||||
/* static */ already_AddRefed<BrowserElementAudioChannel>
|
||||
BrowserElementAudioChannel::Create(nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
AudioChannel aAudioChannel,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<BrowserElementAudioChannel> ac =
|
||||
new BrowserElementAudioChannel(aWindow, aFrameLoader, aAPI, aAudioChannel);
|
||||
|
||||
aRv = ac->Initialize();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ac.forget();
|
||||
}
|
||||
|
||||
BrowserElementAudioChannel::BrowserElementAudioChannel(
|
||||
nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
@ -58,7 +76,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsInMainProcess();
|
||||
MOZ_ASSERT(mFrameLoader);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
@ -94,6 +111,20 @@ BrowserElementAudioChannel::~BrowserElementAudioChannel()
|
||||
nsresult
|
||||
BrowserElementAudioChannel::Initialize()
|
||||
{
|
||||
if (!mFrameLoader) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||
if (!window) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
window->GetScriptableTop(getter_AddRefs(topWindow));
|
||||
|
||||
mFrameWindow = do_QueryInterface(topWindow);
|
||||
mFrameWindow = mFrameWindow->GetOuterWindow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
nsresult rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -35,12 +35,12 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BrowserElementAudioChannel,
|
||||
DOMEventTargetHelper)
|
||||
|
||||
BrowserElementAudioChannel(nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
AudioChannel aAudioChannel);
|
||||
|
||||
nsresult Initialize();
|
||||
static already_AddRefed<BrowserElementAudioChannel>
|
||||
Create(nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
AudioChannel aAudioChannel,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// WebIDL methods
|
||||
|
||||
@ -60,8 +60,15 @@ public:
|
||||
IMPL_EVENT_HANDLER(activestatechanged);
|
||||
|
||||
private:
|
||||
BrowserElementAudioChannel(nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
AudioChannel aAudioChannel);
|
||||
|
||||
~BrowserElementAudioChannel();
|
||||
|
||||
nsresult Initialize();
|
||||
|
||||
void ProcessStateChanged(const char16_t* aData);
|
||||
|
||||
nsCOMPtr<nsIFrameLoader> mFrameLoader;
|
||||
|
@ -563,69 +563,84 @@ nsBrowserElement::GetAllowedAudioChannels(
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService("@mozilla.org/AppsService;1");
|
||||
if (NS_WARN_IF(!appsService)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
aRv = appsService->GetAppByManifestURL(manifestURL, getter_AddRefs(app));
|
||||
GenerateAllowedAudioChannels(window, frameLoader, mBrowserElementAPI,
|
||||
manifestURL, mBrowserElementAudioChannels,
|
||||
aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal is always allowed.
|
||||
nsTArray<nsRefPtr<BrowserElementAudioChannel>> channels;
|
||||
aAudioChannels.AppendElements(mBrowserElementAudioChannels);
|
||||
}
|
||||
|
||||
nsRefPtr<BrowserElementAudioChannel> ac =
|
||||
new BrowserElementAudioChannel(window, frameLoader, mBrowserElementAPI,
|
||||
AudioChannel::Normal);
|
||||
/* static */ void
|
||||
nsBrowserElement::GenerateAllowedAudioChannels(
|
||||
nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
const nsAString& aManifestURL,
|
||||
nsTArray<nsRefPtr<BrowserElementAudioChannel>>& aAudioChannels,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aAudioChannels.IsEmpty());
|
||||
|
||||
aRv = ac->Initialize();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService("@mozilla.org/AppsService;1");
|
||||
if (NS_WARN_IF(!appsService)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
channels.AppendElement(ac);
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
aRv = appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (app) {
|
||||
const nsAttrValue::EnumTable* audioChannelTable =
|
||||
AudioChannelService::GetAudioChannelTable();
|
||||
// Normal is always allowed.
|
||||
nsTArray<nsRefPtr<BrowserElementAudioChannel>> channels;
|
||||
|
||||
bool allowed;
|
||||
nsAutoCString permissionName;
|
||||
nsRefPtr<BrowserElementAudioChannel> ac =
|
||||
BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
|
||||
AudioChannel::Normal, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
|
||||
permissionName.AssignASCII("audio-channel-");
|
||||
permissionName.AppendASCII(audioChannelTable[i].tag);
|
||||
channels.AppendElement(ac);
|
||||
|
||||
aRv = app->HasPermission(permissionName.get(), &allowed);
|
||||
if (app) {
|
||||
const nsAttrValue::EnumTable* audioChannelTable =
|
||||
AudioChannelService::GetAudioChannelTable();
|
||||
|
||||
bool allowed;
|
||||
nsAutoCString permissionName;
|
||||
|
||||
for (uint32_t i = 0; audioChannelTable && audioChannelTable[i].tag; ++i) {
|
||||
permissionName.AssignASCII("audio-channel-");
|
||||
permissionName.AppendASCII(audioChannelTable[i].tag);
|
||||
|
||||
aRv = app->HasPermission(permissionName.get(), &allowed);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allowed) {
|
||||
nsRefPtr<BrowserElementAudioChannel> ac =
|
||||
BrowserElementAudioChannel::Create(aWindow, aFrameLoader, aAPI,
|
||||
(AudioChannel)audioChannelTable[i].value,
|
||||
aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allowed) {
|
||||
nsRefPtr<BrowserElementAudioChannel> ac =
|
||||
new BrowserElementAudioChannel(window, frameLoader,
|
||||
mBrowserElementAPI,
|
||||
(AudioChannel)audioChannelTable[i].value);
|
||||
|
||||
aRv = ac->Initialize();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
channels.AppendElement(ac);
|
||||
}
|
||||
channels.AppendElement(ac);
|
||||
}
|
||||
}
|
||||
|
||||
mBrowserElementAudioChannels.AppendElements(channels);
|
||||
}
|
||||
|
||||
aAudioChannels.AppendElements(mBrowserElementAudioChannels);
|
||||
aAudioChannels.SwapElements(channels);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
|
@ -117,6 +117,15 @@ public:
|
||||
void SetNFCFocus(bool isFocus,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Helper
|
||||
static void GenerateAllowedAudioChannels(
|
||||
nsPIDOMWindow* aWindow,
|
||||
nsIFrameLoader* aFrameLoader,
|
||||
nsIBrowserElementAPI* aAPI,
|
||||
const nsAString& aManifestURL,
|
||||
nsTArray<nsRefPtr<dom::BrowserElementAudioChannel>>& aAudioChannels,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() = 0;
|
||||
void InitBrowserElementAPI();
|
||||
|
@ -2,6 +2,8 @@
|
||||
* 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 "nsIAppsService.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
@ -11,6 +13,7 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "AudioChannelManager.h"
|
||||
#include "mozilla/dom/AudioChannelManagerBinding.h"
|
||||
#include "mozilla/dom/nsBrowserElement.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
using namespace mozilla::hal;
|
||||
@ -149,6 +152,70 @@ AudioChannelManager::HandleEvent(nsIDOMEvent* aEvent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
AudioChannelManager::GetAllowedAudioChannels(
|
||||
nsTArray<nsRefPtr<BrowserElementAudioChannel>>& aAudioChannels,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aAudioChannels.IsEmpty());
|
||||
|
||||
// Only main process is supported.
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetOwner();
|
||||
if (NS_WARN_IF(!window)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
|
||||
MOZ_ASSERT(principal);
|
||||
|
||||
uint16_t status;
|
||||
if (NS_WARN_IF(NS_FAILED(principal->GetAppStatus(&status)))) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status != nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t appId;
|
||||
aRv = principal->GetAppId(&appId);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService("@mozilla.org/AppsService;1");
|
||||
if (NS_WARN_IF(!appsService)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString manifestURL;
|
||||
aRv = appsService->GetManifestURLByLocalId(appId, manifestURL);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsBrowserElement::GenerateAllowedAudioChannels(window, nullptr, nullptr,
|
||||
manifestURL, aAudioChannels,
|
||||
aRv);
|
||||
NS_WARN_IF(aRv.Failed());
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef mozilla_dom_system_AudioChannelManager_h
|
||||
#define mozilla_dom_system_AudioChannelManager_h
|
||||
|
||||
#include "mozilla/dom/BrowserElementAudioChannel.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/HalTypes.h"
|
||||
@ -65,6 +66,10 @@ public:
|
||||
|
||||
IMPL_EVENT_HANDLER(headphoneschange)
|
||||
|
||||
void GetAllowedAudioChannels(
|
||||
nsTArray<nsRefPtr<mozilla::dom::BrowserElementAudioChannel>>& aAudioChannels,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
virtual ~AudioChannelManager();
|
||||
|
||||
|
@ -29,4 +29,9 @@ interface AudioChannelManager : EventTarget {
|
||||
* volume keys.
|
||||
*/
|
||||
attribute DOMString volumeControlChannel;
|
||||
|
||||
[Pure, Cached, Throws,
|
||||
Pref="dom.mozBrowserFramesEnabled",
|
||||
CheckAnyPermissions="system-app-only-audio-channels-in-app"]
|
||||
readonly attribute sequence<BrowserElementAudioChannel> allowedAudioChannels;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user