Source code

Revision control

Copy as Markdown

Other Tools

/* 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/. */
#ifndef mozilla_dom_SerialManagerParent_h
#define mozilla_dom_SerialManagerParent_h
#include "mozilla/Mutex.h"
#include "mozilla/dom/PSerialManagerParent.h"
#include "mozilla/dom/SerialPlatformService.h"
#include "mozilla/ipc/Endpoint.h"
#include "nsIObserver.h"
namespace mozilla::dom {
class SerialPermissionRequest;
class SerialPortParent;
// Thread-safe proxy that forwards device change notifications to port actors
// that were created by this manager on the IO thread. Holds a copy of the
// port actor list so it can dispatch without going through the main thread
// manager. Also observes serial-permission-revoked notifications on the main
// thread and closes all PSerialPort actors for the matching browser.
class SerialDeviceChangeProxy final : public SerialDeviceChangeObserver,
public nsIObserver {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
explicit SerialDeviceChangeProxy(
uint64_t aBrowserId, RefPtr<SerialPlatformService> aPlatformService);
void AddPortActor(SerialPortParent* aActor);
void RemovePortActor(SerialPortParent* aActor);
// Close all tracked port actors (dispatched to IO thread). Used when
// serial permissions are revoked for the owning browsing context.
void RevokeAllPorts();
void OnPortConnected(const IPCSerialPortInfo& aPortInfo) override;
void OnPortDisconnected(const nsAString& aPortId) override;
private:
~SerialDeviceChangeProxy();
nsTArray<RefPtr<SerialPortParent>> ActorsById(const nsAString& aPortId);
Mutex mMutex{"SerialDeviceChangeProxy"};
nsTArray<RefPtr<SerialPortParent>> mPortActors MOZ_GUARDED_BY(mMutex);
const uint64_t mBrowserId;
// Guaranteed non-null: the proxy is only created once the manager has a
// valid platform service.
const RefPtr<SerialPlatformService> mPlatformService;
};
// Parent-side actor for PSerialManager, managed by PWindowGlobal.
// Runs on the main thread.
class SerialManagerParent final : public PSerialManagerParent {
public:
NS_INLINE_DECL_REFCOUNTING(SerialManagerParent, override)
SerialManagerParent();
void Init(uint64_t aBrowserId);
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvRequestPort(
nsTArray<IPCSerialPortFilter>&& aFilters,
nsTArray<nsString>&& aAllowedBluetoothServiceClassIds, bool aAutoselect,
RequestPortResolver&& aResolver);
mozilla::ipc::IPCResult RecvSimulateDeviceConnection(
const nsString& aDeviceId, const nsString& aDevicePath,
uint16_t aVendorId, uint16_t aProductId,
const nsString& aBluetoothServiceClassId,
SimulateDeviceConnectionResolver&& aResolver);
mozilla::ipc::IPCResult RecvSimulateDeviceDisconnection(
const nsString& aDeviceId,
SimulateDeviceDisconnectionResolver&& aResolver);
mozilla::ipc::IPCResult RecvRemoveAllMockDevices(
RemoveAllMockDevicesResolver&& aResolver);
mozilla::ipc::IPCResult RecvResetToDefaultMockDevices(
ResetToDefaultMockDevicesResolver&& aResolver);
private:
~SerialManagerParent();
// Main-thread continuation of RecvRequestPort. Constructs the chooser
// request from the (now main-thread-safe) actor state and starts it.
void StartChooserRequest(bool aAutoselect,
nsTArray<IPCSerialPortInfo>&& aPorts,
RequestPortResolver&& aResolver);
// Creates a PSerialPort endpoint pair and binds the parent endpoint to a
// new SerialPortParent on the IO thread. Returns the child endpoint, or a
// default-constructed invalid endpoint on failure.
mozilla::ipc::Endpoint<PSerialPortChild> CreateAndBindPortActor(
const nsAString& aPortId);
template <typename TWork, typename TResolver>
mozilla::ipc::IPCResult DispatchTestOperation(const char* aName,
TWork&& aWork,
TResolver&& aResolver);
uint64_t mBrowserId = 0;
// Set in Init() and guaranteed non-null for the lifetime of the actor: if
// the platform service is unavailable, Init() tears the actor down.
RefPtr<SerialPlatformService> mPlatformService;
RefPtr<SerialDeviceChangeProxy> mProxy;
// Whether there is a currently outstanding chooser request. If true,
// a new chooser request is rejected.
bool mChooserRequestInFlight = false;
};
} // namespace mozilla::dom
#endif // mozilla_dom_SerialManagerParent_h