1 /* 2 * Copyright (C) 2011-2013 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 <dirent.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <inttypes.h> 21 #include <linux/input.h> 22 #include <stdbool.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <sys/epoll.h> 27 #include <sys/stat.h> 28 #include <sys/types.h> 29 #include <sys/un.h> 30 #include <time.h> 31 #include <unistd.h> 32 33 #include <sys/socket.h> 34 #include <linux/netlink.h> 35 36 #include <batteryservice/BatteryService.h> 37 #include <cutils/android_reboot.h> 38 #include <cutils/klog.h> 39 #include <cutils/misc.h> 40 #include <cutils/uevent.h> 41 #include <cutils/properties.h> 42 43 #ifdef CHARGER_ENABLE_SUSPEND 44 #include <suspend/autosuspend.h> 45 #endif 46 47 #include "minui/minui.h" 48 49 #include "healthd.h" 50 51 char *locale; 52 53 #ifndef max 54 #define max(a,b) ((a) > (b) ? (a) : (b)) 55 #endif 56 57 #ifndef min 58 #define min(a,b) ((a) < (b) ? (a) : (b)) 59 #endif 60 61 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 62 63 #define MSEC_PER_SEC (1000LL) 64 #define NSEC_PER_MSEC (1000000LL) 65 66 #define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) 67 #define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) 68 #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC) 69 70 #define BATTERY_FULL_THRESH 95 71 #define SCREEN_ON_BATTERY_THRESH 0 72 73 #define LAST_KMSG_PATH "/proc/last_kmsg" 74 #define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops" 75 #define LAST_KMSG_MAX_SZ (32 * 1024) 76 77 #define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0) 78 #define LOGI(x...) do { KLOG_INFO("charger", x); } while (0) 79 #define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0) 80 81 struct key_state { 82 bool pending; 83 bool down; 84 int64_t timestamp; 85 }; 86 87 struct frame { 88 int disp_time; 89 int min_capacity; 90 bool level_only; 91 92 gr_surface surface; 93 }; 94 95 struct animation { 96 bool run; 97 98 struct frame *frames; 99 int cur_frame; 100 int num_frames; 101 102 int cur_cycle; 103 int num_cycles; 104 105 /* current capacity being animated */ 106 int capacity; 107 }; 108 109 struct charger { 110 bool have_battery_state; 111 bool charger_connected; 112 int capacity; 113 int64_t next_screen_transition; 114 int64_t next_key_check; 115 int64_t next_pwr_check; 116 117 struct key_state keys[KEY_MAX + 1]; 118 119 struct animation *batt_anim; 120 gr_surface surf_unknown; 121 }; 122 123 static struct frame batt_anim_frames[] = { 124 { 125 .disp_time = 750, 126 .min_capacity = 0, 127 .level_only = false, 128 .surface = NULL, 129 }, 130 { 131 .disp_time = 750, 132 .min_capacity = 20, 133 .level_only = false, 134 .surface = NULL, 135 }, 136 { 137 .disp_time = 750, 138 .min_capacity = 40, 139 .level_only = false, 140 .surface = NULL, 141 }, 142 { 143 .disp_time = 750, 144 .min_capacity = 60, 145 .level_only = false, 146 .surface = NULL, 147 }, 148 { 149 .disp_time = 750, 150 .min_capacity = 80, 151 .level_only = true, 152 .surface = NULL, 153 }, 154 { 155 .disp_time = 750, 156 .min_capacity = BATTERY_FULL_THRESH, 157 .level_only = false, 158 .surface = NULL, 159 }, 160 }; 161 162 static struct animation battery_animation = { 163 .run = false, 164 .frames = batt_anim_frames, 165 .cur_frame = 0, 166 .num_frames = ARRAY_SIZE(batt_anim_frames), 167 .cur_cycle = 0, 168 .num_cycles = 3, 169 .capacity = 0, 170 }; 171 172 static struct charger charger_state; 173 174 static int char_width; 175 static int char_height; 176 static bool minui_inited; 177 178 /* current time in milliseconds */ 179 static int64_t curr_time_ms(void) 180 { 181 struct timespec tm; 182 clock_gettime(CLOCK_MONOTONIC, &tm); 183 return tm.tv_sec * MSEC_PER_SEC + (tm.tv_nsec / NSEC_PER_MSEC); 184 } 185 186 static void clear_screen(void) 187 { 188 gr_color(0, 0, 0, 255); 189 gr_clear(); 190 } 191 192 #define MAX_KLOG_WRITE_BUF_SZ 256 193 194 static void dump_last_kmsg(void) 195 { 196 char *buf; 197 char *ptr; 198 unsigned sz = 0; 199 int len; 200 201 LOGI("\n"); 202 LOGI("*************** LAST KMSG ***************\n"); 203 LOGI("\n"); 204 buf = (char *)load_file(LAST_KMSG_PSTORE_PATH, &sz); 205 206 if (!buf || !sz) { 207 buf = (char *)load_file(LAST_KMSG_PATH, &sz); 208 if (!buf || !sz) { 209 LOGI("last_kmsg not found. Cold reset?\n"); 210 goto out; 211 } 212 } 213 214 len = min(sz, LAST_KMSG_MAX_SZ); 215 ptr = buf + (sz - len); 216 217 while (len > 0) { 218 int cnt = min(len, MAX_KLOG_WRITE_BUF_SZ); 219 char yoink; 220 char *nl; 221 222 nl = (char *)memrchr(ptr, '\n', cnt - 1); 223 if (nl) 224 cnt = nl - ptr + 1; 225 226 yoink = ptr[cnt]; 227 ptr[cnt] = '\0'; 228 klog_write(6, "<6>%s", ptr); 229 ptr[cnt] = yoink; 230 231 len -= cnt; 232 ptr += cnt; 233 } 234 235 free(buf); 236 237 out: 238 LOGI("\n"); 239 LOGI("************* END LAST KMSG *************\n"); 240 LOGI("\n"); 241 } 242 243 static int get_battery_capacity() 244 { 245 return charger_state.capacity; 246 } 247 248 #ifdef CHARGER_ENABLE_SUSPEND 249 static int request_suspend(bool enable) 250 { 251 if (enable) 252 return autosuspend_enable(); 253 else 254 return autosuspend_disable(); 255 } 256 #else 257 static int request_suspend(bool /*enable*/) 258 { 259 return 0; 260 } 261 #endif 262 263 static int draw_text(const char *str, int x, int y) 264 { 265 int str_len_px = gr_measure(str); 266 267 if (x < 0) 268 x = (gr_fb_width() - str_len_px) / 2; 269 if (y < 0) 270 y = (gr_fb_height() - char_height) / 2; 271 gr_text(x, y, str, 0); 272 273 return y + char_height; 274 } 275 276 static void android_green(void) 277 { 278 gr_color(0xa4, 0xc6, 0x39, 255); 279 } 280 281 /* returns the last y-offset of where the surface ends */ 282 static int draw_surface_centered(struct charger* /*charger*/, gr_surface surface) 283 { 284 int w; 285 int h; 286 int x; 287 int y; 288 289 w = gr_get_width(surface); 290 h = gr_get_height(surface); 291 x = (gr_fb_width() - w) / 2 ; 292 y = (gr_fb_height() - h) / 2 ; 293 294 LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); 295 gr_blit(surface, 0, 0, w, h, x, y); 296 return y + h; 297 } 298 299 static void draw_unknown(struct charger *charger) 300 { 301 int y; 302 if (charger->surf_unknown) { 303 draw_surface_centered(charger, charger->surf_unknown); 304 } else { 305 android_green(); 306 y = draw_text("Charging!", -1, -1); 307 draw_text("?\?/100", -1, y + 25); 308 } 309 } 310 311 static void draw_battery(struct charger *charger) 312 { 313 struct animation *batt_anim = charger->batt_anim; 314 struct frame *frame = &batt_anim->frames[batt_anim->cur_frame]; 315 316 if (batt_anim->num_frames != 0) { 317 draw_surface_centered(charger, frame->surface); 318 LOGV("drawing frame #%d min_cap=%d time=%d\n", 319 batt_anim->cur_frame, frame->min_capacity, 320 frame->disp_time); 321 } 322 } 323 324 static void redraw_screen(struct charger *charger) 325 { 326 struct animation *batt_anim = charger->batt_anim; 327 328 clear_screen(); 329 330 /* try to display *something* */ 331 if (batt_anim->capacity < 0 || batt_anim->num_frames == 0) 332 draw_unknown(charger); 333 else 334 draw_battery(charger); 335 gr_flip(); 336 } 337 338 static void kick_animation(struct animation *anim) 339 { 340 anim->run = true; 341 } 342 343 static void reset_animation(struct animation *anim) 344 { 345 anim->cur_cycle = 0; 346 anim->cur_frame = 0; 347 anim->run = false; 348 } 349 350 static void update_screen_state(struct charger *charger, int64_t now) 351 { 352 struct animation *batt_anim = charger->batt_anim; 353 int cur_frame; 354 int disp_time; 355 356 if (!batt_anim->run || now < charger->next_screen_transition) 357 return; 358 359 if (!minui_inited) { 360 int batt_cap = get_battery_capacity(); 361 362 if (batt_cap < SCREEN_ON_BATTERY_THRESH) { 363 LOGV("[%" PRId64 "] level %d, leave screen off\n", now, batt_cap); 364 batt_anim->run = false; 365 charger->next_screen_transition = -1; 366 if (charger->charger_connected) 367 request_suspend(true); 368 return; 369 } 370 371 gr_init(); 372 gr_font_size(&char_width, &char_height); 373 374 #ifndef CHARGER_DISABLE_INIT_BLANK 375 gr_fb_blank(true); 376 #endif 377 minui_inited = true; 378 } 379 380 /* animation is over, blank screen and leave */ 381 if (batt_anim->cur_cycle == batt_anim->num_cycles) { 382 reset_animation(batt_anim); 383 charger->next_screen_transition = -1; 384 gr_fb_blank(true); 385 LOGV("[%" PRId64 "] animation done\n", now); 386 if (charger->charger_connected) 387 request_suspend(true); 388 return; 389 } 390 391 disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time; 392 393 /* animation starting, set up the animation */ 394 if (batt_anim->cur_frame == 0) { 395 int batt_cap; 396 int ret; 397 398 LOGV("[%" PRId64 "] animation starting\n", now); 399 batt_cap = get_battery_capacity(); 400 if (batt_cap >= 0 && batt_anim->num_frames != 0) { 401 int i; 402 403 /* find first frame given current capacity */ 404 for (i = 1; i < batt_anim->num_frames; i++) { 405 if (batt_cap < batt_anim->frames[i].min_capacity) 406 break; 407 } 408 batt_anim->cur_frame = i - 1; 409 410 /* show the first frame for twice as long */ 411 disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * 2; 412 } 413 414 batt_anim->capacity = batt_cap; 415 } 416 417 /* unblank the screen on first cycle */ 418 if (batt_anim->cur_cycle == 0) 419 gr_fb_blank(false); 420 421 /* draw the new frame (@ cur_frame) */ 422 redraw_screen(charger); 423 424 /* if we don't have anim frames, we only have one image, so just bump 425 * the cycle counter and exit 426 */ 427 if (batt_anim->num_frames == 0 || batt_anim->capacity < 0) { 428 LOGV("[%" PRId64 "] animation missing or unknown battery status\n", now); 429 charger->next_screen_transition = now + BATTERY_UNKNOWN_TIME; 430 batt_anim->cur_cycle++; 431 return; 432 } 433 434 /* schedule next screen transition */ 435 charger->next_screen_transition = now + disp_time; 436 437 /* advance frame cntr to the next valid frame only if we are charging 438 * if necessary, advance cycle cntr, and reset frame cntr 439 */ 440 if (charger->charger_connected) { 441 batt_anim->cur_frame++; 442 443 /* if the frame is used for level-only, that is only show it when it's 444 * the current level, skip it during the animation. 445 */ 446 while (batt_anim->cur_frame < batt_anim->num_frames && 447 batt_anim->frames[batt_anim->cur_frame].level_only) 448 batt_anim->cur_frame++; 449 if (batt_anim->cur_frame >= batt_anim->num_frames) { 450 batt_anim->cur_cycle++; 451 batt_anim->cur_frame = 0; 452 453 /* don't reset the cycle counter, since we use that as a signal 454 * in a test above to check if animation is over 455 */ 456 } 457 } else { 458 /* Stop animating if we're not charging. 459 * If we stop it immediately instead of going through this loop, then 460 * the animation would stop somewhere in the middle. 461 */ 462 batt_anim->cur_frame = 0; 463 batt_anim->cur_cycle++; 464 } 465 } 466 467 static int set_key_callback(int code, int value, void *data) 468 { 469 struct charger *charger = (struct charger *)data; 470 int64_t now = curr_time_ms(); 471 int down = !!value; 472 473 if (code > KEY_MAX) 474 return -1; 475 476 /* ignore events that don't modify our state */ 477 if (charger->keys[code].down == down) 478 return 0; 479 480 /* only record the down even timestamp, as the amount 481 * of time the key spent not being pressed is not useful */ 482 if (down) 483 charger->keys[code].timestamp = now; 484 charger->keys[code].down = down; 485 charger->keys[code].pending = true; 486 if (down) { 487 LOGV("[%" PRId64 "] key[%d] down\n", now, code); 488 } else { 489 int64_t duration = now - charger->keys[code].timestamp; 490 int64_t secs = duration / 1000; 491 int64_t msecs = duration - secs * 1000; 492 LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", 493 now, code, secs, msecs); 494 } 495 496 return 0; 497 } 498 499 static void update_input_state(struct charger *charger, 500 struct input_event *ev) 501 { 502 if (ev->type != EV_KEY) 503 return; 504 set_key_callback(ev->code, ev->value, charger); 505 } 506 507 static void set_next_key_check(struct charger *charger, 508 struct key_state *key, 509 int64_t timeout) 510 { 511 int64_t then = key->timestamp + timeout; 512 513 if (charger->next_key_check == -1 || then < charger->next_key_check) 514 charger->next_key_check = then; 515 } 516 517 static void process_key(struct charger *charger, int code, int64_t now) 518 { 519 struct key_state *key = &charger->keys[code]; 520 int64_t next_key_check; 521 522 if (code == KEY_POWER) { 523 if (key->down) { 524 int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME; 525 if (now >= reboot_timeout) { 526 /* We do not currently support booting from charger mode on 527 all devices. Check the property and continue booting or reboot 528 accordingly. */ 529 if (property_get_bool("ro.enable_boot_charger_mode", false)) { 530 LOGI("[%" PRId64 "] booting from charger mode\n", now); 531 property_set("sys.boot_from_charger_mode", "1"); 532 } else { 533 LOGI("[%" PRId64 "] rebooting\n", now); 534 android_reboot(ANDROID_RB_RESTART, 0, 0); 535 } 536 } else { 537 /* if the key is pressed but timeout hasn't expired, 538 * make sure we wake up at the right-ish time to check 539 */ 540 set_next_key_check(charger, key, POWER_ON_KEY_TIME); 541 } 542 } else { 543 /* if the power key got released, force screen state cycle */ 544 if (key->pending) { 545 request_suspend(false); 546 kick_animation(charger->batt_anim); 547 } 548 } 549 } 550 551 key->pending = false; 552 } 553 554 static void handle_input_state(struct charger *charger, int64_t now) 555 { 556 process_key(charger, KEY_POWER, now); 557 558 if (charger->next_key_check != -1 && now > charger->next_key_check) 559 charger->next_key_check = -1; 560 } 561 562 static void handle_power_supply_state(struct charger *charger, int64_t now) 563 { 564 if (!charger->have_battery_state) 565 return; 566 567 if (!charger->charger_connected) { 568 request_suspend(false); 569 if (charger->next_pwr_check == -1) { 570 charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME; 571 LOGI("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n", 572 now, (int64_t)UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check); 573 } else if (now >= charger->next_pwr_check) { 574 LOGI("[%" PRId64 "] shutting down\n", now); 575 android_reboot(ANDROID_RB_POWEROFF, 0, 0); 576 } else { 577 /* otherwise we already have a shutdown timer scheduled */ 578 } 579 } else { 580 /* online supply present, reset shutdown timer if set */ 581 if (charger->next_pwr_check != -1) { 582 LOGI("[%" PRId64 "] device plugged in: shutdown cancelled\n", now); 583 kick_animation(charger->batt_anim); 584 } 585 charger->next_pwr_check = -1; 586 } 587 } 588 589 void healthd_mode_charger_heartbeat() 590 { 591 struct charger *charger = &charger_state; 592 int64_t now = curr_time_ms(); 593 int ret; 594 595 handle_input_state(charger, now); 596 handle_power_supply_state(charger, now); 597 598 /* do screen update last in case any of the above want to start 599 * screen transitions (animations, etc) 600 */ 601 update_screen_state(charger, now); 602 } 603 604 void healthd_mode_charger_battery_update( 605 struct android::BatteryProperties *props) 606 { 607 struct charger *charger = &charger_state; 608 609 charger->charger_connected = 610 props->chargerAcOnline || props->chargerUsbOnline || 611 props->chargerWirelessOnline; 612 charger->capacity = props->batteryLevel; 613 614 if (!charger->have_battery_state) { 615 charger->have_battery_state = true; 616 charger->next_screen_transition = curr_time_ms() - 1; 617 reset_animation(charger->batt_anim); 618 kick_animation(charger->batt_anim); 619 } 620 } 621 622 int healthd_mode_charger_preparetowait(void) 623 { 624 struct charger *charger = &charger_state; 625 int64_t now = curr_time_ms(); 626 int64_t next_event = INT64_MAX; 627 int64_t timeout; 628 struct input_event ev; 629 int ret; 630 631 LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", now, 632 charger->next_screen_transition, charger->next_key_check, 633 charger->next_pwr_check); 634 635 if (charger->next_screen_transition != -1) 636 next_event = charger->next_screen_transition; 637 if (charger->next_key_check != -1 && charger->next_key_check < next_event) 638 next_event = charger->next_key_check; 639 if (charger->next_pwr_check != -1 && charger->next_pwr_check < next_event) 640 next_event = charger->next_pwr_check; 641 642 if (next_event != -1 && next_event != INT64_MAX) 643 timeout = max(0, next_event - now); 644 else 645 timeout = -1; 646 647 return (int)timeout; 648 } 649 650 static int input_callback(int fd, unsigned int epevents, void *data) 651 { 652 struct charger *charger = (struct charger *)data; 653 struct input_event ev; 654 int ret; 655 656 ret = ev_get_input(fd, epevents, &ev); 657 if (ret) 658 return -1; 659 update_input_state(charger, &ev); 660 return 0; 661 } 662 663 static void charger_event_handler(uint32_t /*epevents*/) 664 { 665 int ret; 666 667 ret = ev_wait(-1); 668 if (!ret) 669 ev_dispatch(); 670 } 671 672 void healthd_mode_charger_init(struct healthd_config* /*config*/) 673 { 674 int ret; 675 struct charger *charger = &charger_state; 676 int i; 677 int epollfd; 678 679 dump_last_kmsg(); 680 681 LOGI("--------------- STARTING CHARGER MODE ---------------\n"); 682 683 ret = ev_init(input_callback, charger); 684 if (!ret) { 685 epollfd = ev_get_epollfd(); 686 healthd_register_event(epollfd, charger_event_handler); 687 } 688 689 ret = res_create_display_surface("charger/battery_fail", &charger->surf_unknown); 690 if (ret < 0) { 691 LOGE("Cannot load battery_fail image\n"); 692 charger->surf_unknown = NULL; 693 } 694 695 charger->batt_anim = &battery_animation; 696 697 gr_surface* scale_frames; 698 int scale_count; 699 ret = res_create_multi_display_surface("charger/battery_scale", &scale_count, &scale_frames); 700 if (ret < 0) { 701 LOGE("Cannot load battery_scale image\n"); 702 charger->batt_anim->num_frames = 0; 703 charger->batt_anim->num_cycles = 1; 704 } else if (scale_count != charger->batt_anim->num_frames) { 705 LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", 706 scale_count, charger->batt_anim->num_frames); 707 charger->batt_anim->num_frames = 0; 708 charger->batt_anim->num_cycles = 1; 709 } else { 710 for (i = 0; i < charger->batt_anim->num_frames; i++) { 711 charger->batt_anim->frames[i].surface = scale_frames[i]; 712 } 713 } 714 715 ev_sync_key_state(set_key_callback, charger); 716 717 charger->next_screen_transition = -1; 718 charger->next_key_check = -1; 719 charger->next_pwr_check = -1; 720 } 721