1 // 2 // Copyright (C) 2021 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.0 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 #pragma once 17 18 #include <cstdint> 19 #include <string> 20 #include <utility> 21 #include <vector> 22 23 #include <teeui/common_message_types.h> // /system/teeui/libteeui/.../include 24 25 #include "common/libs/confui/packet.h" 26 #include "common/libs/confui/packet_types.h" 27 28 #include "common/libs/confui/utils.h" 29 #include "common/libs/fs/shared_fd.h" 30 31 namespace cuttlefish { 32 namespace confui { 33 // When you update this, please update all the utility functions 34 // in conf.cpp: e.g. ToString, etc 35 enum class ConfUiCmd : std::uint32_t { 36 kUnknown = 100, 37 kStart = 111, // start rendering, send confirmation msg, & wait respond 38 kStop = 112, // start rendering, send confirmation msg, & wait respond 39 kCliAck = 113, // client acknowledged. "error:err_msg" or "success:command" 40 kCliRespond = 114, // with "confirm" or "cancel" or "abort" 41 kAbort = 115, // to abort the current session 42 kUserInputEvent = 200, 43 kUserTouchEvent = 201 44 }; 45 46 // this is for short messages 47 constexpr const ssize_t kMaxMessageLength = packet::kMaxPayloadLength; 48 49 std::string ToString(const ConfUiCmd& cmd); 50 std::string ToDebugString(const ConfUiCmd& cmd, const bool is_debug); 51 ConfUiCmd ToCmd(const std::string& cmd_str); 52 ConfUiCmd ToCmd(std::uint32_t i); 53 54 std::string ToString(const teeui::UIOption ui_opt); 55 std::optional<teeui::UIOption> ToUiOption(const std::string&); 56 57 struct HostError { 58 static constexpr char kSystemError[] = "system_error"; 59 static constexpr char kUIError[] = "ui_error"; 60 static constexpr char kMessageTooLongError[] = "msg_too_long_error"; 61 static constexpr char kIncorrectUTF8[] = "msg_incorrect_utf8"; 62 }; 63 64 struct UserResponse { 65 using type = std::string; 66 constexpr static const auto kConfirm = "user_confirm"; 67 constexpr static const auto kCancel = "user_cancel"; 68 constexpr static const auto kTouchEvent = "user_touch"; 69 // user may close x button on the virtual window or so 70 // or.. scroll the session up and throw to trash bin 71 constexpr static const auto kUserAbort = "user_abort"; 72 constexpr static const auto kUnknown = "user_unknown"; 73 }; 74 75 class ConfUiMessage { 76 public: ConfUiMessage(const std::string & session_id)77 ConfUiMessage(const std::string& session_id) : session_id_{session_id} {} 78 virtual ~ConfUiMessage() = default; 79 virtual std::string ToString() const = 0; SetSessionId(const std::string session_id)80 void SetSessionId(const std::string session_id) { session_id_ = session_id; } GetSessionId()81 std::string GetSessionId() const { return session_id_; } 82 virtual ConfUiCmd GetType() const = 0; 83 virtual bool SendOver(SharedFD fd) = 0; 84 bool IsUserInput() const; 85 86 protected: 87 std::string session_id_; 88 template <typename... Args> CreateString(Args &&...args)89 static std::string CreateString(Args&&... args) { 90 return "[" + ArgsToStringWithDelim(",", std::forward<Args>(args)...) + "]"; 91 } 92 template <typename... Args> Send_(SharedFD fd,const ConfUiCmd cmd,const std::string & session_id,Args &&...args)93 static bool Send_(SharedFD fd, const ConfUiCmd cmd, 94 const std::string& session_id, Args&&... args) { 95 return packet::WritePayload(fd, confui::ToString(cmd), session_id, 96 std::forward<Args>(args)...); 97 } 98 }; 99 100 template <ConfUiCmd cmd> 101 class ConfUiGenericMessage : public ConfUiMessage { 102 public: ConfUiGenericMessage(const std::string & session_id)103 ConfUiGenericMessage(const std::string& session_id) 104 : ConfUiMessage{session_id} {} 105 virtual ~ConfUiGenericMessage() = default; ToString()106 std::string ToString() const override { 107 return CreateString(session_id_, confui::ToString(GetType())); 108 } GetType()109 ConfUiCmd GetType() const override { return cmd; } SendOver(SharedFD fd)110 bool SendOver(SharedFD fd) override { 111 return Send_(fd, GetType(), session_id_); 112 } 113 }; 114 115 class ConfUiAckMessage : public ConfUiMessage { 116 public: ConfUiAckMessage(const std::string & session_id,const bool is_success,const std::string & status)117 ConfUiAckMessage(const std::string& session_id, const bool is_success, 118 const std::string& status) 119 : ConfUiMessage{session_id}, 120 is_success_(is_success), 121 status_message_(status) {} 122 virtual ~ConfUiAckMessage() = default; 123 std::string ToString() const override; GetType()124 ConfUiCmd GetType() const override { return ConfUiCmd::kCliAck; } 125 bool SendOver(SharedFD fd) override; IsSuccess()126 bool IsSuccess() const { return is_success_; } GetStatusMessage()127 std::string GetStatusMessage() const { return status_message_; } 128 129 private: 130 bool is_success_; 131 std::string status_message_; 132 }; 133 134 // the signed user response sent to the guest 135 class ConfUiCliResponseMessage : public ConfUiMessage { 136 public: 137 ConfUiCliResponseMessage(const std::string& session_id, 138 const UserResponse::type& response, 139 const std::vector<std::uint8_t>& sign = {}, 140 const std::vector<std::uint8_t>& msg = {}) ConfUiMessage(session_id)141 : ConfUiMessage(session_id), 142 response_(response), 143 sign_(sign), 144 message_{msg} {} 145 virtual ~ConfUiCliResponseMessage() = default; 146 std::string ToString() const override; GetType()147 ConfUiCmd GetType() const override { return ConfUiCmd::kCliRespond; } GetResponse()148 auto GetResponse() const { return response_; } GetMessage()149 auto GetMessage() const { return message_; } GetSign()150 auto GetSign() const { return sign_; } 151 bool SendOver(SharedFD fd) override; 152 153 private: 154 UserResponse::type response_; // plain format 155 std::vector<std::uint8_t> sign_; // signed format 156 // second argument to pass via resultCB of promptUserConfirmation 157 std::vector<std::uint8_t> message_; 158 }; 159 160 class ConfUiStartMessage : public ConfUiMessage { 161 public: 162 ConfUiStartMessage(const std::string session_id, 163 const std::string& prompt_text = "", 164 const std::vector<std::uint8_t>& extra_data = {}, 165 const std::string& locale = "C", 166 const std::vector<teeui::UIOption> ui_opts = {}) ConfUiMessage(session_id)167 : ConfUiMessage(session_id), 168 prompt_text_(prompt_text), 169 extra_data_(extra_data), 170 locale_(locale), 171 ui_opts_(ui_opts) {} 172 virtual ~ConfUiStartMessage() = default; 173 std::string ToString() const override; GetType()174 ConfUiCmd GetType() const override { return ConfUiCmd::kStart; } GetPromptText()175 std::string GetPromptText() const { return prompt_text_; } GetExtraData()176 std::vector<std::uint8_t> GetExtraData() const { return extra_data_; } GetLocale()177 std::string GetLocale() const { return locale_; } GetUiOpts()178 std::vector<teeui::UIOption> GetUiOpts() const { return ui_opts_; } 179 bool SendOver(SharedFD fd) override; 180 181 private: 182 std::string prompt_text_; 183 std::vector<std::uint8_t> extra_data_; 184 std::string locale_; 185 std::vector<teeui::UIOption> ui_opts_; 186 187 std::string UiOptsToString() const; 188 }; 189 190 // this one is for deliverSecureInputEvent() as well as 191 // physical-input based implementation 192 class ConfUiUserSelectionMessage : public ConfUiMessage { 193 public: ConfUiUserSelectionMessage(const std::string & session_id,const UserResponse::type & response)194 ConfUiUserSelectionMessage(const std::string& session_id, 195 const UserResponse::type& response) 196 : ConfUiMessage(session_id), response_(response) {} 197 virtual ~ConfUiUserSelectionMessage() = default; 198 std::string ToString() const override; GetType()199 ConfUiCmd GetType() const override { return ConfUiCmd::kUserInputEvent; } GetResponse()200 auto GetResponse() const { return response_; } 201 bool SendOver(SharedFD fd) override; 202 203 private: 204 UserResponse::type response_; 205 }; 206 207 class ConfUiUserTouchMessage : public ConfUiMessage { 208 public: ConfUiUserTouchMessage(const std::string & session_id,const int x,const int y)209 ConfUiUserTouchMessage(const std::string& session_id, const int x, 210 const int y) 211 : ConfUiMessage(session_id), 212 x_(x), 213 y_(y), 214 response_(UserResponse::kTouchEvent) {} 215 virtual ~ConfUiUserTouchMessage() = default; 216 std::string ToString() const override; GetType()217 ConfUiCmd GetType() const override { return ConfUiCmd::kUserTouchEvent; } GetResponse()218 auto GetResponse() const { return response_; } 219 bool SendOver(SharedFD fd) override; GetLocation()220 std::pair<int, int> GetLocation() const { return {x_, y_}; } 221 222 private: 223 int x_; 224 int y_; 225 UserResponse::type response_; 226 }; 227 228 using ConfUiAbortMessage = ConfUiGenericMessage<ConfUiCmd::kAbort>; 229 using ConfUiStopMessage = ConfUiGenericMessage<ConfUiCmd::kStop>; 230 231 } // end of namespace confui 232 } // end of namespace cuttlefish 233