1 /* 2 * Copyright 2020, 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 17 #pragma once 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <cstdint> 22 #include <memory> 23 #include <mutex> 24 #include <thread> 25 26 #include <aidl/android/hardware/confirmationui/BnConfirmationUI.h> 27 #include <aidl/android/hardware/confirmationui/IConfirmationResultCallback.h> 28 #include <aidl/android/hardware/confirmationui/UIOption.h> 29 #include <aidl/android/hardware/security/keymint/HardwareAuthToken.h> 30 #include <teeui/generic_messages.h> 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 #include "guest_session.h" 36 37 namespace aidl::android::hardware::confirmationui { 38 39 using ::aidl::android::hardware::security::keymint::HardwareAuthToken; 40 using std::shared_ptr; 41 using std::string; 42 using std::vector; 43 44 class TrustyConfirmationUI : public BnConfirmationUI { 45 public: 46 using ConfUiMessage = cuttlefish::confui::ConfUiMessage; 47 using ConfUiAckMessage = cuttlefish::confui::ConfUiAckMessage; 48 using ListenerState = GuestSession::ListenerState; 49 50 TrustyConfirmationUI(); 51 virtual ~TrustyConfirmationUI(); 52 // Methods from ::android::hardware::confirmationui::V1_0::IConfirmationUI 53 // follow. 54 ::ndk::ScopedAStatus 55 promptUserConfirmation(const shared_ptr<IConfirmationResultCallback>& resultCB, 56 const vector<uint8_t>& promptText, const vector<uint8_t>& extraData, 57 const string& locale, const vector<UIOption>& uiOptions) override; 58 ::ndk::ScopedAStatus 59 deliverSecureInputEvent(const HardwareAuthToken& secureInputToken) override; 60 61 ::ndk::ScopedAStatus abort() override; 62 63 private: 64 /* 65 * Note for implementation 66 * 67 * The TEE UI session cannot be pre-emptied normally. The session will have an 68 * exclusive control for the input and the screen. Only when something goes 69 * wrong, it can be aborted by abort(). 70 * 71 * Another thing is that promptUserConfirmation() may return without waiting 72 * for the resultCB is completed. When it returns early, it still returns 73 * ResponseCode::OK. In that case, the promptUserConfirmation() could actually 74 * fail -- e.g. the input device is broken down afterwards, the user never 75 * gave an input until timeout, etc. Then, the resultCB would be called with 76 * an appropriate error code. However, even in that case, most of the time 77 * promptUserConfirmation() returns OK. Only when the initial set up for 78 * confirmation UI fails, promptUserConfirmation() may return non-OK. 79 * 80 * So, the implementation is roughly: 81 * 1. If there's another session going on, return with ResponseCode::Ignored 82 * and the return is immediate 83 * 2. If there's a zombie, collect the zombie and go to 3 84 * 3. If there's nothing, start a new session in a new thread, and return 85 * the promptUserConfirmation() call as early as possible 86 * 87 * Another issue is to maintain/define the ownership of vsock. For now, 88 * a message fetcher (from the host) will see if the vsock is ok, and 89 * reconnect if not. But, eventually, the new session should establish a 90 * new connection/client vsock, and the new session should own the fetcher 91 * thread. 92 */ 93 std::thread callback_thread_; 94 ListenerState listener_state_; 95 96 std::mutex listener_state_lock_; 97 std::condition_variable listener_state_condv_; 98 int prompt_result_; 99 100 // client virtio-console fd to the host 101 cuttlefish::SharedFD host_fd_; 102 103 // ack, response, command from the host, and the abort command from the guest 104 std::atomic<std::uint32_t> current_session_id_; 105 std::mutex current_session_lock_; 106 std::unique_ptr<GuestSession> current_session_; 107 std::thread host_cmd_fetcher_thread_; 108 bool is_supported_vm_; 109 110 cuttlefish::SharedFD ConnectToHost(); 111 void HostMessageFetcherLoop(); 112 void RunSession(shared_ptr<IConfirmationResultCallback> resultCB, string promptText, 113 vector<uint8_t> extraData, string locale, vector<UIOption> uiOptions); 114 static const char* GetVirtioConsoleDevicePath(); 115 }; 116 117 } // namespace aidl::android::hardware::confirmationui 118