You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
5.7 KiB
195 lines
5.7 KiB
/* |
|
* Copyright (C) 2017 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. |
|
*/ |
|
|
|
#include <android-base/stringprintf.h> |
|
#include <batteryservice/BatteryService.h> |
|
#include <cutils/klog.h> |
|
|
|
#include "healthd_draw.h" |
|
|
|
#define LOGE(x...) KLOG_ERROR("charger", x); |
|
#define LOGV(x...) KLOG_DEBUG("charger", x); |
|
|
|
HealthdDraw::HealthdDraw(animation* anim) |
|
: kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), |
|
kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { |
|
gr_init(); |
|
gr_font_size(gr_sys_font(), &char_width_, &char_height_); |
|
|
|
screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1); |
|
screen_height_ = gr_fb_height(); |
|
|
|
int res; |
|
if (!anim->text_clock.font_file.empty() && |
|
(res = gr_init_font(anim->text_clock.font_file.c_str(), |
|
&anim->text_clock.font)) < 0) { |
|
LOGE("Could not load time font (%d)\n", res); |
|
} |
|
if (!anim->text_percent.font_file.empty() && |
|
(res = gr_init_font(anim->text_percent.font_file.c_str(), |
|
&anim->text_percent.font)) < 0) { |
|
LOGE("Could not load percent font (%d)\n", res); |
|
} |
|
} |
|
|
|
HealthdDraw::~HealthdDraw() {} |
|
|
|
void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { |
|
clear_screen(); |
|
|
|
/* try to display *something* */ |
|
if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) |
|
draw_unknown(surf_unknown); |
|
else |
|
draw_battery(batt_anim); |
|
gr_flip(); |
|
} |
|
|
|
void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); } |
|
|
|
void HealthdDraw::clear_screen(void) { |
|
gr_color(0, 0, 0, 255); |
|
gr_clear(); |
|
} |
|
|
|
int HealthdDraw::draw_surface_centered(GRSurface* surface) { |
|
int w = gr_get_width(surface); |
|
int h = gr_get_height(surface); |
|
int x = (screen_width_ - w) / 2 + kSplitOffset; |
|
int y = (screen_height_ - h) / 2; |
|
|
|
LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); |
|
gr_blit(surface, 0, 0, w, h, x, y); |
|
if (kSplitScreen) { |
|
x += screen_width_ - 2 * kSplitOffset; |
|
LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); |
|
gr_blit(surface, 0, 0, w, h, x, y); |
|
} |
|
|
|
return y + h; |
|
} |
|
|
|
int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) { |
|
int str_len_px = gr_measure(font, str); |
|
|
|
if (x < 0) x = (screen_width_ - str_len_px) / 2; |
|
if (y < 0) y = (screen_height_ - char_height_) / 2; |
|
gr_text(font, x + kSplitOffset, y, str, false /* bold */); |
|
if (kSplitScreen) |
|
gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */); |
|
|
|
return y + char_height_; |
|
} |
|
|
|
void HealthdDraw::determine_xy(const animation::text_field& field, |
|
const int length, int* x, int* y) { |
|
*x = field.pos_x; |
|
|
|
int str_len_px = length * field.font->char_width; |
|
if (field.pos_x == CENTER_VAL) { |
|
*x = (screen_width_ - str_len_px) / 2; |
|
} else if (field.pos_x >= 0) { |
|
*x = field.pos_x; |
|
} else { // position from max edge |
|
*x = screen_width_ + field.pos_x - str_len_px - kSplitOffset; |
|
} |
|
|
|
*y = field.pos_y; |
|
|
|
if (field.pos_y == CENTER_VAL) { |
|
*y = (screen_height_ - field.font->char_height) / 2; |
|
} else if (field.pos_y >= 0) { |
|
*y = field.pos_y; |
|
} else { // position from max edge |
|
*y = screen_height_ + field.pos_y - field.font->char_height; |
|
} |
|
} |
|
|
|
void HealthdDraw::draw_clock(const animation* anim) { |
|
static constexpr char CLOCK_FORMAT[] = "%H:%M"; |
|
static constexpr int CLOCK_LENGTH = 6; |
|
|
|
const animation::text_field& field = anim->text_clock; |
|
|
|
if (field.font == nullptr || field.font->char_width == 0 || |
|
field.font->char_height == 0) |
|
return; |
|
|
|
time_t rawtime; |
|
time(&rawtime); |
|
tm* time_info = localtime(&rawtime); |
|
|
|
char clock_str[CLOCK_LENGTH]; |
|
size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); |
|
if (length != CLOCK_LENGTH - 1) { |
|
LOGE("Could not format time\n"); |
|
return; |
|
} |
|
|
|
int x, y; |
|
determine_xy(field, length, &x, &y); |
|
|
|
LOGV("drawing clock %s %d %d\n", clock_str, x, y); |
|
gr_color(field.color_r, field.color_g, field.color_b, field.color_a); |
|
draw_text(field.font, x, y, clock_str); |
|
} |
|
|
|
void HealthdDraw::draw_percent(const animation* anim) { |
|
int cur_level = anim->cur_level; |
|
if (anim->cur_status == BATTERY_STATUS_FULL) { |
|
cur_level = 100; |
|
} |
|
|
|
if (cur_level <= 0) return; |
|
|
|
const animation::text_field& field = anim->text_percent; |
|
if (field.font == nullptr || field.font->char_width == 0 || |
|
field.font->char_height == 0) { |
|
return; |
|
} |
|
|
|
std::string str = base::StringPrintf("%d%%", cur_level); |
|
|
|
int x, y; |
|
determine_xy(field, str.size(), &x, &y); |
|
|
|
LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); |
|
gr_color(field.color_r, field.color_g, field.color_b, field.color_a); |
|
draw_text(field.font, x, y, str.c_str()); |
|
} |
|
|
|
void HealthdDraw::draw_battery(const animation* anim) { |
|
const animation::frame& frame = anim->frames[anim->cur_frame]; |
|
|
|
if (anim->num_frames != 0) { |
|
draw_surface_centered(frame.surface); |
|
LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, |
|
frame.min_level, frame.disp_time); |
|
} |
|
draw_clock(anim); |
|
draw_percent(anim); |
|
} |
|
|
|
void HealthdDraw::draw_unknown(GRSurface* surf_unknown) { |
|
int y; |
|
if (surf_unknown) { |
|
draw_surface_centered(surf_unknown); |
|
} else { |
|
gr_color(0xa4, 0xc6, 0x39, 255); |
|
y = draw_text(gr_sys_font(), -1, -1, "Charging!"); |
|
draw_text(gr_sys_font(), -1, y + 25, "?\?/100"); |
|
} |
|
}
|
|
|