diff options
author | Tao Bao | 2016-10-13 17:17:04 -0500 |
---|---|---|
committer | Tao Bao | 2016-10-26 16:36:42 -0500 |
commit | c0319b60f56d445c2d1c74f551e01f069b028fe6 (patch) | |
tree | 2df23be127c0e92bf1e1be19dada2dd2e4182479 /recovery.cpp | |
parent | ebc141dff27c53d7043bf7fc61cd435ac4d13160 (diff) | |
download | platform-bootable-recovery-c0319b60f56d445c2d1c74f551e01f069b028fe6.tar.gz platform-bootable-recovery-c0319b60f56d445c2d1c74f551e01f069b028fe6.tar.xz platform-bootable-recovery-c0319b60f56d445c2d1c74f551e01f069b028fe6.zip |
Some cleanups to recovery.
- Remove the duplicate gCurrentUI variable in recovery.cpp;
- Refactor the load/save of locale functions;
- Clean up ui_print() to get rid of 256-byte buffer limit;
- Declare ui in common.h;
- Move the typedef of Volume into roots.h.
Test: Build and boot into recovery image.
Change-Id: Ia28c116858ca754133127a5ff9c722af67ad55b7
Diffstat (limited to 'recovery.cpp')
-rw-r--r-- | recovery.cpp | 110 |
1 files changed, 53 insertions, 57 deletions
diff --git a/recovery.cpp b/recovery.cpp index 4d1ad1df..4079927e 100644 --- a/recovery.cpp +++ b/recovery.cpp | |||
@@ -69,8 +69,6 @@ | |||
69 | #include "ui.h" | 69 | #include "ui.h" |
70 | #include "screen_ui.h" | 70 | #include "screen_ui.h" |
71 | 71 | ||
72 | struct selabel_handle *sehandle; | ||
73 | |||
74 | static const struct option OPTIONS[] = { | 72 | static const struct option OPTIONS[] = { |
75 | { "update_package", required_argument, NULL, 'u' }, | 73 | { "update_package", required_argument, NULL, 'u' }, |
76 | { "retry_count", required_argument, NULL, 'n' }, | 74 | { "retry_count", required_argument, NULL, 'n' }, |
@@ -119,15 +117,18 @@ static const int BATTERY_READ_TIMEOUT_IN_SEC = 10; | |||
119 | // So we should check battery with a slightly lower limitation. | 117 | // So we should check battery with a slightly lower limitation. |
120 | static const int BATTERY_OK_PERCENTAGE = 20; | 118 | static const int BATTERY_OK_PERCENTAGE = 20; |
121 | static const int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15; | 119 | static const int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15; |
122 | constexpr const char* RECOVERY_WIPE = "/etc/recovery.wipe"; | 120 | static constexpr const char* RECOVERY_WIPE = "/etc/recovery.wipe"; |
121 | static constexpr const char* DEFAULT_LOCALE = "en_US"; | ||
123 | 122 | ||
124 | RecoveryUI* ui = NULL; | 123 | static std::string locale; |
125 | static const char* locale = "en_US"; | 124 | static const char* stage = nullptr; |
126 | char* stage = NULL; | 125 | static const char* reason = nullptr; |
127 | char* reason = NULL; | ||
128 | bool modified_flash = false; | ||
129 | static bool has_cache = false; | 126 | static bool has_cache = false; |
130 | 127 | ||
128 | RecoveryUI* ui = nullptr; | ||
129 | bool modified_flash = false; | ||
130 | struct selabel_handle* sehandle; | ||
131 | |||
131 | /* | 132 | /* |
132 | * The recovery tool communicates with the main system through /cache files. | 133 | * The recovery tool communicates with the main system through /cache files. |
133 | * /cache/recovery/command - INPUT - command line for tool, one arg per line | 134 | * /cache/recovery/command - INPUT - command line for tool, one arg per line |
@@ -206,6 +207,9 @@ FILE* fopen_path(const char *path, const char *mode) { | |||
206 | // close a file, log an error if the error indicator is set | 207 | // close a file, log an error if the error indicator is set |
207 | static void check_and_fclose(FILE *fp, const char *name) { | 208 | static void check_and_fclose(FILE *fp, const char *name) { |
208 | fflush(fp); | 209 | fflush(fp); |
210 | if (fsync(fileno(fp)) == -1) { | ||
211 | PLOG(ERROR) << "Failed to fsync " << name; | ||
212 | } | ||
209 | if (ferror(fp)) { | 213 | if (ferror(fp)) { |
210 | PLOG(ERROR) << "Error in " << name; | 214 | PLOG(ERROR) << "Error in " << name; |
211 | } | 215 | } |
@@ -515,24 +519,18 @@ static void copy_logs() { | |||
515 | // clear the recovery command and prepare to boot a (hopefully working) system, | 519 | // clear the recovery command and prepare to boot a (hopefully working) system, |
516 | // copy our log file to cache as well (for the system to read). This function is | 520 | // copy our log file to cache as well (for the system to read). This function is |
517 | // idempotent: call it as many times as you like. | 521 | // idempotent: call it as many times as you like. |
518 | static void | 522 | static void finish_recovery() { |
519 | finish_recovery() { | ||
520 | // Save the locale to cache, so if recovery is next started up | 523 | // Save the locale to cache, so if recovery is next started up |
521 | // without a --locale argument (eg, directly from the bootloader) | 524 | // without a --locale argument (eg, directly from the bootloader) |
522 | // it will use the last-known locale. | 525 | // it will use the last-known locale. |
523 | if (locale != NULL) { | 526 | if (!locale.empty() && has_cache) { |
524 | size_t len = strlen(locale); | 527 | LOG(INFO) << "Saving locale \"" << locale << "\""; |
525 | __pmsg_write(LOCALE_FILE, locale, len); | 528 | |
526 | if (has_cache) { | 529 | FILE* fp = fopen_path(LOCALE_FILE, "w"); |
527 | LOG(INFO) << "Saving locale \"" << locale << "\""; | 530 | if (!android::base::WriteStringToFd(locale, fileno(fp))) { |
528 | FILE* fp = fopen_path(LOCALE_FILE, "w"); | 531 | PLOG(ERROR) << "Failed to save locale to " << LOCALE_FILE; |
529 | if (fp != NULL) { | ||
530 | fwrite(locale, 1, len, fp); | ||
531 | fflush(fp); | ||
532 | fsync(fileno(fp)); | ||
533 | check_and_fclose(fp, LOCALE_FILE); | ||
534 | } | ||
535 | } | 532 | } |
533 | check_and_fclose(fp, LOCALE_FILE); | ||
536 | } | 534 | } |
537 | 535 | ||
538 | copy_logs(); | 536 | copy_logs(); |
@@ -1282,40 +1280,32 @@ print_property(const char *key, const char *name, void *cookie) { | |||
1282 | printf("%s=%s\n", key, name); | 1280 | printf("%s=%s\n", key, name); |
1283 | } | 1281 | } |
1284 | 1282 | ||
1285 | static void | 1283 | static std::string load_locale_from_cache() { |
1286 | load_locale_from_cache() { | 1284 | if (ensure_path_mounted(LOCALE_FILE) != 0) { |
1287 | FILE* fp = fopen_path(LOCALE_FILE, "r"); | 1285 | LOG(ERROR) << "Can't mount " << LOCALE_FILE; |
1288 | char buffer[80]; | 1286 | return ""; |
1289 | if (fp != NULL) { | ||
1290 | fgets(buffer, sizeof(buffer), fp); | ||
1291 | int j = 0; | ||
1292 | unsigned int i; | ||
1293 | for (i = 0; i < sizeof(buffer) && buffer[i]; ++i) { | ||
1294 | if (!isspace(buffer[i])) { | ||
1295 | buffer[j++] = buffer[i]; | ||
1296 | } | ||
1297 | } | ||
1298 | buffer[j] = 0; | ||
1299 | locale = strdup(buffer); | ||
1300 | check_and_fclose(fp, LOCALE_FILE); | ||
1301 | } | 1287 | } |
1302 | } | ||
1303 | 1288 | ||
1304 | static RecoveryUI* gCurrentUI = NULL; | 1289 | std::string content; |
1290 | if (!android::base::ReadFileToString(LOCALE_FILE, &content)) { | ||
1291 | PLOG(ERROR) << "Can't read " << LOCALE_FILE; | ||
1292 | return ""; | ||
1293 | } | ||
1305 | 1294 | ||
1306 | void | 1295 | return android::base::Trim(content); |
1307 | ui_print(const char* format, ...) { | 1296 | } |
1308 | char buffer[256]; | ||
1309 | 1297 | ||
1298 | void ui_print(const char* format, ...) { | ||
1299 | std::string buffer; | ||
1310 | va_list ap; | 1300 | va_list ap; |
1311 | va_start(ap, format); | 1301 | va_start(ap, format); |
1312 | vsnprintf(buffer, sizeof(buffer), format, ap); | 1302 | android::base::StringAppendV(&buffer, format, ap); |
1313 | va_end(ap); | 1303 | va_end(ap); |
1314 | 1304 | ||
1315 | if (gCurrentUI != NULL) { | 1305 | if (ui != nullptr) { |
1316 | gCurrentUI->Print("%s", buffer); | 1306 | ui->Print("%s", buffer.c_str()); |
1317 | } else { | 1307 | } else { |
1318 | fputs(buffer, stdout); | 1308 | fputs(buffer.c_str(), stdout); |
1319 | } | 1309 | } |
1320 | } | 1310 | } |
1321 | 1311 | ||
@@ -1324,8 +1314,8 @@ static constexpr char log_characters[] = "VDIWEF"; | |||
1324 | void UiLogger(android::base::LogId id, android::base::LogSeverity severity, | 1314 | void UiLogger(android::base::LogId id, android::base::LogSeverity severity, |
1325 | const char* tag, const char* file, unsigned int line, | 1315 | const char* tag, const char* file, unsigned int line, |
1326 | const char* message) { | 1316 | const char* message) { |
1327 | if (severity >= android::base::ERROR && gCurrentUI != NULL) { | 1317 | if (severity >= android::base::ERROR && ui != nullptr) { |
1328 | gCurrentUI->Print("E:%s\n", message); | 1318 | ui->Print("E:%s\n", message); |
1329 | } else { | 1319 | } else { |
1330 | fprintf(stdout, "%c:%s\n", log_characters[severity], message); | 1320 | fprintf(stdout, "%c:%s\n", log_characters[severity], message); |
1331 | } | 1321 | } |
@@ -1421,7 +1411,7 @@ static void log_failure_code(ErrorCode code, const char *update_package) { | |||
1421 | }; | 1411 | }; |
1422 | std::string log_content = android::base::Join(log_buffer, "\n"); | 1412 | std::string log_content = android::base::Join(log_buffer, "\n"); |
1423 | if (!android::base::WriteStringToFile(log_content, TEMPORARY_INSTALL_FILE)) { | 1413 | if (!android::base::WriteStringToFile(log_content, TEMPORARY_INSTALL_FILE)) { |
1424 | PLOG(ERROR) << "failed to write " << TEMPORARY_INSTALL_FILE; | 1414 | PLOG(ERROR) << "failed to write " << TEMPORARY_INSTALL_FILE; |
1425 | } | 1415 | } |
1426 | 1416 | ||
1427 | // Also write the info into last_log. | 1417 | // Also write the info into last_log. |
@@ -1573,18 +1563,24 @@ int main(int argc, char **argv) { | |||
1573 | } | 1563 | } |
1574 | } | 1564 | } |
1575 | 1565 | ||
1576 | if (locale == nullptr && has_cache) { | 1566 | if (locale.empty()) { |
1577 | load_locale_from_cache(); | 1567 | if (has_cache) { |
1568 | locale = load_locale_from_cache(); | ||
1569 | } | ||
1570 | |||
1571 | if (locale.empty()) { | ||
1572 | locale = DEFAULT_LOCALE; | ||
1573 | } | ||
1578 | } | 1574 | } |
1579 | printf("locale is [%s]\n", locale); | 1575 | |
1576 | printf("locale is [%s]\n", locale.c_str()); | ||
1580 | printf("stage is [%s]\n", stage); | 1577 | printf("stage is [%s]\n", stage); |
1581 | printf("reason is [%s]\n", reason); | 1578 | printf("reason is [%s]\n", reason); |
1582 | 1579 | ||
1583 | Device* device = make_device(); | 1580 | Device* device = make_device(); |
1584 | ui = device->GetUI(); | 1581 | ui = device->GetUI(); |
1585 | gCurrentUI = ui; | ||
1586 | 1582 | ||
1587 | ui->SetLocale(locale); | 1583 | ui->SetLocale(locale.c_str()); |
1588 | ui->Init(); | 1584 | ui->Init(); |
1589 | // Set background string to "installing security update" for security update, | 1585 | // Set background string to "installing security update" for security update, |
1590 | // otherwise set it to "installing system update". | 1586 | // otherwise set it to "installing system update". |
@@ -1599,7 +1595,7 @@ int main(int argc, char **argv) { | |||
1599 | if (show_text) ui->ShowText(true); | 1595 | if (show_text) ui->ShowText(true); |
1600 | 1596 | ||
1601 | struct selinux_opt seopts[] = { | 1597 | struct selinux_opt seopts[] = { |
1602 | { SELABEL_OPT_PATH, "/file_contexts" } | 1598 | { SELABEL_OPT_PATH, "/file_contexts" } |
1603 | }; | 1599 | }; |
1604 | 1600 | ||
1605 | sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); | 1601 | sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); |
@@ -1771,7 +1767,7 @@ int main(int argc, char **argv) { | |||
1771 | break; | 1767 | break; |
1772 | } | 1768 | } |
1773 | while (true) { | 1769 | while (true) { |
1774 | pause(); | 1770 | pause(); |
1775 | } | 1771 | } |
1776 | // Should be unreachable. | 1772 | // Should be unreachable. |
1777 | return EXIT_SUCCESS; | 1773 | return EXIT_SUCCESS; |