1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0f
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "host/libs/confui/host_virtual_input.h"
18
19 #include <android-base/logging.h>
20
21 namespace cuttlefish {
22 namespace confui {
23
HostVirtualInput(HostServer & host_server,HostModeCtrl & host_mode_ctrl,InputConnector & android_mode_input)24 HostVirtualInput::HostVirtualInput(HostServer& host_server,
25 HostModeCtrl& host_mode_ctrl,
26 InputConnector& android_mode_input)
27 : host_server_(host_server),
28 host_mode_ctrl_(host_mode_ctrl),
29 android_mode_input_(android_mode_input) {}
30
UserAbortEvent()31 void HostVirtualInput::UserAbortEvent() { host_server_.UserAbortEvent(); }
32
IsConfUiActive()33 bool HostVirtualInput::IsConfUiActive() {
34 return host_mode_ctrl_.IsConfirmatioUiMode();
35 }
36
37 class HostVirtualInputEventSink : public InputConnector::EventSink {
38 public:
HostVirtualInputEventSink(std::unique_ptr<EventSink> android_mode_input,HostVirtualInput & host_virtual_input)39 HostVirtualInputEventSink(std::unique_ptr<EventSink> android_mode_input,
40 HostVirtualInput& host_virtual_input)
41 : android_mode_input_(std::move(android_mode_input)),
42 host_virtual_input_(host_virtual_input) {}
43
44 // EventSink implementation
45 Result<void> SendMouseMoveEvent(int x, int y) override;
46 Result<void> SendMouseButtonEvent(int button, bool down) override;
47 Result<void> SendMouseWheelEvent(int pixels) override;
48 Result<void> SendTouchEvent(const std::string& device_label, int x, int y,
49 bool down) override;
50 Result<void> SendMultiTouchEvent(const std::string& device_label,
51 const std::vector<MultitouchSlot>& slots,
52 bool down) override;
53 Result<void> SendKeyboardEvent(uint16_t code, bool down) override;
54 Result<void> SendRotaryEvent(int pixels) override;
55 Result<void> SendSwitchesEvent(uint16_t code, bool state) override;
56
57 private:
58 std::unique_ptr<EventSink> android_mode_input_;
59 HostVirtualInput& host_virtual_input_;
60 };
61
SendMouseMoveEvent(int x,int y)62 Result<void> HostVirtualInputEventSink::SendMouseMoveEvent(int x, int y) {
63 ConfUiLog(INFO) << "Sending mouse move event: " << x << "," << y;
64 return android_mode_input_->SendMouseMoveEvent(x, y);
65 }
66
SendMouseButtonEvent(int button,bool down)67 Result<void> HostVirtualInputEventSink::SendMouseButtonEvent(int button,
68 bool down) {
69 ConfUiLog(INFO) << "Sending mouse button event: " << button << "," << down;
70 return android_mode_input_->SendMouseButtonEvent(button, down);
71 }
72
SendMouseWheelEvent(int pixels)73 Result<void> HostVirtualInputEventSink::SendMouseWheelEvent(int pixels) {
74 ConfUiLog(INFO) << "Sending mouse wheel event: " << pixels;
75 return android_mode_input_->SendMouseWheelEvent(pixels);
76 }
77
SendTouchEvent(const std::string & device_label,int x,int y,bool down)78 Result<void> HostVirtualInputEventSink::SendTouchEvent(
79 const std::string& device_label, int x, int y, bool down) {
80 if (!host_virtual_input_.IsConfUiActive()) {
81 return android_mode_input_->SendTouchEvent(device_label, x, y, down);
82 }
83
84 if (down) {
85 ConfUiLog(INFO) << "TouchEvent occurs in Confirmation UI Mode at [" << x
86 << ", " << y << "]";
87 host_virtual_input_.host_server().TouchEvent(x, y, down);
88 }
89 return {};
90 }
91
SendMultiTouchEvent(const std::string & device_label,const std::vector<MultitouchSlot> & slots,bool down)92 Result<void> HostVirtualInputEventSink::SendMultiTouchEvent(
93 const std::string& device_label, const std::vector<MultitouchSlot>& slots,
94 bool down) {
95 if (!host_virtual_input_.IsConfUiActive()) {
96 CF_EXPECT(
97 android_mode_input_->SendMultiTouchEvent(device_label, slots, down));
98 return {};
99 }
100 for (auto& slot : slots) {
101 if (down) {
102 auto this_x = slot.x;
103 auto this_y = slot.y;
104 ConfUiLog(INFO) << "TouchEvent occurs in Confirmation UI Mode at ["
105 << this_x << ", " << this_y << "]";
106 host_virtual_input_.host_server().TouchEvent(this_x, this_y, down);
107 }
108 }
109 return {};
110 }
111
SendKeyboardEvent(uint16_t code,bool down)112 Result<void> HostVirtualInputEventSink::SendKeyboardEvent(uint16_t code,
113 bool down) {
114 if (!host_virtual_input_.IsConfUiActive()) {
115 CF_EXPECT(android_mode_input_->SendKeyboardEvent(code, down));
116 return {};
117 }
118 ConfUiLog(VERBOSE) << "keyboard event ignored in confirmation UI mode";
119 return {};
120 }
121
SendRotaryEvent(int pixels)122 Result<void> HostVirtualInputEventSink::SendRotaryEvent(int pixels) {
123 if (!host_virtual_input_.IsConfUiActive()) {
124 CF_EXPECT(android_mode_input_->SendRotaryEvent(pixels));
125 return {};
126 }
127 ConfUiLog(VERBOSE) << "rotary event ignored in confirmation UI mode";
128 return {};
129 }
130
SendSwitchesEvent(uint16_t code,bool state)131 Result<void> HostVirtualInputEventSink::SendSwitchesEvent(uint16_t code,
132 bool state) {
133 if (!host_virtual_input_.IsConfUiActive()) {
134 CF_EXPECT(android_mode_input_->SendSwitchesEvent(code, state));
135 return {};
136 }
137 ConfUiLog(VERBOSE) << "switches event ignored in confirmation UI mode";
138 return {};
139 }
140
CreateSink()141 std::unique_ptr<InputConnector::EventSink> HostVirtualInput::CreateSink() {
142 return std::unique_ptr<EventSink>(
143 new HostVirtualInputEventSink(android_mode_input_.CreateSink(), *this));
144 }
145
146 } // namespace confui
147 } // namespace cuttlefish
148