/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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_SerialPortParent_h #define mozilla_dom_SerialPortParent_h #include "mozilla/dom/PSerialPortParent.h" #include "mozilla/dom/SerialPlatformService.h" #include "mozilla/ipc/DataPipe.h" #include "nsISupports.h" namespace mozilla::dom { class SerialDeviceChangeProxy; namespace webserial { class SerialPortReadPump; class SerialPortWritePump; } // namespace webserial // Parent-side actor for a serial port. Bound to the SerialPlatformService IO // thread so const that I/O operations can be performed directly without // dispatching to a separate thread. Data flows through DataPipes; control // messages (Drain, Flush, Close) use IPC. Note that non-const members are only // safe to access on the SerialPlatformService's IOThread. class SerialPortParent final : public PSerialPortParent { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SerialPortParent, override) mozilla::ipc::IPCResult RecvOpen(const IPCSerialOptions& aOptions, OpenResolver&& aResolver); mozilla::ipc::IPCResult RecvClose(CloseResolver&& aResolver); mozilla::ipc::IPCResult RecvSetSignals(const IPCSerialOutputSignals& aSignals, SetSignalsResolver&& aResolver); mozilla::ipc::IPCResult RecvGetSignals(GetSignalsResolver&& aResolver); mozilla::ipc::IPCResult RecvDrain(DrainResolver&& aResolver); mozilla::ipc::IPCResult RecvFlush(bool aReceive, FlushResolver&& aResolver); mozilla::ipc::IPCResult RecvAttachReadPipe( const RefPtr& aReadPipeSender); mozilla::ipc::IPCResult RecvAttachWritePipe( const RefPtr& aWritePipeReceiver); mozilla::ipc::IPCResult RecvUpdateSharingState(bool aConnected); mozilla::ipc::IPCResult RecvClone( mozilla::ipc::Endpoint&& aEndpoint); void ActorDestroy(ActorDestroyReason aWhy) override; bool PortIdMatches(const nsAString& aPortId) const { return mPortId == aPortId; } // Called by SerialManagerParent when device connection state changes. void NotifyConnected(); void NotifyDisconnected(); SerialPortParent(const nsString& aPortId, uint64_t aBrowserId, SerialDeviceChangeProxy* aProxy = nullptr); private: ~SerialPortParent(); void StopPumps(); void StopReadPump(); void StopWritePump(); void NotifySharingStateChanged(bool aConnected); void StartReadPump( already_AddRefed aReadPipeSender); void StartWritePump( already_AddRefed aWritePipeReceiver); const nsString mPortId; const uint64_t mBrowserId; bool mIsOpen = false; // Whether we have forwarded a connected=true sharing state notification // without a corresponding connected=false. Used by ActorDestroy to send the // missing disconnect so the browser sharing indicator count stays in sync. bool mSharingConnected = false; uint32_t mPipeCapacity = 0; // DataPipe endpoints held by the parent: the read pump writes device data // to mReadPipeSender, and the write pump reads JS data from // mWritePipeReceiver. RefPtr mReadPipeSender; RefPtr mWritePipeReceiver; RefPtr mReadPump; RefPtr mWritePump; RefPtr mDeviceChangeProxy; // Cloned actors sharing the same underlying port. When we get a // connect/disconnect notification, we forward it to all clones too. nsTArray> mClones; }; } // namespace mozilla::dom #endif // mozilla_dom_SerialPortParent_h