/* -*- 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_SerialPort_h #define mozilla_dom_SerialPort_h #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/SerialPortChild.h" #include "mozilla/dom/SerialPortInfo.h" #include "mozilla/dom/WorkerRef.h" namespace mozilla::ipc { class DataPipeReceiver; class DataPipeSender; } // namespace mozilla::ipc namespace mozilla::dom { class Promise; class ReadableStream; class Serial; class SerialPortReadAlgorithms; class SerialPortWriteAlgorithms; class WritableStream; struct SerialOptions; struct SerialOutputSignals; struct SerialPortInfo; class SerialPort final : public DOMEventTargetHelper { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SerialPort, DOMEventTargetHelper) SerialPort(const IPCSerialPortInfo& aInfo, Serial* aSerial); void EventListenerAdded(nsAtom* aType) override; void EventListenerRemoved(nsAtom* aType) override; JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; already_AddRefed Open(const SerialOptions& aOptions, ErrorResult& aRv); already_AddRefed SetSignals(const SerialOutputSignals& aSignals, ErrorResult& aRv); already_AddRefed GetSignals(ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed Close(ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed Forget(ErrorResult& aRv); // Mark this port as forgotten without the full Forget() flow (no IPC, // no manager callback). Used when another context (e.g. a worker) has // already performed the forget and the manager has been updated. MOZ_CAN_RUN_SCRIPT void MarkForgotten(); // https://wicg.github.io/serial/#dom-serialport-connected // Returns this.[[connected]]: whether the device is physically connected. bool Connected() const { return mPhysicallyPresent; } bool IsForgotten() const { return mForgottenState == ForgottenState::Forgotten; } // Returns whether the device is physically connected to the system. // This does not indicate whether the port is open or being used. bool PhysicallyPresent() const { return mPhysicallyPresent; } // Silently marks this port as physically present without dispatching a // connect event. Used when returning a port from requestPort(), since the // port is guaranteed to be connected (GetAvailablePorts only lists connected // devices) but the async RecvPortConnected notification may not have arrived. void MarkPhysicallyPresent() { mPhysicallyPresent = true; } void GetInfo(SerialPortInfo& aRetVal, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT ReadableStream* GetReadable(); // https://wicg.github.io/serial/#dom-serialport-writable MOZ_CAN_RUN_SCRIPT WritableStream* GetWritable(); IMPL_EVENT_HANDLER(connect) IMPL_EVENT_HANDLER(disconnect) const nsString& Id() const { return mInfo.id(); } const IPCSerialPortInfo& GetPortInfo() const { return mInfo; } MOZ_CAN_RUN_SCRIPT void NotifyConnected(); MOZ_CAN_RUN_SCRIPT void NotifyDisconnected(); // Called when the PSerialPort child actor is destroyed externally (e.g. // by the parent closing the channel due to permission revocation). MOZ_CAN_RUN_SCRIPT void OnActorDestroyed(); MOZ_CAN_RUN_SCRIPT_BOUNDARY void Shutdown(); void DisconnectFromOwner() override; RefPtr GetChild() const { return mChild; } void SetChild(SerialPortChild* aChild) { mChild = aChild; } private: ~SerialPort() override; MOZ_CAN_RUN_SCRIPT ReadableStream* CreateReadableStream(); MOZ_CAN_RUN_SCRIPT WritableStream* CreateWritableStream(); void CloseAfterStreamsClosed(); void SettleClosePromise(nsresult aResult); MOZ_CAN_RUN_SCRIPT already_AddRefed CloseStreams(); void NotifySharingStateChanged(bool aConnected); void UpdateWorkerRef(); RefPtr mSerial; IPCSerialPortInfo mInfo; // Whether the port is currently open (between Open() and Close()) bool mIsOpen = false; // Whether the hardware device is physically connected to the system bool mPhysicallyPresent = true; bool mHasShutdown = false; // Whether the user has called forget() on this port enum class ForgottenState { NotForgotten, Forgetting, Forgotten }; ForgottenState mForgottenState = ForgottenState::NotForgotten; uint32_t mBufferSize = 0; uint32_t mPipeCapacity = 0; RefPtr mReadable; RefPtr mWritable; RefPtr mChild; RefPtr mOpenPromise; RefPtr mClosePromise; // Prevents the worker from shutting down while this port is open or // has connect/disconnect event listeners. Managed by UpdateWorkerRef(). RefPtr mWorkerRef; }; } // namespace mozilla::dom #endif // mozilla_dom_SerialPort_h