gecko-dev/dom/presentation/PresentationDeviceManager.cpp

337 строки
8.8 KiB
C++
Исходник Обычный вид История

/* -*- 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 "PresentationDeviceManager.h"
#include "mozilla/Services.h"
#include "MainThreadUtils.h"
#include "nsArrayUtils.h"
#include "nsCategoryCache.h"
#include "nsCOMPtr.h"
#include "nsIMutableArray.h"
#include "nsIObserverService.h"
#include "nsXULAppAPI.h"
#include "PresentationSessionRequest.h"
#include "PresentationTerminateRequest.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(PresentationDeviceManager,
nsIPresentationDeviceManager,
nsIPresentationDeviceListener,
nsIObserver,
nsISupportsWeakReference)
PresentationDeviceManager::PresentationDeviceManager()
{
}
PresentationDeviceManager::~PresentationDeviceManager()
{
UnloadDeviceProviders();
mDevices.Clear();
}
void
PresentationDeviceManager::Init()
{
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
}
LoadDeviceProviders();
}
void
PresentationDeviceManager::Shutdown()
{
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
UnloadDeviceProviders();
}
void
PresentationDeviceManager::LoadDeviceProviders()
{
MOZ_ASSERT(mProviders.IsEmpty());
nsCategoryCache<nsIPresentationDeviceProvider> providerCache(PRESENTATION_DEVICE_PROVIDER_CATEGORY);
providerCache.GetEntries(mProviders);
for (uint32_t i = 0; i < mProviders.Length(); ++i) {
mProviders[i]->SetListener(this);
}
}
void
PresentationDeviceManager::UnloadDeviceProviders()
{
for (uint32_t i = 0; i < mProviders.Length(); ++i) {
mProviders[i]->SetListener(nullptr);
}
mProviders.Clear();
}
void
PresentationDeviceManager::NotifyDeviceChange(nsIPresentationDevice* aDevice,
const char16_t* aType)
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->NotifyObservers(aDevice,
PRESENTATION_DEVICE_CHANGE_TOPIC,
aType);
}
}
// nsIPresentationDeviceManager
NS_IMETHODIMP
PresentationDeviceManager::ForceDiscovery()
{
MOZ_ASSERT(NS_IsMainThread());
for (uint32_t i = 0; i < mProviders.Length(); ++i) {
mProviders[i]->ForceDiscovery();
}
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::AddDeviceProvider(nsIPresentationDeviceProvider* aProvider)
{
NS_ENSURE_ARG(aProvider);
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(mProviders.Contains(aProvider))) {
return NS_OK;
}
mProviders.AppendElement(aProvider);
aProvider->SetListener(this);
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::RemoveDeviceProvider(nsIPresentationDeviceProvider* aProvider)
{
NS_ENSURE_ARG(aProvider);
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(!mProviders.RemoveElement(aProvider))) {
return NS_ERROR_FAILURE;
}
aProvider->SetListener(nullptr);
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::GetDeviceAvailable(bool* aRetVal)
{
NS_ENSURE_ARG_POINTER(aRetVal);
MOZ_ASSERT(NS_IsMainThread());
*aRetVal = !mDevices.IsEmpty();
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::GetAvailableDevices(nsIArray* aPresentationUrls, nsIArray** aRetVal)
{
NS_ENSURE_ARG_POINTER(aRetVal);
MOZ_ASSERT(NS_IsMainThread());
// Bug 1194049: some providers may discontinue discovery after timeout.
// Call |ForceDiscovery()| here to make sure device lists are updated.
NS_DispatchToMainThread(
NewRunnableMethod(this, &PresentationDeviceManager::ForceDiscovery));
nsTArray<nsString> presentationUrls;
if (aPresentationUrls) {
uint32_t length;
nsresult rv = aPresentationUrls->GetLength(&length);
if (NS_SUCCEEDED(rv)) {
for (uint32_t i = 0; i < length; ++i) {
nsCOMPtr<nsISupportsString> isupportStr =
do_QueryElementAt(aPresentationUrls, i);
nsAutoString presentationUrl;
rv = isupportStr->GetData(presentationUrl);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
presentationUrls.AppendElement(presentationUrl);
}
}
}
nsCOMPtr<nsIMutableArray> devices = do_CreateInstance(NS_ARRAY_CONTRACTID);
for (uint32_t i = 0; i < mDevices.Length(); ++i) {
if (presentationUrls.IsEmpty()) {
devices->AppendElement(mDevices[i], false);
continue;
}
for (uint32_t j = 0; j < presentationUrls.Length(); ++j) {
bool isSupported;
if (NS_SUCCEEDED(mDevices[i]->IsRequestedUrlSupported(presentationUrls[i],
&isSupported)) &&
isSupported) {
devices->AppendElement(mDevices[i], false);
break;
}
}
}
devices.forget(aRetVal);
return NS_OK;
}
// nsIPresentationDeviceListener
NS_IMETHODIMP
PresentationDeviceManager::AddDevice(nsIPresentationDevice* aDevice)
{
NS_ENSURE_ARG(aDevice);
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(mDevices.Contains(aDevice))) {
return NS_ERROR_FAILURE;
}
mDevices.AppendElement(aDevice);
NotifyDeviceChange(aDevice, u"add");
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::RemoveDevice(nsIPresentationDevice* aDevice)
{
NS_ENSURE_ARG(aDevice);
MOZ_ASSERT(NS_IsMainThread());
int32_t index = mDevices.IndexOf(aDevice);
if (NS_WARN_IF(index < 0)) {
return NS_ERROR_FAILURE;
}
mDevices.RemoveElementAt(index);
NotifyDeviceChange(aDevice, u"remove");
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::UpdateDevice(nsIPresentationDevice* aDevice)
{
NS_ENSURE_ARG(aDevice);
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(!mDevices.Contains(aDevice))) {
return NS_ERROR_FAILURE;
}
NotifyDeviceChange(aDevice, u"update");
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::OnSessionRequest(nsIPresentationDevice* aDevice,
const nsAString& aUrl,
const nsAString& aPresentationId,
nsIPresentationControlChannel* aControlChannel)
{
NS_ENSURE_ARG(aDevice);
NS_ENSURE_ARG(aControlChannel);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
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 --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PresentationSessionRequest> request =
new PresentationSessionRequest(aDevice, aUrl, aPresentationId, aControlChannel);
obs->NotifyObservers(request,
PRESENTATION_SESSION_REQUEST_TOPIC,
nullptr);
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::OnTerminateRequest(nsIPresentationDevice* aDevice,
const nsAString& aPresentationId,
nsIPresentationControlChannel* aControlChannel,
bool aIsFromReceiver)
{
NS_ENSURE_ARG(aDevice);
NS_ENSURE_ARG(aControlChannel);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
RefPtr<PresentationTerminateRequest> request =
new PresentationTerminateRequest(aDevice, aPresentationId,
aControlChannel, aIsFromReceiver);
obs->NotifyObservers(request,
PRESENTATION_TERMINATE_REQUEST_TOPIC,
nullptr);
return NS_OK;
}
NS_IMETHODIMP
PresentationDeviceManager::OnReconnectRequest(nsIPresentationDevice* aDevice,
const nsAString& aUrl,
const nsAString& aPresentationId,
nsIPresentationControlChannel* aControlChannel)
{
NS_ENSURE_ARG(aDevice);
NS_ENSURE_ARG(aControlChannel);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
RefPtr<PresentationSessionRequest> request =
new PresentationSessionRequest(aDevice, aUrl, aPresentationId, aControlChannel);
obs->NotifyObservers(request,
PRESENTATION_RECONNECT_REQUEST_TOPIC,
nullptr);
return NS_OK;
}
// nsIObserver
NS_IMETHODIMP
PresentationDeviceManager::Observe(nsISupports *aSubject,
const char *aTopic,
const char16_t *aData)
{
if (!strcmp(aTopic, "profile-after-change")) {
Init();
} else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
Shutdown();
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla