• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2021, The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <android-base/logging.h>
21 #include <android/hardware/confirmationui/1.0/types.h>
22 #include <android/hardware/keymaster/4.0/types.h>
23 
24 #include <condition_variable>
25 #include <cstdint>
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 #include <tuple>
30 #include <vector>
31 
32 #include "common/libs/concurrency/thread_safe_queue.h"
33 #include "common/libs/confui/confui.h"
34 #include "common/libs/fs/shared_fd.h"
35 
36 namespace android {
37 namespace hardware {
38 namespace confirmationui {
39 namespace V1_0 {
40 namespace implementation {
41 class GuestSession {
42   public:
43     using ConfUiMessage = cuttlefish::confui::ConfUiMessage;
44     using ConfUiAckMessage = cuttlefish::confui::ConfUiAckMessage;
45     using Queue = cuttlefish::ThreadSafeQueue<std::unique_ptr<ConfUiMessage>>;
46     using QueueImpl = Queue::QueueImpl;
47 
48     enum class ListenerState : uint32_t {
49         None = 0,
50         Starting = 1,
51         SetupDone = 2,
52         Interactive = 3,
53         Terminating = 4,
54     };
55 
GuestSession(const std::uint32_t session_id,ListenerState & listener_state,std::mutex & listener_state_lock,std::condition_variable & listener_state_condv,cuttlefish::SharedFD host_fd,const teeui::MsgString & promptText,const teeui::MsgVector<uint8_t> & extraData,const teeui::MsgString & locale,const teeui::MsgVector<teeui::UIOption> & uiOptions)56     GuestSession(const std::uint32_t session_id, ListenerState& listener_state,
57                  std::mutex& listener_state_lock, std::condition_variable& listener_state_condv,
58                  cuttlefish::SharedFD host_fd, const teeui::MsgString& promptText,
59                  const teeui::MsgVector<uint8_t>& extraData, const teeui::MsgString& locale,
60                  const teeui::MsgVector<teeui::UIOption>& uiOptions)
61         : prompt_text_{promptText.begin(), promptText.end()}, extra_data_{extraData.begin(),
62                                                                           extraData.end()},
63           locale_{locale.begin(), locale.end()}, ui_options_{uiOptions.begin(), uiOptions.end()},
64           listener_state_(listener_state), listener_state_lock_(listener_state_lock),
65           listener_state_condv_(listener_state_condv), host_fd_{host_fd},
66           session_name_(MakeName(session_id)),
67           incoming_msg_queue_(
68               20, [this](GuestSession::QueueImpl* impl) { return QueueFullHandler(impl); }) {}
69 
~GuestSession()70     ~GuestSession() {
71         // the thread for PromptUserConfirmation is still alive
72         // the host_fd_ may be alive
73         auto state = listener_state_;
74         if (state == ListenerState::SetupDone || state == ListenerState::Interactive) {
75             Abort();
76         }
77         // TODO(kwstephenkim): close fd once Session takes the ownership of fd
78         // join host_cmd_fetcher_thread_ once Session takes the ownership of fd
79     }
80 
81     using ResultTriple =
82         std::tuple<ResponseCode, teeui::MsgVector<uint8_t>, teeui::MsgVector<uint8_t>>;
83     ResultTriple PromptUserConfirmation();
84 
85     Return<ResponseCode> DeliverSecureInputEvent(
86         const ::android::hardware::keymaster::V4_0::HardwareAuthToken& secureInputToken);
87 
88     Return<void> Abort();
GetSessionId()89     std::string GetSessionId() const { return session_name_; }
90 
Push(std::unique_ptr<ConfUiMessage> && msg)91     void Push(std::unique_ptr<ConfUiMessage>&& msg) { incoming_msg_queue_.Push(std::move(msg)); }
92 
93   private:
94     template <typename F, typename... Args>
SerializedSend(F && f,cuttlefish::SharedFD fd,Args &&...args)95     bool SerializedSend(F&& f, cuttlefish::SharedFD fd, Args&&... args) {
96         if (!fd->IsOpen()) {
97             return false;
98         }
99         std::unique_lock<std::mutex> lock(send_serializer_mtx_);
100         return f(fd, std::forward<Args>(args)...);
101     }
102 
QueueFullHandler(QueueImpl * queue_impl)103     void QueueFullHandler(QueueImpl* queue_impl) {
104         if (!queue_impl) {
105             LOG(ERROR) << "Registered queue handler is "
106                        << "seeing nullptr for queue implementation.";
107             return;
108         }
109         const auto n = (queue_impl->size()) / 2;
110         // pop front half
111         queue_impl->erase(queue_impl->begin(), queue_impl->begin() + n);
112     }
113 
MakeName(const std::uint32_t i)114     std::string MakeName(const std::uint32_t i) const {
115         return "ConfirmationUiSession" + std::to_string(i);
116     }
117     std::string prompt_text_;
118     std::vector<std::uint8_t> extra_data_;
119     std::string locale_;
120     std::vector<teeui::UIOption> ui_options_;
121 
122     /*
123      * lister_state_lock_ coordinates multiple threads that may
124      * call the three Confirmation UI HAL APIs concurrently
125      */
126     ListenerState& listener_state_;
127     std::mutex& listener_state_lock_;
128     std::condition_variable& listener_state_condv_;
129     cuttlefish::SharedFD host_fd_;
130 
131     const std::string session_name_;
132     Queue incoming_msg_queue_;
133 
134     /*
135      * multiple threads could try to write on the vsock at the
136      * same time. E.g. promptUserConfirmation() thread sends
137      * a command while abort() is being called. The abort() thread
138      * will try to write an abort command concurrently.
139      */
140     std::mutex send_serializer_mtx_;
141 };
142 }  // namespace implementation
143 }  // namespace V1_0
144 }  // namespace confirmationui
145 }  // namespace hardware
146 }  // namespace android
147