gecko-dev/dom/inputport/FakeInputPortService.cpp

209 строки
5.9 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 "FakeInputPortService.h"
#include "InputPortData.h"
#include "mozilla/dom/InputPort.h"
#include "nsIMutableArray.h"
#include "nsITimer.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
namespace mozilla {
namespace dom {
namespace {
class InputPortServiceNotifyRunnable final : public nsRunnable
{
public:
InputPortServiceNotifyRunnable(
nsIInputPortServiceCallback* aCallback,
nsIArray* aDataList,
uint16_t aErrorCode = nsIInputPortServiceCallback::INPUTPORT_ERROR_OK)
: mCallback(aCallback)
, mDataList(aDataList)
, mErrorCode(aErrorCode)
{
MOZ_ASSERT(aCallback);
MOZ_ASSERT(aDataList);
}
NS_IMETHOD Run() override
{
if (mErrorCode == nsIInputPortServiceCallback::INPUTPORT_ERROR_OK) {
return mCallback->NotifySuccess(mDataList);
} else {
return mCallback->NotifyError(mErrorCode);
}
}
private:
nsCOMPtr<nsIInputPortServiceCallback> mCallback;
nsCOMPtr<nsIArray> mDataList;
uint16_t mErrorCode;
};
class PortConnectionChangedCallback final : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
PortConnectionChangedCallback(nsIInputPortData* aInputPortData,
nsIInputPortListener* aInputPortListener,
const bool aIsConnected)
: mInputPortData(aInputPortData)
, mInputPortListener(aInputPortListener)
, mIsConnected(aIsConnected)
{}
NS_IMETHOD
Notify(nsITimer* aTimer) override
{
InputPortData* portData = static_cast<InputPortData*>(mInputPortData.get());
portData->SetConnected(mIsConnected);
nsresult rv = mInputPortListener->NotifyConnectionChanged(
portData->GetId(), mIsConnected);
return rv;
}
private:
~PortConnectionChangedCallback() {}
nsCOMPtr<nsIInputPortData> mInputPortData;
nsCOMPtr<nsIInputPortListener> mInputPortListener;
bool mIsConnected;
};
} // namespace
NS_IMPL_ISUPPORTS(PortConnectionChangedCallback, nsITimerCallback)
NS_IMPL_CYCLE_COLLECTION_CLASS(FakeInputPortService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FakeInputPortService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInputPortListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPortConnectionChangedTimer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPortDatas)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FakeInputPortService)
tmp->Shutdown();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mInputPortListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPortConnectionChangedTimer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPortDatas)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(FakeInputPortService)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FakeInputPortService)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FakeInputPortService)
NS_INTERFACE_MAP_ENTRY(nsIInputPortService)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
FakeInputPortService::FakeInputPortService()
{
Init();
}
FakeInputPortService::~FakeInputPortService()
{
Shutdown();
}
void
FakeInputPortService::Init()
{
nsCOMPtr<nsIInputPortData> portData1 =
MockInputPort(NS_LITERAL_STRING("1"), NS_LITERAL_STRING("av"), true);
mPortDatas.AppendElement(portData1);
nsCOMPtr<nsIInputPortData> portData2 =
MockInputPort(NS_LITERAL_STRING("2"), NS_LITERAL_STRING("displayport"), false);
mPortDatas.AppendElement(portData2);
nsCOMPtr<nsIInputPortData> portData3 =
MockInputPort(NS_LITERAL_STRING("3"), NS_LITERAL_STRING("hdmi"), true);
mPortDatas.AppendElement(portData3);
}
void
FakeInputPortService::Shutdown()
{
if (mPortConnectionChangedTimer) {
mPortConnectionChangedTimer->Cancel();
}
}
/* virtual */ NS_IMETHODIMP
FakeInputPortService::GetInputPortListener(nsIInputPortListener** aInputPortListener)
{
if (!mInputPortListener) {
*aInputPortListener = nullptr;
return NS_OK;
}
*aInputPortListener = mInputPortListener;
NS_ADDREF(*aInputPortListener);
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
FakeInputPortService::SetInputPortListener(nsIInputPortListener* aInputPortListener)
{
mInputPortListener = aInputPortListener;
return NS_OK;
}
/* virtual */ NS_IMETHODIMP
FakeInputPortService::GetInputPorts(nsIInputPortServiceCallback* aCallback)
{
if (!aCallback) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIMutableArray> portDataList = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!portDataList) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t i = 0; i < mPortDatas.Length(); i++) {
portDataList->AppendElement(mPortDatas[i], false);
}
mPortConnectionChangedTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_TRUE(mPortConnectionChangedTimer, NS_ERROR_OUT_OF_MEMORY);
bool isConnected = false;
mPortDatas[0]->GetConnected(&isConnected);
//simulate the connection change event.
nsRefPtr<PortConnectionChangedCallback> connectionChangedCb =
new PortConnectionChangedCallback(mPortDatas[0], mInputPortListener, !isConnected);
nsresult rv = mPortConnectionChangedTimer->InitWithCallback(
connectionChangedCb, 100, nsITimer::TYPE_ONE_SHOT);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIRunnable> runnable =
new InputPortServiceNotifyRunnable(aCallback, portDataList);
return NS_DispatchToCurrentThread(runnable);
}
already_AddRefed<nsIInputPortData>
FakeInputPortService::MockInputPort(const nsAString& aId,
const nsAString& aType,
bool aIsConnected)
{
nsCOMPtr<nsIInputPortData> portData = new InputPortData();
portData->SetId(aId);
portData->SetType(aType);
portData->SetConnected(aIsConnected);
return portData.forget();
}
} // namespace dom
} // namespace mozilla