| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef GARNET_BIN_UI_INPUT_READER_TESTS_MOCK_HID_DECODER_H_ |
| #define GARNET_BIN_UI_INPUT_READER_TESTS_MOCK_HID_DECODER_H_ |
| |
| #include <lib/fit/function.h> |
| #include <zx/event.h> |
| |
| #include "garnet/bin/ui/input_reader/hid_decoder.h" |
| #include "lib/fxl/memory/weak_ptr.h" |
| |
| namespace mozart { |
| |
| // Base class for mock HID decoders, which fails every operation but implements |
| // |GetEvent| properly. |
| class MockHidDecoder : public HidDecoder { |
| public: |
| // Function mocking out |Init()|, which produces the |Protocol| of the device |
| // and the bool return value of |Init()| (true on success). |
| using InitHandler = fit::function<std::pair<Protocol, bool>()>; |
| |
| MockHidDecoder(InitHandler init_handler); |
| // Convenience constructor that just sets the protocol on |Init()|. |
| MockHidDecoder(Protocol protocol); |
| ~MockHidDecoder() override; |
| |
| fxl::WeakPtr<MockHidDecoder> GetWeakPtr(); |
| |
| // |HidDecoder| |
| const std::string& name() const override; |
| |
| // |HidDecoder| |
| Protocol protocol() const override { return protocol_; } |
| |
| // |HidDecoder| |
| bool Init() override; |
| // |HidDecoder| |
| zx::event GetEvent() override; |
| |
| // |HidDecoder| |
| const std::vector<uint8_t>& Read(int* bytes_read) override; |
| // |HidDecoder| |
| bool Read(HidGamepadSimple* gamepad) override; |
| // |HidDecoder| |
| bool Read(HidAmbientLightSimple* light) override; |
| // |HidDecoder| |
| bool Read(HidButtons* data) override; |
| bool Read(Touchscreen::Report* report) override; |
| |
| bool SetDescriptor(Touchscreen::Descriptor* touch_desc) override; |
| |
| // Legacy emulation, which will allow |Read(int* bytes_read)| returning |
| // |bytes| and setting |bytes_read| to |content_length|. There must not be a |
| // pending report that has not been |Read|. |
| void Send(std::vector<uint8_t> bytes, int content_length); |
| // There must not be a pending report that has not been |Read|. |
| void Send(const HidGamepadSimple& gamepad); |
| // There must not be a pending report that has not been |Read|. |
| void Send(const HidAmbientLightSimple& light); |
| // There must not be a pending report that has not been |Read|. |
| void Send(const HidButtons& buttons); |
| // There must not be a pending report that has not been |Read|. |
| void Send(const Touchscreen::Report& touchscreen); |
| // Emulates device removal. There must not be a pending report that has not |
| // been |Read|. |
| void Close(); |
| |
| private: |
| enum class ReportType { |
| kNone = 0, |
| kLegacy, |
| kGamepad, |
| kLight, |
| kButtons, |
| kTouchscreen |
| }; |
| |
| struct Report { |
| ReportType type; |
| |
| // Keep this outside of the union/don't use std::variant because the legacy |
| // |Read| overload needs to return a const ref, so this needs to linger even |
| // after the report has been read. |
| std::vector<uint8_t> legacy_bytes; |
| union { |
| // This can be shorter than the length of |legacy_bytes|. |
| int legacy_content_length; |
| |
| HidGamepadSimple gamepad; |
| HidAmbientLightSimple light; |
| HidButtons buttons; |
| Touchscreen::Report touchscreen; |
| }; |
| }; |
| |
| template <class ReportVariant> |
| bool MockRead(ReportType expected_type, const ReportVariant& source, |
| ReportVariant* dest); |
| |
| void Signal(); |
| void ClearReport(); |
| |
| InitHandler init_handler_; |
| zx::event event_; |
| Protocol protocol_; |
| Report report_; |
| |
| fxl::WeakPtrFactory<MockHidDecoder> weak_ptr_factory_; |
| }; |
| |
| } // namespace mozart |
| |
| #endif // GARNET_BIN_UI_INPUT_READER_TESTS_MOCK_HID_DECODER_H_ |