You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
806 lines
33 KiB
806 lines
33 KiB
// License: Apache 2.0. See LICENSE file in root directory.
|
|
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.
|
|
|
|
#include <glad/glad.h>
|
|
#include "updates-model.h"
|
|
#include "device-model.h"
|
|
#include "ux-window.h"
|
|
#include "os.h"
|
|
#include <stb_image.h>
|
|
#include "sw-update/http-downloader.h"
|
|
#include <rsutils/easylogging/easyloggingpp.h>
|
|
|
|
using namespace rs2;
|
|
using namespace sw_update;
|
|
using namespace http;
|
|
|
|
void updates_model::draw(std::shared_ptr<notifications_model> not_model, ux_window& window, std::string& error_message)
|
|
{
|
|
// Protect resources
|
|
static std::vector<update_profile_model> updates_copy;
|
|
{
|
|
std::lock_guard<std::mutex> lock(_lock);
|
|
updates_copy = _updates;
|
|
}
|
|
|
|
const auto window_name = "Updates Window";
|
|
|
|
//Main window pop up only if essential updates exists
|
|
if (updates_copy.size())
|
|
{
|
|
ImGui::OpenPopup(window_name);
|
|
}
|
|
|
|
position_params positions;
|
|
|
|
positions.w = window.width() * 0.6f;
|
|
positions.h = 600;
|
|
positions.x0 = window.width() * 0.2f;
|
|
positions.y0 = std::max(window.height() - positions.h, 0.f) / 2;
|
|
ImGui::SetNextWindowPos({ positions.x0, positions.y0 });
|
|
ImGui::SetNextWindowSize({ positions.w, positions.h });
|
|
|
|
auto flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar |
|
|
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ShowBorders;
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_PopupBg, sensor_bg);
|
|
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_grey);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5, 5));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 1);
|
|
|
|
if (ImGui::BeginPopupModal(window_name, nullptr, flags))
|
|
{
|
|
|
|
std::string title_message = "SOFTWARE UPDATES";
|
|
auto title_size = ImGui::CalcTextSize(title_message.c_str());
|
|
ImGui::SetCursorPosX(positions.w / 2 - title_size.x / 2);
|
|
ImGui::PushFont(window.get_large_font());
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", title_message.c_str());
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopFont();
|
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5);
|
|
|
|
positions.orig_pos = ImGui::GetCursorScreenPos();
|
|
positions.mid_y = (positions.orig_pos.y + positions.y0 + positions.h - 30) / 2;
|
|
|
|
ImGui::GetWindowDrawList()->AddRectFilled({ positions.orig_pos.x, positions.orig_pos.y },
|
|
{ positions.x0 + positions.w - 5, positions.y0 + positions.h - 30 }, ImColor(header_color));
|
|
ImGui::GetWindowDrawList()->AddLine({ positions.orig_pos.x, positions.mid_y },
|
|
{ positions.x0 + positions.w - 10, positions.mid_y }, ImColor(sensor_bg));
|
|
|
|
auto& update = updates_copy[selected_index];
|
|
|
|
bool sw_update_needed(false), fw_update_needed(false);
|
|
|
|
bool fw_update_in_process = _fw_update_state == fw_update_states::started
|
|
|| _fw_update_state == fw_update_states::failed_updating
|
|
|| _fw_update_state == fw_update_states::failed_downloading;
|
|
|
|
// Verify Device Exists or a FW update process
|
|
if (update.profile.dev_active || fw_update_in_process)
|
|
{
|
|
// ===========================================================================
|
|
// Draw Software update Pane
|
|
// ===========================================================================
|
|
sw_update_needed = draw_software_section(window_name, update, positions, window, error_message);
|
|
|
|
// ===========================================================================
|
|
// Draw Firmware update Pane
|
|
// ===========================================================================
|
|
fw_update_needed = draw_firmware_section(not_model, window_name, update, positions, window, error_message);
|
|
}
|
|
else
|
|
{ // Indicate device disconnected to the user
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::SetWindowFontScale(1.5);
|
|
std::string disconnected_text = "THE DEVICE HAS BEEN DISCONNECTED,";
|
|
auto disconnected_text_size = ImGui::CalcTextSize(disconnected_text.c_str());
|
|
auto disconnected_text_x_pixel = positions.w / 2 - disconnected_text_size.x / 2; // Align 2 center
|
|
auto vertical_padding = 100.f;
|
|
ImGui::SetCursorPos({ disconnected_text_x_pixel, vertical_padding });
|
|
ImGui::Text("%s", disconnected_text.c_str());
|
|
|
|
std::string reconnect_text = "PLEASE RECONNECT IT OR CLOSE THE UPDATES WINDOW.";
|
|
auto reconnect_text_size = ImGui::CalcTextSize(reconnect_text.c_str());
|
|
auto reconnect_text_x_pixel = positions.w / 2 - reconnect_text_size.x / 2; // Align 2 center
|
|
ImGui::SetCursorPosX(reconnect_text_x_pixel);
|
|
ImGui::Text("%s", reconnect_text.c_str());
|
|
|
|
ImGui::SetWindowFontScale(3.);
|
|
|
|
auto disconnect_icon_size = ImGui::CalcTextSize(textual_icons::lock);
|
|
auto disconnect_icon_x_pixel = (positions.w / 2.f) - (disconnect_icon_size.x / 2); // Align 2 center
|
|
ImGui::SetCursorPosX( disconnect_icon_x_pixel );
|
|
ImGui::Text("%s", static_cast<const char *>(textual_icons::lock));
|
|
ImGui::SetWindowFontScale(1.);
|
|
ImGui::PopStyleColor();
|
|
|
|
|
|
}
|
|
// ===========================================================================
|
|
// Draw Lower Pane
|
|
// ===========================================================================
|
|
|
|
auto no_update_needed = (!sw_update_needed && !fw_update_needed);
|
|
|
|
if (!no_update_needed)
|
|
{
|
|
ImGui::SetCursorPos({ 5, positions.h - 25 });
|
|
if (emphasize_dismiss_text)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_red);
|
|
}
|
|
|
|
ImGui::Checkbox("I understand and would like to proceed anyway without updating", &ignore);
|
|
|
|
if (emphasize_dismiss_text)
|
|
{
|
|
ImGui::PopStyleColor();
|
|
}
|
|
}
|
|
|
|
ImGui::SetCursorPos({ positions.w - 145, positions.h - 25 });
|
|
|
|
auto enabled = ignore || no_update_needed;
|
|
if (enabled)
|
|
{
|
|
if (_fw_update_state != fw_update_states::started)
|
|
{
|
|
if (ImGui::Button("Close", { 120, 20 }))
|
|
{
|
|
{
|
|
std::lock_guard<std::mutex> lock(_lock);
|
|
_updates.clear();
|
|
}
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
emphasize_dismiss_text = false;
|
|
ignore = false;
|
|
_fw_update_state = fw_update_states::ready;
|
|
_fw_download_progress = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg);
|
|
ImGui::Button("Close", { 120, 20 });
|
|
ImGui::PopStyleColor();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg);
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, sensor_bg);
|
|
|
|
if (ImGui::Button("Close", { 120, 20 }))
|
|
{
|
|
emphasize_dismiss_text = true;
|
|
}
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::SetTooltip("To close this window you must install all essential update\n"
|
|
"or agree to the warning of closing without it");
|
|
|
|
}
|
|
ImGui::PopStyleColor(2);
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
ImGui::PopStyleColor(3);
|
|
ImGui::PopStyleVar(2);
|
|
|
|
}
|
|
|
|
bool updates_model::draw_software_section(const char * window_name, update_profile_model& selected_profile, position_params& pos, ux_window& window, std::string& error_message)
|
|
{
|
|
bool essential_sw_update_needed(false);
|
|
bool recommended_sw_update_needed(false);
|
|
{
|
|
// Prepare sorted array of SW updates profiles
|
|
// Assumption - essential updates version <= other policies versions
|
|
std::vector<dev_updates_profile::version_info> software_updates;
|
|
for (auto&& swu : selected_profile.profile.software_versions)
|
|
software_updates.push_back(swu.second);
|
|
std::sort(software_updates.begin(), software_updates.end(), [](dev_updates_profile::version_info& a, dev_updates_profile::version_info& b) {
|
|
return a.ver < b.ver;
|
|
});
|
|
if (static_cast<int>(software_updates.size()) <= selected_software_update_index) selected_software_update_index = 0;
|
|
|
|
dev_updates_profile::version_info selected_software_update;
|
|
if (software_updates.size() != 0)
|
|
{
|
|
bool essential_found(false);
|
|
bool recommended_found(false);
|
|
for (auto sw_update : software_updates)
|
|
{
|
|
if (!essential_found)
|
|
{
|
|
essential_found = essential_found || sw_update.name_for_display.find("ESSENTIAL") != std::string::npos;
|
|
essential_sw_update_needed = essential_sw_update_needed || essential_found && (selected_profile.profile.software_version < sw_update.ver);
|
|
}
|
|
|
|
if (!recommended_found)
|
|
{
|
|
recommended_found = recommended_found || sw_update.name_for_display.find("RECOMMENDED") != std::string::npos;
|
|
recommended_sw_update_needed = recommended_sw_update_needed || recommended_found && (selected_profile.profile.software_version < sw_update.ver);
|
|
}
|
|
}
|
|
|
|
// If essential update found on DB but not needed - Remove it
|
|
if (essential_found && !essential_sw_update_needed)
|
|
{
|
|
auto it = std::find_if(software_updates.begin(), software_updates.end(), [&](dev_updates_profile::version_info& u) {
|
|
return (u.name_for_display.find("ESSENTIAL") != std::string::npos);
|
|
});
|
|
if (it != software_updates.end())
|
|
software_updates.erase(it);
|
|
}
|
|
|
|
// If recommended update found on DB but not needed - Remove it
|
|
if (recommended_found && !recommended_sw_update_needed)
|
|
{
|
|
auto it = std::find_if(software_updates.begin(), software_updates.end(), [&](dev_updates_profile::version_info& u) {
|
|
return (u.name_for_display.find("RECOMMENDED") != std::string::npos);
|
|
});
|
|
if (it != software_updates.end())
|
|
software_updates.erase(it);
|
|
}
|
|
|
|
if (essential_sw_update_needed || recommended_sw_update_needed)
|
|
{
|
|
selected_software_update = software_updates[selected_software_update_index];
|
|
}
|
|
}
|
|
|
|
ImVec2 sw_text_pos(pos.orig_pos.x + 10, pos.orig_pos.y + 10);
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
|
|
ImGui::PushFont(window.get_large_font());
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("LibRealSense SDK: ");
|
|
ImGui::PopStyleColor();
|
|
ImGui::SameLine();
|
|
|
|
if (!essential_sw_update_needed || software_updates.size() == 0)
|
|
{
|
|
if (recommended_sw_update_needed)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("Recommended update available!");
|
|
}
|
|
else
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_blue);
|
|
ImGui::Text("%s", static_cast<const char *>(textual_icons::check_square_o));
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", "Up to date.");
|
|
}
|
|
ImGui::PopStyleColor();
|
|
}
|
|
else if (essential_sw_update_needed)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, yellowish);
|
|
ImGui::Text("Essential update is available. Please install!");
|
|
ImGui::PopStyleColor();
|
|
}
|
|
|
|
|
|
ImGui::PopFont();
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_grey);
|
|
sw_text_pos.y += 30;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Content:"); ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
ImGui::Text("%s", "Intel RealSense SDK 2.0, Intel RealSense Viewer and Depth Quality Tool");
|
|
|
|
sw_text_pos.y += 20;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Purpose:"); ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
ImGui::Text("%s", "Enhancements for stream alignment, texture mapping and camera accuracy health algorithms");
|
|
|
|
sw_text_pos.y += 30;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Current SW version:");
|
|
ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
auto current_sw_ver_str = std::string(selected_profile.profile.software_version);
|
|
ImGui::Text("%s", current_sw_ver_str.c_str());
|
|
|
|
if (essential_sw_update_needed)
|
|
{
|
|
ImGui::SameLine();
|
|
ImGui::PushStyleColor(ImGuiCol_Text, yellowish);
|
|
ImGui::Text("%s", " (Your version is older than the minimum version required for the proper functioning of your device)");
|
|
ImGui::PopStyleColor();
|
|
}
|
|
|
|
if ( selected_software_update.ver )
|
|
{
|
|
sw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
|
|
ImGui::Text("%s", (software_updates.size() >= 2) ?
|
|
"Versions available:" :
|
|
"Version to download:");
|
|
ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
// 3 box for multiple versions
|
|
if (software_updates.size() >= 2)
|
|
{
|
|
std::vector<const char*> swu_labels;
|
|
for (auto&& swu : software_updates)
|
|
{
|
|
swu_labels.push_back(swu.name_for_display.c_str());
|
|
}
|
|
ImGui::PushStyleColor(ImGuiCol_BorderShadow, dark_grey);
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, sensor_bg);
|
|
|
|
std::string combo_id = "##Software Update Version";
|
|
ImGui::PushItemWidth(200);
|
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 3);
|
|
ImGui::Combo(combo_id.c_str(), &selected_software_update_index, swu_labels.data(), static_cast<int>(swu_labels.size()));
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopStyleColor(2);
|
|
ImGui::SetWindowFontScale(1.);
|
|
}
|
|
else
|
|
{ // Single version
|
|
ImGui::Text("%s", std::string(selected_software_update.ver).c_str());
|
|
}
|
|
}
|
|
|
|
if (selected_software_update.release_page != "")
|
|
{
|
|
sw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Release Link:"); ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_grey);
|
|
ImGui::Text("%s", selected_software_update.release_page.c_str());
|
|
|
|
ImGui::SameLine();
|
|
auto underline_start = ImVec2(ImGui::GetCursorScreenPos().x - (ImGui::CalcTextSize(selected_software_update.release_page.c_str()).x + 8), ImGui::GetCursorScreenPos().y + ImGui::GetFontSize());
|
|
auto underline_end = ImVec2(ImGui::GetCursorScreenPos().x - 8, ImGui::GetCursorScreenPos().y + ImGui::GetFontSize());
|
|
ImGui::GetWindowDrawList()->AddLine(underline_start, underline_end, ImColor(light_grey));
|
|
|
|
ImGui::PopStyleColor();
|
|
if (ImGui::IsItemHovered())
|
|
window.link_hovered();
|
|
if (ImGui::IsItemClicked())
|
|
{
|
|
try
|
|
{
|
|
open_url(selected_software_update.release_page.c_str());
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_ERROR("Error opening URL: " + selected_software_update.release_page);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (selected_software_update.description != "")
|
|
{
|
|
sw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
|
|
ImGui::Text("%s", "Description:");
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::PushTextWrapPos(pos.w - 150);
|
|
ImGui::PushStyleColor(ImGuiCol_Border, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, regular_blue);
|
|
auto msg = selected_software_update.description.c_str();
|
|
sw_text_pos.x -= 4;
|
|
sw_text_pos.y += 15;
|
|
ImGui::SetCursorScreenPos(sw_text_pos);
|
|
ImGui::InputTextMultiline("##Software Update Description", const_cast<char*>(msg),
|
|
strlen(msg) + 1, ImVec2(ImGui::GetContentRegionAvailWidth() - 150, pos.mid_y - (pos.orig_pos.y + 160) - 40),
|
|
ImGuiInputTextFlags_ReadOnly);
|
|
ImGui::PopStyleColor(7);
|
|
ImGui::PopTextWrapPos();
|
|
}
|
|
|
|
if ( selected_software_update.ver )
|
|
{
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + pos.w - 150, pos.mid_y - 45 });
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::PushStyleColor(ImGuiCol_BorderShadow, dark_grey);
|
|
ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg);
|
|
|
|
if (ImGui::Button("Download", { 120, 40 }))
|
|
{
|
|
try
|
|
{
|
|
open_url(selected_software_update.download_link.c_str());
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_ERROR("Error opening URL: " + selected_software_update.download_link);
|
|
}
|
|
}
|
|
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
std::string tooltip = "This will redirect you to download the selected software from:\n" + selected_software_update.download_link;
|
|
ImGui::SetTooltip("%s", tooltip.c_str());
|
|
window.link_hovered();
|
|
}
|
|
|
|
ImGui::PopStyleColor(3);
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + 10, pos.mid_y - 25 });
|
|
ImGui::Text("%s", "Visit the release page before download to identify the most suitable package.");
|
|
}
|
|
|
|
ImGui::PopStyleColor();
|
|
}
|
|
return essential_sw_update_needed;
|
|
}
|
|
bool updates_model::draw_firmware_section(std::shared_ptr<notifications_model> not_model, const char * window_name, update_profile_model& selected_profile, position_params& pos, ux_window& window, std::string& error_message)
|
|
{
|
|
bool essential_fw_update_needed(false);
|
|
bool recommended_fw_update_needed(false);
|
|
|
|
// Prepare sorted array of FW updates profiles
|
|
// Assumption - essential updates version <= other policies versions
|
|
std::vector<dev_updates_profile::version_info> firmware_updates;
|
|
for (auto&& swu : selected_profile.profile.firmware_versions)
|
|
firmware_updates.push_back(swu.second);
|
|
std::sort(firmware_updates.begin(), firmware_updates.end(), [](dev_updates_profile::version_info& a, dev_updates_profile::version_info& b) {
|
|
return a.ver < b.ver;
|
|
});
|
|
if (static_cast<int>(firmware_updates.size()) <= selected_firmware_update_index) selected_firmware_update_index = 0;
|
|
|
|
dev_updates_profile::version_info selected_firmware_update;
|
|
|
|
if (firmware_updates.size() != 0)
|
|
{
|
|
bool essential_found(false);
|
|
bool recommended_found(false);
|
|
|
|
for (auto fw_update : firmware_updates)
|
|
{
|
|
if (!essential_found)
|
|
{
|
|
essential_found = essential_found || fw_update.name_for_display.find("ESSENTIAL") != std::string::npos;
|
|
essential_fw_update_needed = essential_fw_update_needed || essential_found && (selected_profile.profile.firmware_version < fw_update.ver);
|
|
}
|
|
|
|
if (!recommended_found)
|
|
{
|
|
recommended_found = recommended_found || fw_update.name_for_display.find("RECOMMENDED") != std::string::npos;
|
|
recommended_fw_update_needed = recommended_fw_update_needed || recommended_found && (selected_profile.profile.firmware_version < fw_update.ver);
|
|
}
|
|
}
|
|
|
|
// If essential update found on DB but not needed - Remove it
|
|
if (essential_found && !essential_fw_update_needed)
|
|
{
|
|
auto it = std::find_if(firmware_updates.begin(), firmware_updates.end(), [&](dev_updates_profile::version_info& u) {
|
|
return (u.name_for_display.find("ESSENTIAL") != std::string::npos);
|
|
});
|
|
if (it != firmware_updates.end())
|
|
firmware_updates.erase(it);
|
|
}
|
|
|
|
// If recommended update found on DB but not needed - Remove it
|
|
if (recommended_found && !recommended_fw_update_needed)
|
|
{
|
|
auto it = std::find_if(firmware_updates.begin(), firmware_updates.end(), [&](dev_updates_profile::version_info& u) {
|
|
return (u.name_for_display.find("RECOMMENDED") != std::string::npos);
|
|
});
|
|
if (it != firmware_updates.end())
|
|
firmware_updates.erase(it);
|
|
}
|
|
if (essential_fw_update_needed || recommended_fw_update_needed)
|
|
{
|
|
selected_firmware_update = firmware_updates[selected_firmware_update_index];
|
|
}
|
|
|
|
}
|
|
|
|
auto left_padding = 10;
|
|
auto top_padding = 15;
|
|
ImVec2 fw_text_pos(pos.orig_pos.x + left_padding, pos.mid_y + top_padding);
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
|
|
ImGui::PushFont(window.get_large_font());
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("FIRMWARE: ");
|
|
ImGui::PopStyleColor();
|
|
ImGui::SameLine();
|
|
if (!essential_fw_update_needed || firmware_updates.size() == 0)
|
|
{
|
|
if (recommended_fw_update_needed)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("Recommended update available!");
|
|
}
|
|
else
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_blue);
|
|
ImGui::Text("%s", static_cast<const char *>(textual_icons::check_square_o));
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", "Up to date.");
|
|
}
|
|
ImGui::PopStyleColor();
|
|
}
|
|
else if (essential_fw_update_needed)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, yellowish);
|
|
ImGui::Text("Essential update is available. Please install!");
|
|
ImGui::PopStyleColor();
|
|
}
|
|
|
|
|
|
ImGui::PopFont();
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_grey);
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Content:"); ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
ImGui::Text("%s", "Signed Firmware Image (.bin file)");
|
|
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Device detected: ");
|
|
ImGui::PopStyleColor();
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", selected_profile.profile.device_name.c_str());
|
|
ImGui::SameLine();
|
|
ImGui::Text(", SN: %s", selected_profile.profile.serial_number.c_str());
|
|
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Current FW version:");
|
|
ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
|
|
// During FW update do not take the version from the device because a recovery device version is 0.0.0.0.
|
|
// Instead display an update in progress label
|
|
std::string current_fw_ver_str;
|
|
if (_fw_update_state != fw_update_states::started)
|
|
current_fw_ver_str = std::string(selected_profile.profile.firmware_version);
|
|
else
|
|
current_fw_ver_str = "Update in progress..";
|
|
|
|
ImGui::Text("%s", current_fw_ver_str.c_str());
|
|
|
|
|
|
|
|
if (essential_fw_update_needed)
|
|
{
|
|
ImGui::SameLine();
|
|
ImGui::PushStyleColor(ImGuiCol_Text, yellowish);
|
|
ImGui::Text("%s", " (Your version is older than the minimum version required for the proper functioning of your device)");
|
|
ImGui::PopStyleColor();
|
|
}
|
|
|
|
if ( selected_firmware_update.ver )
|
|
{
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
|
|
ImGui::Text("%s", (firmware_updates.size() >= 2) ?
|
|
"Versions available:" :
|
|
"Version to download:");
|
|
ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
// Combo box for multiple versions
|
|
if (firmware_updates.size() >= 2)
|
|
{
|
|
std::vector<const char*> fwu_labels;
|
|
for (auto&& fwu : firmware_updates)
|
|
{
|
|
fwu_labels.push_back(fwu.name_for_display.c_str());
|
|
}
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_BorderShadow, dark_grey);
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, sensor_bg);
|
|
|
|
std::string combo_id = "##Firmware Update Version";
|
|
ImGui::PushItemWidth(200);
|
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 3);
|
|
ImGui::Combo(combo_id.c_str(), &selected_firmware_update_index, fwu_labels.data(), static_cast<int>(fwu_labels.size()));
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopStyleColor(2);
|
|
ImGui::SetWindowFontScale(1.);
|
|
}
|
|
else
|
|
{ // Single version
|
|
ImGui::Text("%s", std::string(selected_firmware_update.ver).c_str());
|
|
}
|
|
}
|
|
|
|
if (selected_firmware_update.release_page != "")
|
|
{
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Release Link:"); ImGui::SameLine();
|
|
ImGui::PopStyleColor();
|
|
ImGui::PushStyleColor(ImGuiCol_Text, light_grey);
|
|
ImGui::Text("%s", selected_firmware_update.release_page.c_str());
|
|
|
|
ImGui::SameLine();
|
|
auto underline_start = ImVec2(ImGui::GetCursorScreenPos().x - (ImGui::CalcTextSize(selected_firmware_update.release_page.c_str()).x + 8), ImGui::GetCursorScreenPos().y + ImGui::GetFontSize());
|
|
auto underline_end = ImVec2(ImGui::GetCursorScreenPos().x - 8, ImGui::GetCursorScreenPos().y + ImGui::GetFontSize());
|
|
ImGui::GetWindowDrawList()->AddLine(underline_start, underline_end, ImColor(light_grey));
|
|
|
|
|
|
ImGui::PopStyleColor();
|
|
if (ImGui::IsItemHovered())
|
|
window.link_hovered();
|
|
if (ImGui::IsItemClicked())
|
|
{
|
|
try
|
|
{
|
|
open_url(selected_firmware_update.release_page.c_str());
|
|
}
|
|
catch (...)
|
|
{
|
|
LOG_ERROR("Error opening URL: " + selected_firmware_update.release_page);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (selected_firmware_update.description != "")
|
|
{
|
|
fw_text_pos.y += 25;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::Text("%s", "Description:");
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::PushTextWrapPos(pos.w - 150);
|
|
ImGui::PushStyleColor(ImGuiCol_Border, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, transparent);
|
|
ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, regular_blue);
|
|
auto msg = selected_firmware_update.description.c_str();
|
|
fw_text_pos.x -= 4;
|
|
fw_text_pos.y += 15;
|
|
ImGui::SetCursorScreenPos(fw_text_pos);
|
|
ImGui::InputTextMultiline("##Firmware Update Description", const_cast<char*>(msg),
|
|
strlen(msg) + 1, ImVec2(ImGui::GetContentRegionAvailWidth() - 150, 75),
|
|
ImGuiInputTextFlags_ReadOnly);
|
|
ImGui::PopStyleColor(7);
|
|
ImGui::PopTextWrapPos();
|
|
}
|
|
|
|
|
|
if( ( _fw_update_state == fw_update_states::ready || _fw_update_state == fw_update_states::completed )
|
|
&& ( essential_fw_update_needed || recommended_fw_update_needed ) )
|
|
{
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + pos.w - 150, pos.orig_pos.y + pos.h - 115 });
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
ImGui::PushStyleColor(ImGuiCol_Button, sensor_bg);
|
|
|
|
if (ImGui::Button("Download &\n Install", ImVec2(120, 40)) || _retry)
|
|
{
|
|
_retry = false;
|
|
auto link = selected_firmware_update.download_link;
|
|
std::thread download_thread([link, this]() {
|
|
std::vector<uint8_t> vec;
|
|
http_downloader client;
|
|
|
|
if (!client.download_to_bytes_vector(link, vec,
|
|
[this](uint64_t dl_current_bytes, uint64_t dl_total_bytes) -> callback_result {
|
|
_fw_download_progress = static_cast<int>((dl_current_bytes * 100) / dl_total_bytes);
|
|
return callback_result::CONTINUE_DOWNLOAD;
|
|
}))
|
|
{
|
|
_fw_update_state = fw_update_states::failed_downloading;
|
|
LOG_ERROR("Error in download firmware version from: " + link);
|
|
}
|
|
|
|
_fw_image = vec;
|
|
|
|
_fw_download_progress = 100;
|
|
});
|
|
download_thread.detach();
|
|
|
|
_fw_update_state = fw_update_states::downloading;
|
|
_progress.last_progress_time = std::chrono::system_clock::now();
|
|
}
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::SetTooltip("This will download selected firmware and install it to the device");
|
|
window.link_hovered();
|
|
}
|
|
ImGui::PopStyleColor(2);
|
|
}
|
|
else if (_fw_update_state == fw_update_states::downloading)
|
|
{
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + left_padding, pos.orig_pos.y + pos.h - 95 });
|
|
_progress.draw(window, static_cast<int>(pos.w) - 170 - left_padding, _fw_download_progress / 3);
|
|
if (_fw_download_progress == 100 && !_fw_image.empty())
|
|
{
|
|
_fw_download_progress = 0;
|
|
_fw_update_state = fw_update_states::started;
|
|
|
|
_update_manager = std::make_shared<firmware_update_manager>(not_model,
|
|
*selected_profile.dev_model, selected_profile.profile.dev, selected_profile.ctx, _fw_image, true
|
|
);
|
|
auto invoke = [](std::function<void()> action) { action(); };
|
|
_update_manager->start(invoke);
|
|
}
|
|
}
|
|
else if (_fw_update_state == fw_update_states::started)
|
|
{
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + left_padding, pos.orig_pos.y + pos.h - 95 });
|
|
_progress.draw(window, static_cast<int>(pos.w) - 170 - left_padding, static_cast<int>(_update_manager->get_progress() * 0.66 + 33));
|
|
if (_update_manager->done()) {
|
|
_fw_update_state = fw_update_states::completed;
|
|
_fw_image.clear();
|
|
}
|
|
|
|
if (_update_manager->failed()) {
|
|
_fw_update_state = fw_update_states::failed_updating;
|
|
_fw_image.clear();
|
|
_fw_download_progress = 0;
|
|
}
|
|
// Verify an error window will not pop up. ImGui cannot handle 2 PopUpModals in parallel.
|
|
if (!error_message.empty())
|
|
{
|
|
LOG_ERROR("error caught during update process, details: " + error_message);
|
|
error_message.clear();
|
|
}
|
|
|
|
}
|
|
else if (_fw_update_state == fw_update_states::failed_downloading ||
|
|
_fw_update_state == fw_update_states::failed_updating)
|
|
{
|
|
ImGui::SetCursorScreenPos({ pos.orig_pos.x + left_padding, pos.orig_pos.y + pos.h - 95 });
|
|
ImGui::PushStyleColor(ImGuiCol_Text, white);
|
|
std::string text = _fw_update_state == fw_update_states::failed_downloading ?
|
|
"Firmware download failed, check connection and press to retry" :
|
|
"Firmware update process failed, press to retry";
|
|
if (ImGui::Button(text.c_str(), ImVec2(pos.w - 170 - left_padding, 25)))
|
|
{
|
|
_fw_update_state = fw_update_states::ready;
|
|
_update_manager.reset();
|
|
_fw_image.clear();
|
|
_retry = true;
|
|
}
|
|
ImGui::PopStyleColor();
|
|
_fw_download_progress = 0;
|
|
}
|
|
else if (_fw_update_state == fw_update_states::completed)
|
|
{
|
|
_fw_update_state = fw_update_states::ready;
|
|
_update_manager.reset();
|
|
_fw_image.clear();
|
|
_fw_download_progress = 0;
|
|
}
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
return essential_fw_update_needed;
|
|
}
|
|
|