From b31f9ce6d150a264f584d9b38a54da0723fc249c Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 21 May 2018 16:04:57 -0700 Subject: recovery: c++ify pthread use in UI Change pthread usage to std::mutex, lock_guard, unique_lock, thread, or condition_variable as appropriate. Test: Recovery works, recovery_component_test pass Bug: 78793464 Change-Id: Ibf0b1bbedcf0b6e32fc4ee6aaadd17f21b4d7077 --- screen_ui.cpp | 110 ++++++++++++++++++++++++---------------------------------- screen_ui.h | 4 +-- ui.cpp | 89 +++++++++++++++++++---------------------------- ui.h | 7 ++-- wear_ui.cpp | 4 +-- 5 files changed, 87 insertions(+), 127 deletions(-) diff --git a/screen_ui.cpp b/screen_ui.cpp index 0ee0ddcec..b9aba807d 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -171,8 +169,7 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu) stage(-1), max_stage(-1), locale_(""), - rtl_locale_(false), - updateMutex(PTHREAD_MUTEX_INITIALIZER) {} + rtl_locale_(false) {} ScreenRecoveryUI::~ScreenRecoveryUI() { progress_thread_stopped_ = true; @@ -368,7 +365,7 @@ void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector(text_image, &free)); } - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); gr_color(0, 0, 0, 255); gr_clear(); @@ -400,7 +397,6 @@ void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector lg(updateMutex); + + // update the installation animation, if active + // skip this if we have a text overlay (too expensive to update) + if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) { + if (!intro_done) { + if (current_frame == intro_frames - 1) { + intro_done = true; + current_frame = 0; + } else { + ++current_frame; + } } else { - ++current_frame; + current_frame = (current_frame + 1) % loop_frames; } - } else { - current_frame = (current_frame + 1) % loop_frames; - } - - redraw = true; - } - // move the progress bar forward on timed intervals, if configured - int duration = progressScopeDuration; - if (progressBarType == DETERMINATE && duration > 0) { - double elapsed = now() - progressScopeTime; - float p = 1.0 * elapsed / duration; - if (p > 1.0) p = 1.0; - if (p > progress) { - progress = p; redraw = true; } - } - if (redraw) update_progress_locked(); + // move the progress bar forward on timed intervals, if configured + int duration = progressScopeDuration; + if (progressBarType == DETERMINATE && duration > 0) { + double elapsed = now() - progressScopeTime; + float p = 1.0 * elapsed / duration; + if (p > 1.0) p = 1.0; + if (p > progress) { + progress = p; + redraw = true; + } + } + + if (redraw) update_progress_locked(); + } - pthread_mutex_unlock(&updateMutex); double end = now(); // minimum of 20ms delay between frames double delay = interval - (end - start); @@ -799,16 +795,14 @@ void ScreenRecoveryUI::LoadAnimation() { } void ScreenRecoveryUI::SetBackground(Icon icon) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); currentIcon = icon; update_screen_locked(); - - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::SetProgressType(ProgressType type) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (progressBarType != type) { progressBarType = type; } @@ -816,11 +810,10 @@ void ScreenRecoveryUI::SetProgressType(ProgressType type) { progressScopeSize = 0; progress = 0; update_progress_locked(); - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::ShowProgress(float portion, float seconds) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); progressBarType = DETERMINATE; progressScopeStart += progressScopeSize; progressScopeSize = portion; @@ -828,11 +821,10 @@ void ScreenRecoveryUI::ShowProgress(float portion, float seconds) { progressScopeDuration = seconds; progress = 0; update_progress_locked(); - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::SetProgress(float fraction) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (fraction < 0.0) fraction = 0.0; if (fraction > 1.0) fraction = 1.0; if (progressBarType == DETERMINATE && fraction > progress) { @@ -844,14 +836,12 @@ void ScreenRecoveryUI::SetProgress(float fraction) { update_progress_locked(); } } - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::SetStage(int current, int max) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); stage = current; max_stage = max; - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) { @@ -862,7 +852,7 @@ void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) fputs(str.c_str(), stdout); } - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (text_rows_ > 0 && text_cols_ > 0) { for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) { if (*ptr == '\n' || text_col_ >= text_cols_) { @@ -875,7 +865,6 @@ void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) text_[text_row_][text_col_] = '\0'; update_screen_locked(); } - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::Print(const char* fmt, ...) { @@ -893,23 +882,21 @@ void ScreenRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) { } void ScreenRecoveryUI::PutChar(char ch) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (ch != '\n') text_[text_row_][text_col_++] = ch; if (ch == '\n' || text_col_ >= text_cols_) { text_col_ = 0; ++text_row_; } - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::ClearText() { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); text_col_ = 0; text_row_ = 0; for (size_t i = 0; i < text_rows_; ++i) { memset(text_[i], 0, text_cols_ + 1); } - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::ShowFile(FILE* fp) { @@ -986,17 +973,16 @@ void ScreenRecoveryUI::ShowFile(const std::string& filename) { void ScreenRecoveryUI::StartMenu(const std::vector& headers, const std::vector& items, size_t initial_selection) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (text_rows_ > 0 && text_cols_ > 1) { menu_ = std::make_unique(scrollable_menu_, text_rows_, text_cols_ - 1, headers, items, initial_selection); update_screen_locked(); } - pthread_mutex_unlock(&updateMutex); } int ScreenRecoveryUI::SelectMenu(int sel) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (menu_) { int old_sel = menu_->selection(); sel = menu_->Select(sel); @@ -1005,17 +991,15 @@ int ScreenRecoveryUI::SelectMenu(int sel) { update_screen_locked(); } } - pthread_mutex_unlock(&updateMutex); return sel; } void ScreenRecoveryUI::EndMenu() { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (menu_) { menu_.reset(); update_screen_locked(); } - pthread_mutex_unlock(&updateMutex); } size_t ScreenRecoveryUI::ShowMenu(const std::vector& headers, @@ -1067,31 +1051,27 @@ size_t ScreenRecoveryUI::ShowMenu(const std::vector& headers, } bool ScreenRecoveryUI::IsTextVisible() { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); int visible = show_text; - pthread_mutex_unlock(&updateMutex); return visible; } bool ScreenRecoveryUI::WasTextEverVisible() { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); int ever_visible = show_text_ever; - pthread_mutex_unlock(&updateMutex); return ever_visible; } void ScreenRecoveryUI::ShowText(bool visible) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); show_text = visible; if (show_text) show_text_ever = true; update_screen_locked(); - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::Redraw() { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); update_screen_locked(); - pthread_mutex_unlock(&updateMutex); } void ScreenRecoveryUI::KeyLongPress(int) { diff --git a/screen_ui.h b/screen_ui.h index c3605161a..b76d4706e 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -17,7 +17,6 @@ #ifndef RECOVERY_SCREEN_UI_H #define RECOVERY_SCREEN_UI_H -#include #include #include @@ -192,7 +191,6 @@ class ScreenRecoveryUI : public RecoveryUI { GRSurface* GetCurrentFrame() const; GRSurface* GetCurrentText() const; - static void* ProgressThreadStartRoutine(void* data); void ProgressThreadLoop(); virtual void ShowFile(FILE*); @@ -297,7 +295,7 @@ class ScreenRecoveryUI : public RecoveryUI { std::string locale_; bool rtl_locale_; - pthread_mutex_t updateMutex; + std::mutex updateMutex; private: void SetLocale(const std::string&); diff --git a/ui.cpp b/ui.cpp index dbe77ae8c..51d7f129c 100644 --- a/ui.cpp +++ b/ui.cpp @@ -18,8 +18,6 @@ #include #include -#include -#include #include #include #include @@ -74,8 +72,6 @@ RecoveryUI::RecoveryUI() touch_slot_(0), is_bootreason_recovery_ui_(false), screensaver_state_(ScreensaverState::DISABLED) { - pthread_mutex_init(&key_queue_mutex, nullptr); - pthread_cond_init(&key_queue_cond, nullptr); memset(key_pressed, 0, sizeof(key_pressed)); } @@ -341,25 +337,25 @@ void RecoveryUI::ProcessKey(int key_code, int updown) { bool register_key = false; bool long_press = false; - pthread_mutex_lock(&key_queue_mutex); - key_pressed[key_code] = updown; - if (updown) { - ++key_down_count; - key_last_down = key_code; - key_long_press = false; - - std::thread time_key_thread(&RecoveryUI::TimeKey, this, key_code, key_down_count); - time_key_thread.detach(); - } else { - if (key_last_down == key_code) { - long_press = key_long_press; - register_key = true; + { + std::lock_guard lg(key_queue_mutex); + key_pressed[key_code] = updown; + if (updown) { + ++key_down_count; + key_last_down = key_code; + key_long_press = false; + std::thread time_key_thread(&RecoveryUI::TimeKey, this, key_code, key_down_count); + time_key_thread.detach(); + } else { + if (key_last_down == key_code) { + long_press = key_long_press; + register_key = true; + } + key_last_down = -1; } - key_last_down = -1; } - bool reboot_enabled = enable_reboot; - pthread_mutex_unlock(&key_queue_mutex); + bool reboot_enabled = enable_reboot; if (register_key) { switch (CheckKey(key_code, long_press)) { case RecoveryUI::IGNORE: @@ -388,44 +384,37 @@ void RecoveryUI::ProcessKey(int key_code, int updown) { void RecoveryUI::TimeKey(int key_code, int count) { std::this_thread::sleep_for(750ms); // 750 ms == "long" bool long_press = false; - pthread_mutex_lock(&key_queue_mutex); - if (key_last_down == key_code && key_down_count == count) { - long_press = key_long_press = true; + { + std::lock_guard lg(key_queue_mutex); + if (key_last_down == key_code && key_down_count == count) { + long_press = key_long_press = true; + } } - pthread_mutex_unlock(&key_queue_mutex); if (long_press) KeyLongPress(key_code); } void RecoveryUI::EnqueueKey(int key_code) { - pthread_mutex_lock(&key_queue_mutex); + std::lock_guard lg(key_queue_mutex); const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (key_queue_len < queue_max) { key_queue[key_queue_len++] = key_code; - pthread_cond_signal(&key_queue_cond); + key_queue_cond.notify_one(); } - pthread_mutex_unlock(&key_queue_mutex); } int RecoveryUI::WaitKey() { - pthread_mutex_lock(&key_queue_mutex); + std::unique_lock lk(key_queue_mutex); // Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is // plugged in. do { - struct timeval now; - struct timespec timeout; - gettimeofday(&now, nullptr); - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = now.tv_usec * 1000; - timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC; - - int rc = 0; - while (key_queue_len == 0 && rc != ETIMEDOUT) { - rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex, &timeout); + std::cv_status rc = std::cv_status::no_timeout; + while (key_queue_len == 0 && rc != std::cv_status::timeout) { + rc = key_queue_cond.wait_for(lk, std::chrono::seconds(UI_WAIT_KEY_TIMEOUT_SEC)); } if (screensaver_state_ != ScreensaverState::DISABLED) { - if (rc == ETIMEDOUT) { + if (rc == std::cv_status::timeout) { // Lower the brightness level: NORMAL -> DIMMED; DIMMED -> OFF. if (screensaver_state_ == ScreensaverState::NORMAL) { if (android::base::WriteStringToFile(std::to_string(brightness_dimmed_value_), @@ -464,7 +453,6 @@ int RecoveryUI::WaitKey() { key = key_queue[0]; memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len); } - pthread_mutex_unlock(&key_queue_mutex); return key; } @@ -485,16 +473,14 @@ bool RecoveryUI::IsUsbConnected() { } bool RecoveryUI::IsKeyPressed(int key) { - pthread_mutex_lock(&key_queue_mutex); + std::lock_guard lg(key_queue_mutex); int pressed = key_pressed[key]; - pthread_mutex_unlock(&key_queue_mutex); return pressed; } bool RecoveryUI::IsLongPress() { - pthread_mutex_lock(&key_queue_mutex); + std::lock_guard lg(key_queue_mutex); bool result = key_long_press; - pthread_mutex_unlock(&key_queue_mutex); return result; } @@ -511,15 +497,15 @@ bool RecoveryUI::HasTouchScreen() const { } void RecoveryUI::FlushKeys() { - pthread_mutex_lock(&key_queue_mutex); + std::lock_guard lg(key_queue_mutex); key_queue_len = 0; - pthread_mutex_unlock(&key_queue_mutex); } RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) { - pthread_mutex_lock(&key_queue_mutex); - key_long_press = false; - pthread_mutex_unlock(&key_queue_mutex); + { + std::lock_guard lg(key_queue_mutex); + key_long_press = false; + } // If we have power and volume up keys, that chord is the signal to toggle the text display. if (HasThreeButtons() || (HasPowerKey() && HasTouchScreen() && touch_screen_allowed_)) { @@ -542,9 +528,7 @@ RecoveryUI::KeyAction RecoveryUI::CheckKey(int key, bool is_long_press) { // Press power seven times in a row to reboot. if (key == KEY_POWER) { - pthread_mutex_lock(&key_queue_mutex); bool reboot_enabled = enable_reboot; - pthread_mutex_unlock(&key_queue_mutex); if (reboot_enabled) { ++consecutive_power_keys; @@ -564,7 +548,6 @@ void RecoveryUI::KeyLongPress(int) { } void RecoveryUI::SetEnableReboot(bool enabled) { - pthread_mutex_lock(&key_queue_mutex); + std::lock_guard lg(key_queue_mutex); enable_reboot = enabled; - pthread_mutex_unlock(&key_queue_mutex); } diff --git a/ui.h b/ui.h index 75390d83c..32e28099e 100644 --- a/ui.h +++ b/ui.h @@ -18,10 +18,11 @@ #define RECOVERY_UI_H #include // KEY_MAX -#include #include +#include #include +#include #include #include #include @@ -188,8 +189,8 @@ class RecoveryUI { bool InitScreensaver(); // Key event input queue - pthread_mutex_t key_queue_mutex; - pthread_cond_t key_queue_cond; + std::mutex key_queue_mutex; + std::condition_variable key_queue_cond; int key_queue[256], key_queue_len; char key_pressed[KEY_MAX + 1]; // under key_queue_mutex int key_last_down; // under key_queue_mutex diff --git a/wear_ui.cpp b/wear_ui.cpp index f4a839923..65c4aeed6 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -16,7 +16,6 @@ #include "wear_ui.h" -#include #include #include @@ -86,11 +85,10 @@ void WearRecoveryUI::SetStage(int /* current */, int /* max */) {} void WearRecoveryUI::StartMenu(const std::vector& headers, const std::vector& items, size_t initial_selection) { - pthread_mutex_lock(&updateMutex); + std::lock_guard lg(updateMutex); if (text_rows_ > 0 && text_cols_ > 0) { menu_ = std::make_unique(scrollable_menu_, text_rows_ - kMenuUnusableRows - 1, text_cols_ - 1, headers, items, initial_selection); update_screen_locked(); } - pthread_mutex_unlock(&updateMutex); } -- cgit v1.2.3