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 #include "phys_button_example.h"
18
19 #include <stddef.h>
20 #include <stdint.h>
21
22 #include "example_utils.h"
23 #include "layout/phys_button_layout.h"
24
25 #include <memory>
26
27 namespace teeui {
28 namespace example {
29 namespace phys_button {
30
translateLabels(Layout * layout)31 template <typename Layout> static void translateLabels(Layout* layout) {
32 translateLabel<LabelOK>(layout);
33 translateLabel<LabelCancel>(layout);
34 translateLabel<LabelTitle>(layout);
35 translateLabel<LabelHint>(layout);
36 }
37
38 class GUIStatePhysButtons : public ITeeuiExample {
39 public:
40 bool inverted_;
41 std::string confirmationMessage_;
42 layout_t<ConfUILayout> layoutInstance_ = {};
43
GUIStatePhysButtons()44 GUIStatePhysButtons() : inverted_(false), layoutInstance_{} {}
45
selectLanguage(const char * language_id)46 void selectLanguage(const char* language_id) override {
47 teeui::localization::selectLangId(language_id);
48 translateLabels(&layoutInstance_);
49 }
50
setConfirmationMessage(std::string confirmationMessage)51 void setConfirmationMessage(std::string confirmationMessage) override {
52 confirmationMessage_ = std::move(confirmationMessage);
53 std::get<LabelBody>(layoutInstance_)
54 .setText({&*confirmationMessage_.begin(), &*confirmationMessage_.end()});
55 }
56
57 uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false) override;
onEvent(uint32_t,uint32_t,uint32_t)58 EventResult onEvent(uint32_t, uint32_t, uint32_t) override { return EventResult::NONE; }
59
60 uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride,
61 uint32_t* buffer,
62 size_t buffer_size_in_elements_not_bytes) override;
63 };
64
createTeeuiExample()65 std::unique_ptr<ITeeuiExample> createTeeuiExample() {
66 return std::make_unique<GUIStatePhysButtons>();
67 }
68
setLayoutParams(DeviceInfo & deviceInfo,bool magnified,bool inverted)69 static context<ConUIParameters> setLayoutParams(DeviceInfo& deviceInfo, bool magnified,
70 bool inverted) {
71 context<ConUIParameters> ctx(deviceInfo.mm2px_, deviceInfo.dp2px_);
72 ctx.setParam<RightEdgeOfScreen>(pxs(deviceInfo.width_));
73 ctx.setParam<BottomOfScreen>(pxs(deviceInfo.height_));
74 ctx.setParam<PowerButtonTop>(mms(deviceInfo.powerButtonTopMm_));
75 ctx.setParam<PowerButtonBottom>(mms(deviceInfo.powerButtonBottomMm_));
76 ctx.setParam<VolUpButtonTop>(mms(deviceInfo.volUpButtonTopMm_));
77 ctx.setParam<VolUpButtonBottom>(mms(deviceInfo.volUpButtonBottomMm_));
78 if (magnified) {
79 ctx.setParam<DefaultFontSize>(18_dp);
80 ctx.setParam<BodyFontSize>(20_dp);
81 } else {
82 ctx.setParam<DefaultFontSize>(14_dp);
83 ctx.setParam<BodyFontSize>(16_dp);
84 }
85 if (inverted) {
86 ctx.setParam<ShieldColor>(kShieldColorInv);
87 ctx.setParam<ColorText>(kTextColorInv);
88 ctx.setParam<ColorBG>(kBackGroundColorInv);
89 } else {
90 ctx.setParam<ShieldColor>(kShieldColor);
91 ctx.setParam<ColorText>(kTextColor);
92 ctx.setParam<ColorBG>(kBackGroundColor);
93 }
94 return ctx;
95 }
96
setDeviceInfo(DeviceInfo device_info,bool magnified,bool inverted)97 uint32_t GUIStatePhysButtons::setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted) {
98 layoutInstance_ =
99 instantiateLayout(ConfUILayout(), setLayoutParams(device_info, magnified, inverted));
100 inverted_ = inverted;
101
102 return 0;
103 }
104
renderUIIntoBuffer(uint32_t x,uint32_t y,uint32_t w,uint32_t h,uint32_t lineStride,uint32_t * buffer,size_t buffer_size_in_elements_not_bytes)105 uint32_t GUIStatePhysButtons::renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h,
106 uint32_t lineStride, uint32_t* buffer,
107 size_t buffer_size_in_elements_not_bytes) {
108 uint32_t afterLastPixelIndex = 0;
109 if (__builtin_add_overflow(y, h, &afterLastPixelIndex) ||
110 __builtin_add_overflow(afterLastPixelIndex, -1, &afterLastPixelIndex) ||
111 __builtin_mul_overflow(afterLastPixelIndex, lineStride, &afterLastPixelIndex) ||
112 __builtin_add_overflow(afterLastPixelIndex, x, &afterLastPixelIndex) ||
113 __builtin_add_overflow(afterLastPixelIndex, w, &afterLastPixelIndex) ||
114 afterLastPixelIndex > buffer_size_in_elements_not_bytes) {
115 return uint32_t(Error::OutOfBoundsDrawing);
116 }
117
118 uint32_t* begin = buffer + (y * lineStride + x);
119
120 Color bgColor = inverted_ ? kBackGroundColorInv : kBackGroundColor;
121
122 for (uint32_t yi = 0; yi < h; ++yi) {
123 for (uint32_t xi = 0; xi < w; ++xi) {
124 begin[xi] = bgColor;
125 }
126 begin += lineStride;
127 }
128 FrameBuffer fb;
129 fb.left_ = x;
130 fb.top_ = y;
131 fb.width_ = w;
132 fb.height_ = h;
133 fb.buffer_ = buffer;
134 fb.size_in_elements_ = buffer_size_in_elements_not_bytes;
135 fb.lineStride_ = lineStride;
136
137 auto pixelDrawer = makePixelDrawer(
138 [&fb](uint32_t x, uint32_t y, Color color) -> Error { return fb.drawPixel(x, y, color); });
139
140 if (auto error = drawElements(layoutInstance_, pixelDrawer)) {
141 return uint32_t(error.code());
142 }
143
144 return 0; // OK
145 }
146
147 } // namespace phys_button
148 } // namespace example
149 } // namespace teeui