1 #pragma once 2 3 /* 4 * Copyright (C) 2017 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 20 #include <condition_variable> 21 #include <memory> 22 #include <mutex> 23 #include <unordered_map> 24 25 #include "common/libs/threads/thread_annotations.h" 26 #include "host/frontend/vnc_server/vnc_utils.h" 27 28 namespace cuttlefish { 29 namespace vnc { 30 31 class VncClientConnection; 32 class FrameBufferWatcher; 33 using StripePtrVec = std::vector<std::shared_ptr<const Stripe>>; 34 using SeqNumberVec = std::vector<StripeSeqNumber>; 35 36 SeqNumberVec MakeSeqNumberVec(); 37 38 class BlackBoard { 39 private: 40 struct ClientFBUState { 41 bool ready_to_receive{}; 42 ScreenOrientation orientation{}; 43 std::condition_variable new_frame_cv; 44 SeqNumberVec stripe_seq_nums = MakeSeqNumberVec(); 45 bool closed{}; 46 }; 47 48 public: 49 class Registerer { 50 public: Registerer(BlackBoard * bb,const VncClientConnection * conn)51 Registerer(BlackBoard* bb, const VncClientConnection* conn) 52 : bb_{bb}, conn_{conn} { 53 bb->Register(conn); 54 } ~Registerer()55 ~Registerer() { bb_->Unregister(conn_); } 56 Registerer(const Registerer&) = delete; 57 Registerer& operator=(const Registerer&) = delete; 58 59 private: 60 BlackBoard* bb_{}; 61 const VncClientConnection* conn_{}; 62 }; 63 64 BlackBoard() = default; 65 BlackBoard(const BlackBoard&) = delete; 66 BlackBoard& operator=(const BlackBoard&) = delete; 67 68 bool NoNewStripesFor(const SeqNumberVec& seq_nums) const REQUIRES(m_); 69 void NewStripeReady(int index, StripeSeqNumber seq_num); 70 void Register(const VncClientConnection* conn); 71 void Unregister(const VncClientConnection* conn); 72 73 StripePtrVec WaitForSenderWork(const VncClientConnection* conn); 74 75 void WaitForAtLeastOneClientConnection(); 76 77 void FrameBufferUpdateRequestReceived(const VncClientConnection* conn); 78 // Setting orientation implies needing the entire screen 79 void SetOrientation(const VncClientConnection* conn, 80 ScreenOrientation orientation); 81 void SignalClientNeedsEntireScreen(const VncClientConnection* conn); 82 83 void StopWaiting(const VncClientConnection* conn); 84 85 void set_frame_buffer_watcher(FrameBufferWatcher* frame_buffer_watcher); 86 87 // quality_level must be the value received from the client, in the range 88 // [kJpegMinQualityEncoding, kJpegMaxQualityEncoding], else it is ignored. 89 void set_jpeg_quality_level(int quality_level); 90 jpeg_quality_level()91 int jpeg_quality_level() const { 92 std::lock_guard<std::mutex> guard(m_); 93 return jpeg_quality_level_; 94 } 95 96 private: 97 ClientFBUState& GetStateForClient(const VncClientConnection* conn) 98 REQUIRES(m_); 99 static void ResetToZero(SeqNumberVec* seq_nums); 100 101 mutable std::mutex m_; 102 SeqNumberVec most_recent_stripe_seq_nums_ GUARDED_BY(m_) = MakeSeqNumberVec(); 103 std::unordered_map<const VncClientConnection*, ClientFBUState> clients_ 104 GUARDED_BY(m_); 105 int jpeg_quality_level_ GUARDED_BY(m_) = 100; 106 std::condition_variable new_client_cv_; 107 // NOTE the FrameBufferWatcher pointer itself should be 108 // guarded, but not the pointee. GUARDED_BY(m_)109 FrameBufferWatcher* frame_buffer_watcher_ GUARDED_BY(m_){}; 110 }; 111 112 } // namespace vnc 113 } // namespace cuttlefish 114