/*! * * Copyright (c) 2023 Diality Inc. - All Rights Reserved. * * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file VSwUpdate.h * \author (last) Phil Braica * \date (last) 23-Jan-2023 * \author (original) Phil Braica * \date (original) 23-Jan-2023 * */ #ifndef V_SW_UPDATE_H_ #define V_SW_UPDATE_H_ #include "IEnterBootLoader.h" #include "Package.h" #include #include #include #include #include #include #include #include /*! * \brief The view model for software update. */ class VSWUpdate : public QAbstractTableModel, SwUpdate::IEnterBootLoader { Q_OBJECT Q_ENUMS(Roles) Q_PROPERTY(QString buttonText READ getButtonText WRITE setButtonText NOTIFY buttonTextChanged) Q_PROPERTY(QString stateData READ getState WRITE setState NOTIFY stateChanged) Q_PROPERTY(float percent READ getPercent WRITE setPercent NOTIFY percentChanged) Q_PROPERTY(bool progressVisible READ getProgressVisible WRITE setProgressVisible NOTIFY progressVisibleChanged) public: // Constructor. explicit VSWUpdate(QObject* parent = nullptr); // Virtual destructor. virtual ~VSWUpdate(); // Setup function. void setup( const QStringList directories, const QString factoryImageDir, const QString wifiImageDir, const QString oldUpdateDir, uint32 maxOldUpdates, const QString publicKeyFile); /*! * \brief Provide a list of available data roles. * * Used by QML to provide cell like data. * * \return Hash of int, names. */ QHash roleNames() const override { return {{Qt::DisplayRole, "displayRole"}, {Qt::UserRole + 1, "colorRole"}}; } /*! * \brief Number of rows (number of available updates). * * \param parent Model index. * * \return Number of rows. */ int rowCount(const QModelIndex& parent = QModelIndex()) const override { if (parent.isValid()) { return 0; } return (int)_available.size(); } /*! * \brief Return the number of columns. * * \param parent Model index. * * \return 4, there are 4 columns. */ int columnCount(const QModelIndex& parent = QModelIndex()) const override { if (parent.isValid()) { return 0; } return 5; } /*! * \brief Get table data. * * \param index Table model index. * \param role Kind of data (text, color). * * \return Depending on the role, either text or color. */ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; /*! * \brief Get the message text. * * \return Text string. */ QString getState() const { return _stateMsg; } /*! * \brief Set the message text. * * Sets the value and fires the property event. * * \param value New value. */ void setState(const QString& value) { // Trim compare, then set as needed and fire event. QString trim = value.trimmed(); trim = (_postWasOk ? QString("Post passed. ") : QString("Post failed! ")) + (_settingsOk ? QString("Settings/version info retrieved. ") : QString("Settings/version failed! ")) + (_wasTrialBoot ? QString("First reboot after install\n") : QString("Previous functional boot\n")) + trim; if (_stateMsg != trim) { _stateMsg = trim; emit stateChanged(); } } /*! * \brief Get the button text property for the XML button. * * \return Text string. */ QString getButtonText() const { return _buttonText; } /*! * \brief Set the button text. * * Sets the value and fires the property event. * * \param value New value. */ void setButtonText(const QString& value) { if (_buttonText != value) { _buttonText = value; emit buttonTextChanged(); } } /*! * \brief Get the percent complete value. * * \return Value 0 to 1.. */ float getPercent() const { return _percent; } /*! * \brief Set the percent complete value. * * Sets the value and fires the property event. * * \param value New value. */ void setPercent(const float& value) { if (_percent != value) { _percent = value; emit percentChanged(); } } /*! * \brief Get the bool indicating the progress bar should be visible. * * \return True if the progress bar should be visible. */ bool getProgressVisible() { return _progressVisible; } /*! * \brief Set whether the progress bar should be visible or not. * * \param value New value. */ void setProgressVisible(bool value) { if (_progressVisible != value) { _progressVisible = value; emit progressVisibleChanged(); } } // IEnterBootLoader interface. void sendEnterBootloader(bool asHd); signals: /*! Signal that data changed. */ void stateChanged(); /*! Signal the button text changed. */ void buttonTextChanged(); /*! Signal the percentage value changed. */ void percentChanged(); /*! Signal that progress changed. */ void progressVisibleChanged(); /*! * \brief Fired when we are about to try to reboot the Linux box. * * Allows the UI to attempt any custom logging. After this callback * signal completes, the reboot will get called. */ void aboutToReboot(); /*! * \brief Indicates a likely cyber attack occured. * * The msg contains info already logged, in case the main * UI also needs that message for some reason. * * \param msg What has already been logged. */ void securityCompromised(const QString& msg); public slots: // Start / stop button clicked. void startStopBtnClicked(); // Row clicked. void rowClicked(int row); // Shown / hidden. void visibilityChanged(bool visible, QObject * qml); // Things to determine if we booted ok. void onPostDone(bool vPass); void onSettingsDone(); protected: // Write an app styled can msg to control both FW nodes. void sendAppCommand(uint16 cmd, bool asHd); // Log a message. void writeLog(const QString& msg, bool isDebug); // Virtual to make testing easier. virtual void reboot(); // State. void startStopUpdate(const QString& msg, bool asStart); // Utility. void set_progress(const QString& txt); void update_progress(const QString& txt, float percent = 0); void clear_progress(); // Periodic update poll. void handle_update(); // Utility functions. void scanForUpdates(); // Sort packages found for UI table. void ui_sort(std::vector& pkgs); // Control the USB, both enable and mounting. bool controlUSB(bool enable); void checkMountUsb(); std::vector _available; ///< List of available things. QString _pubKey; ///< Public key. QStringList _updateDirs; ///< Update available directories. QString _persistent; ///< Persistent update text. std::string _oldUpdates; ///< Old updates directory. std::string _factoryImg; ///< Factory image or factory directory. std::string _wifiDir; ///< Wifi download dir. uint32 _maxOld; ///< Max old updates. bool _updating; ///< Updating flag. float _percent; ///< Percent complete, [0-1]. QTimer _timer; ///< Timer for update. sint32 _selected; ///< Selected row, -1 is none. Package _package; ///< Our update object (UI indepenedent C++). QString _stateMsg; ///< State text. QString _buttonText; ///< Button text. QQuickItem* _mpBackButton; ///< Back button. bool _isVisible; ///< Widget is visible or not. bool _progressVisible; ///< Is the progress bar visible. bool _postWasOk; ///< Post was ok flag. bool _settingsOk; ///< Version and settings are ok. bool _wasTrialBoot; ///< This was a trial boot or normal. std::chrono::time_point _lastPing; ///< Last ping time. }; #endif // V_SW_UPDATE_H_