Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 1 | /* |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 2 | * Copyright (C) 2011-2017 The Android Open Source Project |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 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 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 17 | #include <charger/healthd_mode_charger.h> |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 18 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 19 | #include <dirent.h> |
| 20 | #include <errno.h> |
| 21 | #include <fcntl.h> |
Colin Cross | e1d5247 | 2014-05-15 17:49:06 -0700 | [diff] [blame] | 22 | #include <inttypes.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 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 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 33 | #include <optional> |
Tao Bao | 92c2601 | 2017-01-18 22:54:54 -0800 | [diff] [blame] | 34 | |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 35 | #include <android-base/file.h> |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 36 | #include <android-base/logging.h> |
Mark Salyzyn | 26f1dd7 | 2017-06-27 09:19:09 -0700 | [diff] [blame] | 37 | #include <android-base/macros.h> |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 38 | #include <android-base/strings.h> |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 39 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 40 | #include <linux/netlink.h> |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 41 | #include <sys/socket.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 42 | |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 43 | #include <cutils/android_get_control_file.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 44 | #include <cutils/klog.h> |
| 45 | #include <cutils/misc.h> |
Riley Andrews | 6bd4588 | 2014-06-23 15:20:51 -0700 | [diff] [blame] | 46 | #include <cutils/properties.h> |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 47 | #include <cutils/uevent.h> |
Todd Poynor | c8183bb | 2017-01-31 15:51:50 -0800 | [diff] [blame] | 48 | #include <sys/reboot.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 49 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 50 | #include <suspend/autosuspend.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 51 | |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 52 | #include "AnimationParser.h" |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 53 | #include "healthd_draw.h" |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 54 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 55 | #include <aidl/android/hardware/health/BatteryStatus.h> |
| 56 | #include <health/HealthLoop.h> |
Yabin Cui | e98e177 | 2016-02-17 12:21:34 -0800 | [diff] [blame] | 57 | #include <healthd/healthd.h> |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 58 | |
Yifan Hong | e3ffd1b | 2021-10-20 22:18:16 -0700 | [diff] [blame] | 59 | #if !defined(__ANDROID_VNDK__) |
| 60 | #include "charger.sysprop.h" |
| 61 | #endif |
| 62 | |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 63 | using std::string_literals::operator""s; |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 64 | using namespace android; |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 65 | using aidl::android::hardware::health::BatteryStatus; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 66 | using android::hardware::health::HealthLoop; |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 67 | |
Tao Bao | 5747e22 | 2018-09-11 10:46:35 -0700 | [diff] [blame] | 68 | // main healthd loop |
| 69 | extern int healthd_main(void); |
| 70 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 71 | // minui globals |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 72 | char* locale; |
Colin Cross | 1c38f5d | 2014-02-13 13:34:37 -0800 | [diff] [blame] | 73 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 74 | #ifndef max |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 75 | #define max(a, b) ((a) > (b) ? (a) : (b)) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 76 | #endif |
| 77 | |
| 78 | #ifndef min |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 79 | #define min(a, b) ((a) < (b) ? (a) : (b)) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 80 | #endif |
| 81 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 82 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 83 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 84 | #define MSEC_PER_SEC (1000LL) |
| 85 | #define NSEC_PER_MSEC (1000000LL) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 86 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 87 | #define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) |
| 88 | #define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 89 | #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC) |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 90 | #define UNPLUGGED_DISPLAY_TIME (3 * MSEC_PER_SEC) |
Ken Tsou | 6c7ece7 | 2019-02-15 10:50:58 +0800 | [diff] [blame] | 91 | #define MAX_BATT_LEVEL_WAIT_TIME (3 * MSEC_PER_SEC) |
John Zhao | 5cac100 | 2019-03-31 17:22:47 +0800 | [diff] [blame] | 92 | #define UNPLUGGED_SHUTDOWN_TIME_PROP "ro.product.charger.unplugged_shutdown_time" |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 93 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 94 | #define LAST_KMSG_MAX_SZ (32 * 1024) |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 95 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 96 | #define LOGE(x...) KLOG_ERROR("charger", x); |
| 97 | #define LOGW(x...) KLOG_WARNING("charger", x); |
| 98 | #define LOGV(x...) KLOG_DEBUG("charger", x); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 99 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 100 | namespace android { |
| 101 | |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 102 | #if defined(__ANDROID_VNDK__) |
| 103 | static constexpr const char* vendor_animation_desc_path = |
| 104 | "/vendor/etc/res/values/charger/animation.txt"; |
| 105 | static constexpr const char* vendor_animation_root = "/vendor/etc/res/images/"; |
| 106 | static constexpr const char* vendor_default_animation_root = "/vendor/etc/res/images/default/"; |
| 107 | #else |
| 108 | |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 109 | // Legacy animation resources are loaded from this directory. |
| 110 | static constexpr const char* legacy_animation_root = "/res/images/"; |
| 111 | |
| 112 | // Built-in animation resources are loaded from this directory. |
| 113 | static constexpr const char* system_animation_root = "/system/etc/res/images/"; |
| 114 | |
| 115 | // Resources in /product/etc/res overrides resources in /res and /system/etc/res. |
Yifan Hong | 082d295 | 2019-01-28 12:55:54 -0800 | [diff] [blame] | 116 | // If the device is using the Generic System Image (GSI), resources may exist in |
| 117 | // both paths. |
| 118 | static constexpr const char* product_animation_desc_path = |
| 119 | "/product/etc/res/values/charger/animation.txt"; |
| 120 | static constexpr const char* product_animation_root = "/product/etc/res/images/"; |
| 121 | static constexpr const char* animation_desc_path = "/res/values/charger/animation.txt"; |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 122 | #endif |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 123 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 124 | static const animation BASE_ANIMATION = { |
| 125 | .text_clock = |
| 126 | { |
| 127 | .pos_x = 0, |
| 128 | .pos_y = 0, |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 129 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 130 | .color_r = 255, |
| 131 | .color_g = 255, |
| 132 | .color_b = 255, |
| 133 | .color_a = 255, |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 134 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 135 | .font = nullptr, |
| 136 | }, |
| 137 | .text_percent = |
| 138 | { |
| 139 | .pos_x = 0, |
| 140 | .pos_y = 0, |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 141 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 142 | .color_r = 255, |
| 143 | .color_g = 255, |
| 144 | .color_b = 255, |
| 145 | .color_a = 255, |
| 146 | }, |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 147 | |
| 148 | .run = false, |
| 149 | |
| 150 | .frames = nullptr, |
| 151 | .cur_frame = 0, |
| 152 | .num_frames = 0, |
| 153 | .first_frame_repeats = 2, |
| 154 | |
| 155 | .cur_cycle = 0, |
| 156 | .num_cycles = 3, |
| 157 | |
| 158 | .cur_level = 0, |
| 159 | .cur_status = BATTERY_STATUS_UNKNOWN, |
| 160 | }; |
| 161 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 162 | void Charger::InitDefaultAnimationFrames() { |
| 163 | owned_frames_ = { |
| 164 | { |
| 165 | .disp_time = 750, |
| 166 | .min_level = 0, |
| 167 | .max_level = 19, |
| 168 | .surface = NULL, |
| 169 | }, |
| 170 | { |
| 171 | .disp_time = 750, |
| 172 | .min_level = 0, |
| 173 | .max_level = 39, |
| 174 | .surface = NULL, |
| 175 | }, |
| 176 | { |
| 177 | .disp_time = 750, |
| 178 | .min_level = 0, |
| 179 | .max_level = 59, |
| 180 | .surface = NULL, |
| 181 | }, |
| 182 | { |
| 183 | .disp_time = 750, |
| 184 | .min_level = 0, |
| 185 | .max_level = 79, |
| 186 | .surface = NULL, |
| 187 | }, |
| 188 | { |
| 189 | .disp_time = 750, |
| 190 | .min_level = 80, |
| 191 | .max_level = 95, |
| 192 | .surface = NULL, |
| 193 | }, |
| 194 | { |
| 195 | .disp_time = 750, |
| 196 | .min_level = 0, |
| 197 | .max_level = 100, |
| 198 | .surface = NULL, |
| 199 | }, |
| 200 | }; |
| 201 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 202 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 203 | Charger::Charger(ChargerConfigurationInterface* configuration) |
| 204 | : batt_anim_(BASE_ANIMATION), configuration_(configuration) {} |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 205 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 206 | Charger::~Charger() {} |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 207 | |
| 208 | /* current time in milliseconds */ |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 209 | static int64_t curr_time_ms() { |
| 210 | timespec tm; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 211 | clock_gettime(CLOCK_MONOTONIC, &tm); |
| 212 | return tm.tv_sec * MSEC_PER_SEC + (tm.tv_nsec / NSEC_PER_MSEC); |
| 213 | } |
| 214 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 215 | #define MAX_KLOG_WRITE_BUF_SZ 256 |
| 216 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 217 | static void dump_last_kmsg(void) { |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 218 | std::string buf; |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 219 | char* ptr; |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 220 | size_t len; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 221 | |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 222 | LOGW("*************** LAST KMSG ***************\n"); |
Mark Salyzyn | 26f1dd7 | 2017-06-27 09:19:09 -0700 | [diff] [blame] | 223 | const char* kmsg[] = { |
| 224 | // clang-format off |
| 225 | "/sys/fs/pstore/console-ramoops-0", |
| 226 | "/sys/fs/pstore/console-ramoops", |
| 227 | "/proc/last_kmsg", |
| 228 | // clang-format on |
| 229 | }; |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 230 | for (size_t i = 0; i < arraysize(kmsg) && buf.empty(); ++i) { |
| 231 | auto fd = android_get_control_file(kmsg[i]); |
| 232 | if (fd >= 0) { |
| 233 | android::base::ReadFdToString(fd, &buf); |
| 234 | } else { |
| 235 | android::base::ReadFileToString(kmsg[i], &buf); |
| 236 | } |
Mark Salyzyn | 26f1dd7 | 2017-06-27 09:19:09 -0700 | [diff] [blame] | 237 | } |
Todd Poynor | cd7c104 | 2013-11-22 17:52:59 -0800 | [diff] [blame] | 238 | |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 239 | if (buf.empty()) { |
Mark Salyzyn | 26f1dd7 | 2017-06-27 09:19:09 -0700 | [diff] [blame] | 240 | LOGW("last_kmsg not found. Cold reset?\n"); |
| 241 | goto out; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 242 | } |
| 243 | |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 244 | len = min(buf.size(), LAST_KMSG_MAX_SZ); |
| 245 | ptr = &buf[buf.size() - len]; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 246 | |
| 247 | while (len > 0) { |
Yifan Hong | dc9c08b | 2019-03-25 18:09:35 -0700 | [diff] [blame] | 248 | size_t cnt = min(len, MAX_KLOG_WRITE_BUF_SZ); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 249 | char yoink; |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 250 | char* nl; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 251 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 252 | nl = (char*)memrchr(ptr, '\n', cnt - 1); |
| 253 | if (nl) cnt = nl - ptr + 1; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 254 | |
| 255 | yoink = ptr[cnt]; |
| 256 | ptr[cnt] = '\0'; |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 257 | klog_write(6, "<4>%s", ptr); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 258 | ptr[cnt] = yoink; |
| 259 | |
| 260 | len -= cnt; |
| 261 | ptr += cnt; |
| 262 | } |
| 263 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 264 | out: |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 265 | LOGW("************* END LAST KMSG *************\n"); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 266 | } |
| 267 | |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 268 | int Charger::RequestEnableSuspend() { |
| 269 | if (!configuration_->ChargerEnableSuspend()) { |
Yifan Hong | 97eecdc | 2019-07-03 11:07:37 -0700 | [diff] [blame] | 270 | return 0; |
| 271 | } |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 272 | return autosuspend_enable(); |
| 273 | } |
Yifan Hong | 97eecdc | 2019-07-03 11:07:37 -0700 | [diff] [blame] | 274 | |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 275 | int Charger::RequestDisableSuspend() { |
| 276 | if (!configuration_->ChargerEnableSuspend()) { |
| 277 | return 0; |
| 278 | } |
| 279 | return autosuspend_disable(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 280 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 281 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 282 | static void kick_animation(animation* anim) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 283 | anim->run = true; |
| 284 | } |
| 285 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 286 | static void reset_animation(animation* anim) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 287 | anim->cur_cycle = 0; |
| 288 | anim->cur_frame = 0; |
| 289 | anim->run = false; |
| 290 | } |
| 291 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 292 | void Charger::UpdateScreenState(int64_t now) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 293 | int disp_time; |
| 294 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 295 | if (!batt_anim_.run || now < next_screen_transition_) return; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 296 | |
Ken Tsou | 6c7ece7 | 2019-02-15 10:50:58 +0800 | [diff] [blame] | 297 | // If battery level is not ready, keep checking in the defined time |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 298 | if (health_info_.battery_level == 0 && health_info_.battery_status == BatteryStatus::UNKNOWN) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 299 | if (wait_batt_level_timestamp_ == 0) { |
Ken Tsou | 6c7ece7 | 2019-02-15 10:50:58 +0800 | [diff] [blame] | 300 | // Set max delay time and skip drawing screen |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 301 | wait_batt_level_timestamp_ = now + MAX_BATT_LEVEL_WAIT_TIME; |
Ken Tsou | 6c7ece7 | 2019-02-15 10:50:58 +0800 | [diff] [blame] | 302 | LOGV("[%" PRId64 "] wait for battery capacity ready\n", now); |
| 303 | return; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 304 | } else if (now <= wait_batt_level_timestamp_) { |
Ken Tsou | 6c7ece7 | 2019-02-15 10:50:58 +0800 | [diff] [blame] | 305 | // Do nothing, keep waiting |
| 306 | return; |
| 307 | } |
| 308 | // If timeout and battery level is still not ready, draw unknown battery |
| 309 | } |
| 310 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 311 | if (healthd_draw_ == nullptr) { |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 312 | std::optional<bool> out_screen_on = configuration_->ChargerShouldKeepScreenOn(); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 313 | if (out_screen_on.has_value()) { |
| 314 | if (!*out_screen_on) { |
Ruchi Kandoi | bdf11c7 | 2014-09-25 19:44:42 -0700 | [diff] [blame] | 315 | LOGV("[%" PRId64 "] leave screen off\n", now); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 316 | batt_anim_.run = false; |
| 317 | next_screen_transition_ = -1; |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 318 | if (configuration_->ChargerIsOnline()) { |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 319 | RequestEnableSuspend(); |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 320 | } |
Ruchi Kandoi | bdf11c7 | 2014-09-25 19:44:42 -0700 | [diff] [blame] | 321 | return; |
| 322 | } |
Todd Poynor | a730027 | 2014-06-30 13:15:05 -0700 | [diff] [blame] | 323 | } |
| 324 | |
Xiaohui Niu | a40d872 | 2021-08-31 16:22:25 +0800 | [diff] [blame] | 325 | healthd_draw_ = HealthdDraw::Create(&batt_anim_); |
| 326 | if (healthd_draw_ == nullptr) return; |
Todd Poynor | a730027 | 2014-06-30 13:15:05 -0700 | [diff] [blame] | 327 | |
Yifan Hong | e3ffd1b | 2021-10-20 22:18:16 -0700 | [diff] [blame] | 328 | #if !defined(__ANDROID_VNDK__) |
Yifan Hong | 97eecdc | 2019-07-03 11:07:37 -0700 | [diff] [blame] | 329 | if (android::sysprop::ChargerProperties::disable_init_blank().value_or(false)) { |
Jack Wu | c1b1711 | 2021-09-29 22:27:56 +0800 | [diff] [blame] | 330 | healthd_draw_->blank_screen(true, static_cast<int>(drm_)); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 331 | screen_blanked_ = true; |
Yifan Hong | 97eecdc | 2019-07-03 11:07:37 -0700 | [diff] [blame] | 332 | } |
Yifan Hong | e3ffd1b | 2021-10-20 22:18:16 -0700 | [diff] [blame] | 333 | #endif |
Todd Poynor | a730027 | 2014-06-30 13:15:05 -0700 | [diff] [blame] | 334 | } |
| 335 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 336 | /* animation is over, blank screen and leave */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 337 | if (batt_anim_.num_cycles > 0 && batt_anim_.cur_cycle == batt_anim_.num_cycles) { |
| 338 | reset_animation(&batt_anim_); |
| 339 | next_screen_transition_ = -1; |
Jack Wu | c1b1711 | 2021-09-29 22:27:56 +0800 | [diff] [blame] | 340 | healthd_draw_->blank_screen(true, static_cast<int>(drm_)); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 341 | screen_blanked_ = true; |
Colin Cross | e1d5247 | 2014-05-15 17:49:06 -0700 | [diff] [blame] | 342 | LOGV("[%" PRId64 "] animation done\n", now); |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 343 | if (configuration_->ChargerIsOnline()) { |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 344 | RequestEnableSuspend(); |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 345 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 346 | return; |
| 347 | } |
| 348 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 349 | disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 350 | |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 351 | /* turn off all screen */ |
| 352 | if (screen_switch_ == SCREEN_SWITCH_ENABLE) { |
| 353 | healthd_draw_->blank_screen(true, 0 /* drm */); |
| 354 | healthd_draw_->blank_screen(true, 1 /* drm */); |
Jack Wu | 56540a0 | 2021-10-22 17:10:37 +0800 | [diff] [blame] | 355 | healthd_draw_->rotate_screen(static_cast<int>(drm_)); |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 356 | screen_blanked_ = true; |
| 357 | screen_switch_ = SCREEN_SWITCH_DISABLE; |
| 358 | } |
| 359 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 360 | if (screen_blanked_) { |
Jack Wu | c1b1711 | 2021-09-29 22:27:56 +0800 | [diff] [blame] | 361 | healthd_draw_->blank_screen(false, static_cast<int>(drm_)); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 362 | screen_blanked_ = false; |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 363 | } |
Thierry Strudel | ac2aa7d | 2018-05-23 15:48:46 -0700 | [diff] [blame] | 364 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 365 | /* animation starting, set up the animation */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 366 | if (batt_anim_.cur_frame == 0) { |
Colin Cross | e1d5247 | 2014-05-15 17:49:06 -0700 | [diff] [blame] | 367 | LOGV("[%" PRId64 "] animation starting\n", now); |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 368 | batt_anim_.cur_level = health_info_.battery_level; |
| 369 | batt_anim_.cur_status = (int)health_info_.battery_status; |
| 370 | if (health_info_.battery_level >= 0 && batt_anim_.num_frames != 0) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 371 | /* find first frame given current battery level */ |
| 372 | for (int i = 0; i < batt_anim_.num_frames; i++) { |
| 373 | if (batt_anim_.cur_level >= batt_anim_.frames[i].min_level && |
| 374 | batt_anim_.cur_level <= batt_anim_.frames[i].max_level) { |
| 375 | batt_anim_.cur_frame = i; |
| 376 | break; |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 377 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 378 | } |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 379 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 380 | if (configuration_->ChargerIsOnline()) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 381 | // repeat the first frame first_frame_repeats times |
| 382 | disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time * |
| 383 | batt_anim_.first_frame_repeats; |
| 384 | } else { |
| 385 | disp_time = UNPLUGGED_DISPLAY_TIME / batt_anim_.num_cycles; |
| 386 | } |
| 387 | |
| 388 | LOGV("cur_frame=%d disp_time=%d\n", batt_anim_.cur_frame, disp_time); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 389 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 390 | } |
| 391 | |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 392 | /* draw the new frame (@ cur_frame) */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 393 | healthd_draw_->redraw_screen(&batt_anim_, surf_unknown_); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 394 | |
| 395 | /* if we don't have anim frames, we only have one image, so just bump |
| 396 | * the cycle counter and exit |
| 397 | */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 398 | if (batt_anim_.num_frames == 0 || batt_anim_.cur_level < 0) { |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 399 | LOGW("[%" PRId64 "] animation missing or unknown battery status\n", now); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 400 | next_screen_transition_ = now + BATTERY_UNKNOWN_TIME; |
| 401 | batt_anim_.cur_cycle++; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 402 | return; |
| 403 | } |
| 404 | |
| 405 | /* schedule next screen transition */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 406 | next_screen_transition_ = curr_time_ms() + disp_time; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 407 | |
Ruchi Kandoi | 9015eaa | 2014-06-23 11:13:15 -0700 | [diff] [blame] | 408 | /* advance frame cntr to the next valid frame only if we are charging |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 409 | * if necessary, advance cycle cntr, and reset frame cntr |
| 410 | */ |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 411 | if (configuration_->ChargerIsOnline()) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 412 | batt_anim_.cur_frame++; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 413 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 414 | while (batt_anim_.cur_frame < batt_anim_.num_frames && |
| 415 | (batt_anim_.cur_level < batt_anim_.frames[batt_anim_.cur_frame].min_level || |
| 416 | batt_anim_.cur_level > batt_anim_.frames[batt_anim_.cur_frame].max_level)) { |
| 417 | batt_anim_.cur_frame++; |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 418 | } |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 419 | if (batt_anim_.cur_frame >= batt_anim_.num_frames) { |
| 420 | batt_anim_.cur_cycle++; |
| 421 | batt_anim_.cur_frame = 0; |
Ruchi Kandoi | 9015eaa | 2014-06-23 11:13:15 -0700 | [diff] [blame] | 422 | |
| 423 | /* don't reset the cycle counter, since we use that as a signal |
| 424 | * in a test above to check if animation is over |
| 425 | */ |
| 426 | } |
| 427 | } else { |
| 428 | /* Stop animating if we're not charging. |
| 429 | * If we stop it immediately instead of going through this loop, then |
| 430 | * the animation would stop somewhere in the middle. |
| 431 | */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 432 | batt_anim_.cur_frame = 0; |
| 433 | batt_anim_.cur_cycle++; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 434 | } |
| 435 | } |
| 436 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 437 | int Charger::SetKeyCallback(int code, int value) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 438 | int64_t now = curr_time_ms(); |
| 439 | int down = !!value; |
| 440 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 441 | if (code > KEY_MAX) return -1; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 442 | |
| 443 | /* ignore events that don't modify our state */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 444 | if (keys_[code].down == down) return 0; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 445 | |
| 446 | /* only record the down even timestamp, as the amount |
| 447 | * of time the key spent not being pressed is not useful */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 448 | if (down) keys_[code].timestamp = now; |
| 449 | keys_[code].down = down; |
| 450 | keys_[code].pending = true; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 451 | if (down) { |
Colin Cross | e1d5247 | 2014-05-15 17:49:06 -0700 | [diff] [blame] | 452 | LOGV("[%" PRId64 "] key[%d] down\n", now, code); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 453 | } else { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 454 | int64_t duration = now - keys_[code].timestamp; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 455 | int64_t secs = duration / 1000; |
| 456 | int64_t msecs = duration - secs * 1000; |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 457 | LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", now, code, |
| 458 | secs, msecs); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 459 | } |
| 460 | |
| 461 | return 0; |
| 462 | } |
| 463 | |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 464 | int Charger::SetSwCallback(int code, int value) { |
| 465 | if (code > SW_MAX) return -1; |
| 466 | if (code == SW_LID) { |
| 467 | if ((screen_switch_ == SCREEN_SWITCH_DEFAULT) || ((value != 0) && (drm_ == DRM_INNER)) || |
| 468 | ((value == 0) && (drm_ == DRM_OUTER))) { |
| 469 | screen_switch_ = SCREEN_SWITCH_ENABLE; |
| 470 | drm_ = (value != 0) ? DRM_OUTER : DRM_INNER; |
| 471 | keys_[code].pending = true; |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | return 0; |
| 476 | } |
| 477 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 478 | void Charger::UpdateInputState(input_event* ev) { |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 479 | if (ev->type == EV_SW && ev->code == SW_LID) { |
| 480 | SetSwCallback(ev->code, ev->value); |
| 481 | return; |
| 482 | } |
| 483 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 484 | if (ev->type != EV_KEY) return; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 485 | SetKeyCallback(ev->code, ev->value); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 486 | } |
| 487 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 488 | void Charger::SetNextKeyCheck(key_state* key, int64_t timeout) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 489 | int64_t then = key->timestamp + timeout; |
| 490 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 491 | if (next_key_check_ == -1 || then < next_key_check_) next_key_check_ = then; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 492 | } |
| 493 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 494 | void Charger::ProcessKey(int code, int64_t now) { |
| 495 | key_state* key = &keys_[code]; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 496 | |
| 497 | if (code == KEY_POWER) { |
| 498 | if (key->down) { |
| 499 | int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME; |
| 500 | if (now >= reboot_timeout) { |
Riley Andrews | 6bd4588 | 2014-06-23 15:20:51 -0700 | [diff] [blame] | 501 | /* We do not currently support booting from charger mode on |
| 502 | all devices. Check the property and continue booting or reboot |
| 503 | accordingly. */ |
| 504 | if (property_get_bool("ro.enable_boot_charger_mode", false)) { |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 505 | LOGW("[%" PRId64 "] booting from charger mode\n", now); |
Riley Andrews | 6bd4588 | 2014-06-23 15:20:51 -0700 | [diff] [blame] | 506 | property_set("sys.boot_from_charger_mode", "1"); |
| 507 | } else { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 508 | if (batt_anim_.cur_level >= boot_min_cap_) { |
Ruchi Kandoi | a84b1f6 | 2014-10-21 18:24:11 -0700 | [diff] [blame] | 509 | LOGW("[%" PRId64 "] rebooting\n", now); |
Todd Poynor | c8183bb | 2017-01-31 15:51:50 -0800 | [diff] [blame] | 510 | reboot(RB_AUTOBOOT); |
Ruchi Kandoi | a84b1f6 | 2014-10-21 18:24:11 -0700 | [diff] [blame] | 511 | } else { |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 512 | LOGV("[%" PRId64 |
| 513 | "] ignore power-button press, battery level " |
| 514 | "less than minimum\n", |
| 515 | now); |
Ruchi Kandoi | a84b1f6 | 2014-10-21 18:24:11 -0700 | [diff] [blame] | 516 | } |
Riley Andrews | 6bd4588 | 2014-06-23 15:20:51 -0700 | [diff] [blame] | 517 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 518 | } else { |
| 519 | /* if the key is pressed but timeout hasn't expired, |
| 520 | * make sure we wake up at the right-ish time to check |
| 521 | */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 522 | SetNextKeyCheck(key, POWER_ON_KEY_TIME); |
Ruchi Kandoi | 9a11aaa | 2014-10-22 14:16:35 -0700 | [diff] [blame] | 523 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 524 | /* Turn on the display and kick animation on power-key press |
| 525 | * rather than on key release |
| 526 | */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 527 | kick_animation(&batt_anim_); |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 528 | RequestDisableSuspend(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 529 | } |
| 530 | } else { |
| 531 | /* if the power key got released, force screen state cycle */ |
| 532 | if (key->pending) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 533 | kick_animation(&batt_anim_); |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 534 | RequestDisableSuspend(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 535 | } |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | key->pending = false; |
| 540 | } |
| 541 | |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 542 | void Charger::ProcessHallSensor(int code) { |
| 543 | key_state* key = &keys_[code]; |
| 544 | |
| 545 | if (code == SW_LID) { |
| 546 | if (key->pending) { |
| 547 | reset_animation(&batt_anim_); |
| 548 | kick_animation(&batt_anim_); |
| 549 | RequestDisableSuspend(); |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | key->pending = false; |
| 554 | } |
| 555 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 556 | void Charger::HandleInputState(int64_t now) { |
| 557 | ProcessKey(KEY_POWER, now); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 558 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 559 | if (next_key_check_ != -1 && now > next_key_check_) next_key_check_ = -1; |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 560 | |
| 561 | ProcessHallSensor(SW_LID); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 562 | } |
| 563 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 564 | void Charger::HandlePowerSupplyState(int64_t now) { |
John Zhao | 5cac100 | 2019-03-31 17:22:47 +0800 | [diff] [blame] | 565 | int timer_shutdown = UNPLUGGED_SHUTDOWN_TIME; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 566 | if (!have_battery_state_) return; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 567 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 568 | if (!configuration_->ChargerIsOnline()) { |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 569 | RequestDisableSuspend(); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 570 | if (next_pwr_check_ == -1) { |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 571 | /* Last cycle would have stopped at the extreme top of battery-icon |
| 572 | * Need to show the correct level corresponding to capacity. |
| 573 | * |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 574 | * Reset next_screen_transition_ to update screen immediately. |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 575 | * Reset & kick animation to show complete animation cycles |
| 576 | * when charger disconnected. |
| 577 | */ |
John Zhao | 5cac100 | 2019-03-31 17:22:47 +0800 | [diff] [blame] | 578 | timer_shutdown = |
| 579 | property_get_int32(UNPLUGGED_SHUTDOWN_TIME_PROP, UNPLUGGED_SHUTDOWN_TIME); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 580 | next_screen_transition_ = now - 1; |
| 581 | reset_animation(&batt_anim_); |
| 582 | kick_animation(&batt_anim_); |
| 583 | next_pwr_check_ = now + timer_shutdown; |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 584 | LOGW("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n", |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 585 | now, (int64_t)timer_shutdown, next_pwr_check_); |
| 586 | } else if (now >= next_pwr_check_) { |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 587 | LOGW("[%" PRId64 "] shutting down\n", now); |
Todd Poynor | c8183bb | 2017-01-31 15:51:50 -0800 | [diff] [blame] | 588 | reboot(RB_POWER_OFF); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 589 | } else { |
| 590 | /* otherwise we already have a shutdown timer scheduled */ |
| 591 | } |
| 592 | } else { |
| 593 | /* online supply present, reset shutdown timer if set */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 594 | if (next_pwr_check_ != -1) { |
| 595 | /* Reset next_screen_transition_ to update screen immediately. |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 596 | * Reset & kick animation to show complete animation cycles |
| 597 | * when charger connected again. |
| 598 | */ |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 599 | RequestDisableSuspend(); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 600 | next_screen_transition_ = now - 1; |
| 601 | reset_animation(&batt_anim_); |
| 602 | kick_animation(&batt_anim_); |
kentsou | ba61ea4 | 2018-07-17 17:49:34 +0800 | [diff] [blame] | 603 | LOGW("[%" PRId64 "] device plugged in: shutdown cancelled\n", now); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 604 | } |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 605 | next_pwr_check_ = -1; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 606 | } |
| 607 | } |
| 608 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 609 | void Charger::OnHeartbeat() { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 610 | // charger* charger = &charger_state; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 611 | int64_t now = curr_time_ms(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 612 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 613 | HandleInputState(now); |
| 614 | HandlePowerSupplyState(now); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 615 | |
| 616 | /* do screen update last in case any of the above want to start |
| 617 | * screen transitions (animations, etc) |
| 618 | */ |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 619 | UpdateScreenState(now); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 620 | } |
| 621 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 622 | void Charger::OnHealthInfoChanged(const ChargerHealthInfo& health_info) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 623 | if (!have_battery_state_) { |
| 624 | have_battery_state_ = true; |
| 625 | next_screen_transition_ = curr_time_ms() - 1; |
Yifan Hong | 8e55134 | 2021-10-26 22:51:29 -0700 | [diff] [blame] | 626 | RequestDisableSuspend(); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 627 | reset_animation(&batt_anim_); |
| 628 | kick_animation(&batt_anim_); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 629 | } |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 630 | health_info_ = health_info; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 631 | } |
| 632 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 633 | int Charger::OnPrepareToWait(void) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 634 | int64_t now = curr_time_ms(); |
| 635 | int64_t next_event = INT64_MAX; |
| 636 | int64_t timeout; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 637 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 638 | LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 639 | now, next_screen_transition_, next_key_check_, next_pwr_check_); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 640 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 641 | if (next_screen_transition_ != -1) next_event = next_screen_transition_; |
| 642 | if (next_key_check_ != -1 && next_key_check_ < next_event) next_event = next_key_check_; |
| 643 | if (next_pwr_check_ != -1 && next_pwr_check_ < next_event) next_event = next_pwr_check_; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 644 | |
| 645 | if (next_event != -1 && next_event != INT64_MAX) |
| 646 | timeout = max(0, next_event - now); |
| 647 | else |
| 648 | timeout = -1; |
| 649 | |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 650 | return (int)timeout; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 651 | } |
| 652 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 653 | int Charger::InputCallback(int fd, unsigned int epevents) { |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 654 | input_event ev; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 655 | int ret; |
| 656 | |
| 657 | ret = ev_get_input(fd, epevents, &ev); |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 658 | if (ret) return -1; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 659 | UpdateInputState(&ev); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 660 | return 0; |
| 661 | } |
| 662 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 663 | static void charger_event_handler(HealthLoop* /*charger_loop*/, uint32_t /*epevents*/) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 664 | int ret; |
| 665 | |
| 666 | ret = ev_wait(-1); |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 667 | if (!ret) ev_dispatch(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 668 | } |
| 669 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 670 | void Charger::InitAnimation() { |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 671 | bool parse_success; |
| 672 | |
| 673 | std::string content; |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 674 | |
| 675 | #if defined(__ANDROID_VNDK__) |
| 676 | if (base::ReadFileToString(vendor_animation_desc_path, &content)) { |
| 677 | parse_success = parse_animation_desc(content, &batt_anim_); |
| 678 | batt_anim_.set_resource_root(vendor_animation_root); |
| 679 | } else { |
| 680 | LOGW("Could not open animation description at %s\n", vendor_animation_desc_path); |
| 681 | parse_success = false; |
| 682 | } |
| 683 | #else |
Yifan Hong | 082d295 | 2019-01-28 12:55:54 -0800 | [diff] [blame] | 684 | if (base::ReadFileToString(product_animation_desc_path, &content)) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 685 | parse_success = parse_animation_desc(content, &batt_anim_); |
| 686 | batt_anim_.set_resource_root(product_animation_root); |
Yifan Hong | 082d295 | 2019-01-28 12:55:54 -0800 | [diff] [blame] | 687 | } else if (base::ReadFileToString(animation_desc_path, &content)) { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 688 | parse_success = parse_animation_desc(content, &batt_anim_); |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 689 | // Fallback resources always exist in system_animation_root. On legacy devices with an old |
| 690 | // ramdisk image, resources may be overridden under root. For example, |
| 691 | // /res/images/charger/battery_fail.png may not be the same as |
| 692 | // system/core/healthd/images/battery_fail.png in the source tree, but is a device-specific |
| 693 | // image. Hence, load from /res, and fall back to /system/etc/res. |
| 694 | batt_anim_.set_resource_root(legacy_animation_root, system_animation_root); |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 695 | } else { |
| 696 | LOGW("Could not open animation description at %s\n", animation_desc_path); |
| 697 | parse_success = false; |
| 698 | } |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 699 | #endif |
| 700 | |
| 701 | #if defined(__ANDROID_VNDK__) |
| 702 | auto default_animation_root = vendor_default_animation_root; |
| 703 | #else |
| 704 | auto default_animation_root = system_animation_root; |
| 705 | #endif |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 706 | |
| 707 | if (!parse_success) { |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 708 | LOGW("Could not parse animation description. " |
| 709 | "Using default animation with resources at %s\n", |
| 710 | default_animation_root); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 711 | batt_anim_ = BASE_ANIMATION; |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 712 | batt_anim_.animation_file.assign(default_animation_root + "charger/battery_scale.png"s); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 713 | InitDefaultAnimationFrames(); |
| 714 | batt_anim_.frames = owned_frames_.data(); |
| 715 | batt_anim_.num_frames = owned_frames_.size(); |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 716 | } |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 717 | if (batt_anim_.fail_file.empty()) { |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 718 | batt_anim_.fail_file.assign(default_animation_root + "charger/battery_fail.png"s); |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 719 | } |
| 720 | |
| 721 | LOGV("Animation Description:\n"); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 722 | LOGV(" animation: %d %d '%s' (%d)\n", batt_anim_.num_cycles, batt_anim_.first_frame_repeats, |
| 723 | batt_anim_.animation_file.c_str(), batt_anim_.num_frames); |
| 724 | LOGV(" fail_file: '%s'\n", batt_anim_.fail_file.c_str()); |
| 725 | LOGV(" clock: %d %d %d %d %d %d '%s'\n", batt_anim_.text_clock.pos_x, |
| 726 | batt_anim_.text_clock.pos_y, batt_anim_.text_clock.color_r, batt_anim_.text_clock.color_g, |
| 727 | batt_anim_.text_clock.color_b, batt_anim_.text_clock.color_a, |
| 728 | batt_anim_.text_clock.font_file.c_str()); |
| 729 | LOGV(" percent: %d %d %d %d %d %d '%s'\n", batt_anim_.text_percent.pos_x, |
| 730 | batt_anim_.text_percent.pos_y, batt_anim_.text_percent.color_r, |
| 731 | batt_anim_.text_percent.color_g, batt_anim_.text_percent.color_b, |
| 732 | batt_anim_.text_percent.color_a, batt_anim_.text_percent.font_file.c_str()); |
| 733 | for (int i = 0; i < batt_anim_.num_frames; i++) { |
| 734 | LOGV(" frame %.2d: %d %d %d\n", i, batt_anim_.frames[i].disp_time, |
| 735 | batt_anim_.frames[i].min_level, batt_anim_.frames[i].max_level); |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 736 | } |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 737 | } |
| 738 | |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 739 | void Charger::OnInit(struct healthd_config* config) { |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 740 | int ret; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 741 | int i; |
| 742 | int epollfd; |
| 743 | |
| 744 | dump_last_kmsg(); |
| 745 | |
Todd Poynor | ebeb0c0 | 2014-09-23 14:54:24 -0700 | [diff] [blame] | 746 | LOGW("--------------- STARTING CHARGER MODE ---------------\n"); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 747 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 748 | ret = ev_init( |
| 749 | std::bind(&Charger::InputCallback, this, std::placeholders::_1, std::placeholders::_2)); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 750 | if (!ret) { |
| 751 | epollfd = ev_get_epollfd(); |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 752 | configuration_->ChargerRegisterEvent(epollfd, &charger_event_handler, EVENT_WAKEUP_FD); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 753 | } |
| 754 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 755 | InitAnimation(); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 756 | |
Greg Kaiser | 8763fd2 | 2020-08-12 07:03:50 -0700 | [diff] [blame] | 757 | ret = CreateDisplaySurface(batt_anim_.fail_file, &surf_unknown_); |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 758 | if (ret < 0) { |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 759 | #if !defined(__ANDROID_VNDK__) |
Thierry Strudel | ac2aa7d | 2018-05-23 15:48:46 -0700 | [diff] [blame] | 760 | LOGE("Cannot load custom battery_fail image. Reverting to built in: %d\n", ret); |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 761 | ret = CreateDisplaySurface((system_animation_root + "charger/battery_fail.png"s).c_str(), |
| 762 | &surf_unknown_); |
Yifan Hong | ac74836 | 2021-10-26 17:20:25 -0700 | [diff] [blame] | 763 | #endif |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 764 | if (ret < 0) { |
| 765 | LOGE("Cannot load built in battery_fail image\n"); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 766 | surf_unknown_ = NULL; |
Damien Bargiacchi | 565ba02 | 2016-08-11 15:29:50 -0700 | [diff] [blame] | 767 | } |
| 768 | } |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 769 | |
Elliott Hughes | 9e85ea1 | 2015-04-15 10:25:55 -0700 | [diff] [blame] | 770 | GRSurface** scale_frames; |
Doug Zongker | ee6ef15 | 2014-03-11 08:42:09 -0700 | [diff] [blame] | 771 | int scale_count; |
Tao Bao | 0db8023 | 2015-12-16 10:57:10 -0800 | [diff] [blame] | 772 | int scale_fps; // Not in use (charger/battery_scale doesn't have FPS text |
| 773 | // chunk). We are using hard-coded frame.disp_time instead. |
Greg Kaiser | 8763fd2 | 2020-08-12 07:03:50 -0700 | [diff] [blame] | 774 | ret = CreateMultiDisplaySurface(batt_anim_.animation_file, &scale_count, &scale_fps, |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 775 | &scale_frames); |
Doug Zongker | ee6ef15 | 2014-03-11 08:42:09 -0700 | [diff] [blame] | 776 | if (ret < 0) { |
| 777 | LOGE("Cannot load battery_scale image\n"); |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 778 | batt_anim_.num_frames = 0; |
| 779 | batt_anim_.num_cycles = 1; |
| 780 | } else if (scale_count != batt_anim_.num_frames) { |
Luke Song | 1d540dd | 2017-07-13 15:10:35 -0700 | [diff] [blame] | 781 | LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", scale_count, |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 782 | batt_anim_.num_frames); |
| 783 | batt_anim_.num_frames = 0; |
| 784 | batt_anim_.num_cycles = 1; |
Doug Zongker | ee6ef15 | 2014-03-11 08:42:09 -0700 | [diff] [blame] | 785 | } else { |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 786 | for (i = 0; i < batt_anim_.num_frames; i++) { |
| 787 | batt_anim_.frames[i].surface = scale_frames[i]; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 788 | } |
| 789 | } |
Jack Wu | c1b1711 | 2021-09-29 22:27:56 +0800 | [diff] [blame] | 790 | drm_ = DRM_INNER; |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 791 | screen_switch_ = SCREEN_SWITCH_DEFAULT; |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 792 | ev_sync_key_state(std::bind(&Charger::SetKeyCallback, this, std::placeholders::_1, |
| 793 | std::placeholders::_2)); |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 794 | |
Jack Wu | 3d637a9 | 2021-09-27 17:40:40 +0800 | [diff] [blame] | 795 | (void)ev_sync_sw_state( |
| 796 | std::bind(&Charger::SetSwCallback, this, std::placeholders::_1, std::placeholders::_2)); |
| 797 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 798 | next_screen_transition_ = -1; |
| 799 | next_key_check_ = -1; |
| 800 | next_pwr_check_ = -1; |
| 801 | wait_batt_level_timestamp_ = 0; |
Yifan Hong | 10c2b40 | 2017-11-08 10:57:52 -0800 | [diff] [blame] | 802 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 803 | // Retrieve healthd_config from the existing health HAL. |
Yifan Hong | b5d7033 | 2021-10-20 17:15:32 -0700 | [diff] [blame] | 804 | configuration_->ChargerInitConfig(config); |
Yifan Hong | 10c2b40 | 2017-11-08 10:57:52 -0800 | [diff] [blame] | 805 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 806 | boot_min_cap_ = config->boot_min_cap; |
Todd Poynor | fea5b4d | 2013-09-09 12:09:08 -0700 | [diff] [blame] | 807 | } |
Tao Bao | 5747e22 | 2018-09-11 10:46:35 -0700 | [diff] [blame] | 808 | |
Yifan Hong | abda715 | 2020-08-05 16:15:15 -0700 | [diff] [blame] | 809 | int Charger::CreateDisplaySurface(const std::string& name, GRSurface** surface) { |
| 810 | return res_create_display_surface(name.c_str(), surface); |
| 811 | } |
| 812 | |
| 813 | int Charger::CreateMultiDisplaySurface(const std::string& name, int* frames, int* fps, |
| 814 | GRSurface*** surface) { |
| 815 | return res_create_multi_display_surface(name.c_str(), frames, fps, surface); |
| 816 | } |
| 817 | |
| 818 | void set_resource_root_for(const std::string& root, const std::string& backup_root, |
| 819 | std::string* value) { |
| 820 | if (value->empty()) { |
| 821 | return; |
| 822 | } |
| 823 | |
| 824 | std::string new_value = root + *value + ".png"; |
| 825 | // If |backup_root| is provided, additionally check whether the file under |root| is |
| 826 | // accessible or not. If not accessible, fallback to file under |backup_root|. |
| 827 | if (!backup_root.empty() && access(new_value.data(), F_OK) == -1) { |
| 828 | new_value = backup_root + *value + ".png"; |
| 829 | } |
| 830 | |
| 831 | *value = new_value; |
| 832 | } |
| 833 | |
| 834 | void animation::set_resource_root(const std::string& root, const std::string& backup_root) { |
| 835 | CHECK(android::base::StartsWith(root, "/") && android::base::EndsWith(root, "/")) |
| 836 | << "animation root " << root << " must start and end with /"; |
| 837 | CHECK(backup_root.empty() || (android::base::StartsWith(backup_root, "/") && |
| 838 | android::base::EndsWith(backup_root, "/"))) |
| 839 | << "animation backup root " << backup_root << " must start and end with /"; |
| 840 | set_resource_root_for(root, backup_root, &animation_file); |
| 841 | set_resource_root_for(root, backup_root, &fail_file); |
| 842 | set_resource_root_for(root, backup_root, &text_clock.font_file); |
| 843 | set_resource_root_for(root, backup_root, &text_percent.font_file); |
| 844 | } |
| 845 | |
Yifan Hong | 7dcf7b0 | 2019-10-08 17:27:11 -0700 | [diff] [blame] | 846 | } // namespace android |