blob: ea3d991c04d9fc8de7b7240841848e78d1b81362 [file] [log] [blame]
Luke Song1d540dd2017-07-13 15:10:35 -07001/*
2 * Copyright (C) 2017 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 <android-base/stringprintf.h>
18#include <batteryservice/BatteryService.h>
19#include <cutils/klog.h>
20
21#include "healthd_draw.h"
22
23#define LOGE(x...) KLOG_ERROR("charger", x);
24#define LOGV(x...) KLOG_DEBUG("charger", x);
25
26HealthdDraw::HealthdDraw(animation* anim)
27 : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN),
28 kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) {
29 gr_init();
30 gr_font_size(gr_sys_font(), &char_width_, &char_height_);
31
32 screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1);
33 screen_height_ = gr_fb_height();
34
35 int res;
36 if (!anim->text_clock.font_file.empty() &&
37 (res = gr_init_font(anim->text_clock.font_file.c_str(),
38 &anim->text_clock.font)) < 0) {
39 LOGE("Could not load time font (%d)\n", res);
40 }
41 if (!anim->text_percent.font_file.empty() &&
42 (res = gr_init_font(anim->text_percent.font_file.c_str(),
43 &anim->text_percent.font)) < 0) {
44 LOGE("Could not load percent font (%d)\n", res);
45 }
46}
47
48HealthdDraw::~HealthdDraw() {}
49
50void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) {
51 clear_screen();
52
53 /* try to display *something* */
54 if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0)
55 draw_unknown(surf_unknown);
56 else
57 draw_battery(batt_anim);
58 gr_flip();
59}
60
61void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); }
62
63void HealthdDraw::clear_screen(void) {
64 gr_color(0, 0, 0, 255);
65 gr_clear();
66}
67
68int HealthdDraw::draw_surface_centered(GRSurface* surface) {
69 int w = gr_get_width(surface);
70 int h = gr_get_height(surface);
71 int x = (screen_width_ - w) / 2 + kSplitOffset;
72 int y = (screen_height_ - h) / 2;
73
74 LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
75 gr_blit(surface, 0, 0, w, h, x, y);
76 if (kSplitScreen) {
77 x += screen_width_ - 2 * kSplitOffset;
78 LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
79 gr_blit(surface, 0, 0, w, h, x, y);
80 }
81
82 return y + h;
83}
84
85int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) {
86 int str_len_px = gr_measure(font, str);
87
88 if (x < 0) x = (screen_width_ - str_len_px) / 2;
89 if (y < 0) y = (screen_height_ - char_height_) / 2;
90 gr_text(font, x + kSplitOffset, y, str, false /* bold */);
91 if (kSplitScreen)
92 gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */);
93
94 return y + char_height_;
95}
96
97void HealthdDraw::determine_xy(const animation::text_field& field,
98 const int length, int* x, int* y) {
99 *x = field.pos_x;
100
101 int str_len_px = length * field.font->char_width;
102 if (field.pos_x == CENTER_VAL) {
103 *x = (screen_width_ - str_len_px) / 2;
104 } else if (field.pos_x >= 0) {
105 *x = field.pos_x;
106 } else { // position from max edge
107 *x = screen_width_ + field.pos_x - str_len_px - kSplitOffset;
108 }
109
110 *y = field.pos_y;
111
112 if (field.pos_y == CENTER_VAL) {
113 *y = (screen_height_ - field.font->char_height) / 2;
114 } else if (field.pos_y >= 0) {
115 *y = field.pos_y;
116 } else { // position from max edge
117 *y = screen_height_ + field.pos_y - field.font->char_height;
118 }
119}
120
121void HealthdDraw::draw_clock(const animation* anim) {
122 static constexpr char CLOCK_FORMAT[] = "%H:%M";
123 static constexpr int CLOCK_LENGTH = 6;
124
125 const animation::text_field& field = anim->text_clock;
126
127 if (field.font == nullptr || field.font->char_width == 0 ||
128 field.font->char_height == 0)
129 return;
130
131 time_t rawtime;
132 time(&rawtime);
133 tm* time_info = localtime(&rawtime);
134
135 char clock_str[CLOCK_LENGTH];
136 size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info);
137 if (length != CLOCK_LENGTH - 1) {
138 LOGE("Could not format time\n");
139 return;
140 }
141
142 int x, y;
143 determine_xy(field, length, &x, &y);
144
145 LOGV("drawing clock %s %d %d\n", clock_str, x, y);
146 gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
147 draw_text(field.font, x, y, clock_str);
148}
149
150void HealthdDraw::draw_percent(const animation* anim) {
151 int cur_level = anim->cur_level;
152 if (anim->cur_status == BATTERY_STATUS_FULL) {
153 cur_level = 100;
154 }
155
156 if (cur_level <= 0) return;
157
158 const animation::text_field& field = anim->text_percent;
159 if (field.font == nullptr || field.font->char_width == 0 ||
160 field.font->char_height == 0) {
161 return;
162 }
163
164 std::string str = base::StringPrintf("%d%%", cur_level);
165
166 int x, y;
167 determine_xy(field, str.size(), &x, &y);
168
169 LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
170 gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
171 draw_text(field.font, x, y, str.c_str());
172}
173
174void HealthdDraw::draw_battery(const animation* anim) {
175 const animation::frame& frame = anim->frames[anim->cur_frame];
176
177 if (anim->num_frames != 0) {
178 draw_surface_centered(frame.surface);
179 LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame,
180 frame.min_level, frame.disp_time);
181 }
182 draw_clock(anim);
183 draw_percent(anim);
184}
185
186void HealthdDraw::draw_unknown(GRSurface* surf_unknown) {
187 int y;
188 if (surf_unknown) {
189 draw_surface_centered(surf_unknown);
190 } else {
191 gr_color(0xa4, 0xc6, 0x39, 255);
192 y = draw_text(gr_sys_font(), -1, -1, "Charging!");
193 draw_text(gr_sys_font(), -1, y + 25, "?\?/100");
194 }
195}