/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include // $(croot)/external/freetype #include // $(croot)/system/teeui/libteeui/.../include #include "common/libs/confui/confui.h" #include "host/libs/confui/layouts/layout.h" #include "host/libs/confui/server_common.h" #include "host/libs/screen_connector/screen_connector.h" namespace cuttlefish { namespace confui { /** * create a raw frame for confirmation UI dialog */ class ConfUiRenderer { public: using LabelConfMsg = teeui::LabelBody; ConfUiRenderer(const std::uint32_t display); /** * this does not repaint from the scratch all the time * * Unless repainting the whole thing is needed, it remove the message * label, and re-draw there. There seems yet no fancy way of doing this. * Thus, it repaint the background color on the top of the label, and * draw the label on the new background * * As HostRenderer is intended to be shared across sessions, HostRender * owns the buffer, and returns reference to the buffer. Note that no * 2 or more sessions are concurrently executed. Only 1 or 0 is active * at the given moment. */ std::tuple RenderRawFrame( const std::string& confirmation_msg, const std::string& lang_id = "en"); bool IsFrameReady() const { return !raw_frame_.empty(); } private: struct Boundary { // inclusive but.. LayoutElement's size is float std::uint32_t x, y, w, h; // (x, y) is the top left }; template Boundary GetBoundary(LayoutElement&& e) { auto box = e.bounds_; Boundary b; // (x,y) is left top. so floor() makes sense // w, h are witdh and height in float. perhaps ceiling makes more // sense b.x = static_cast(box.x().floor().count()); b.y = static_cast(box.y().floor().count()); b.w = static_cast(box.w().ceil().count()); b.h = static_cast(box.h().ceil().count()); return b; } // essentially, to repaint from the scratch, so returns new frame // when successful. Or, nullopt std::optional RepaintRawFrame(const std::string& confirmation_msg, const std::string& lang_id = "en"); bool InitLayout(const std::string& lang_id); teeui::Error UpdateTranslations(); /** * could be confusing. update prompt_, and update the text_ in the Label * object, the GUI components. This does not render immediately. And.. * to render it, we must clean up the existing dirty pixels, which * this method does not do. */ void SetConfUiMessage(const std::string& s); teeui::Error SetLangId(const std::string& lang_id); teeui::context GetDeviceContext(); // effectively, will be send to teeui as a callback function teeui::Error UpdatePixels(TeeUiFrame& buffer, std::uint32_t x, std::uint32_t y, teeui::Color color); // from Trusty // second param is for type deduction template static teeui::Error drawElements(std::tuple& layout, const teeui::PixelDrawer& drawPixel) { // Error::operator|| is overloaded, so we don't get short circuit // evaluation. But we get the first error that occurs. We will still try and // draw the remaining elements in the order they appear in the layout tuple. return (std::get(layout).draw(drawPixel) || ...); } // repaint the confirmation UI label only teeui::Error RenderConfirmationMsgOnly(const std::string& confirmation_msg); // from Trusty template void UpdateColorScheme(Context* ctx) { using namespace teeui; color_text_ = is_inverted_ ? kColorDisabledInv : kColorDisabled; shield_color_ = is_inverted_ ? kColorShieldInv : kColorShield; color_bg_ = is_inverted_ ? kColorBackgroundInv : kColorBackground; ctx->template setParam(shield_color_); ctx->template setParam(color_text_); ctx->template setParam(color_bg_); return; } template auto SetText(const std::string& text) { return std::get