diff --git a/src/dcc-update-plugin/operation/updatemodel.cpp b/src/dcc-update-plugin/operation/updatemodel.cpp index 1e68d221..98c1cf76 100644 --- a/src/dcc-update-plugin/operation/updatemodel.cpp +++ b/src/dcc-update-plugin/operation/updatemodel.cpp @@ -46,6 +46,7 @@ UpdateModel::UpdateModel(QObject* parent) , m_updateDisabledIcon("") , m_updateDisabledTips("") , m_batterIsOK(false) + , m_postUpdateCheckCompleted(true) // 非 Wayland 默认为 true,Wayland 下检查完成后再置为 true , m_lastStatus(Default) , m_showCheckUpdate(false) , m_checkUpdateIcon("") @@ -222,6 +223,16 @@ void UpdateModel::setBatterIsOK(bool ok) Q_EMIT batterIsOKChanged(ok); } +void UpdateModel::setPostUpdateCheckCompleted(bool completed) +{ + if (m_postUpdateCheckCompleted == completed) { + return; + } + + m_postUpdateCheckCompleted = completed; + Q_EMIT postUpdateCheckCompletedChanged(completed); +} + void UpdateModel::setForceUpdateText(const QString& updateTime, int lastoreStatus) { if (!updateTime.isEmpty()) { diff --git a/src/dcc-update-plugin/operation/updatemodel.h b/src/dcc-update-plugin/operation/updatemodel.h index 7d1bb6a8..efb7b369 100644 --- a/src/dcc-update-plugin/operation/updatemodel.h +++ b/src/dcc-update-plugin/operation/updatemodel.h @@ -100,6 +100,7 @@ class UpdateModel : public QObject Q_PROPERTY(bool upgradeDeliveryEnable READ upgradeDeliveryEnable NOTIFY upgradeDeliveryEnableChanged FINAL) Q_PROPERTY(bool p2pUpdateEnabled READ isP2PUpdateEnabled NOTIFY p2pUpdateEnableStateChanged FINAL) Q_PROPERTY(bool forceUpdate READ forceUpdate NOTIFY forceUpdateChanged FINAL) + Q_PROPERTY(bool postUpdateCheckCompleted READ postUpdateCheckCompleted NOTIFY postUpdateCheckCompletedChanged FINAL) Q_PROPERTY(UpdateHistoryModel *historyModel READ historyModel NOTIFY historyModelChanged FINAL) @@ -261,6 +262,9 @@ class UpdateModel : public QObject bool isPrivateUpdate() const { return m_isPrivateUpdate; } void setIsPrivateUpdate(bool isPrivateUpdate); + bool postUpdateCheckCompleted() const { return m_postUpdateCheckCompleted; } + void setPostUpdateCheckCompleted(bool completed); + UpdatesStatus updateStatus(ControlPanelType type) const; UpdatesStatus updateStatus(UpdateType type) const; QList updateTypesList(ControlPanelType type) const; @@ -419,6 +423,7 @@ public slots: void updateInfoChanged(UpdateType); void isUpdatableChanged(const bool isUpdatablePackages); void isPrivateUpdateChanged(const bool isPrivateUpdate); + void postUpdateCheckCompletedChanged(bool completed); void updateStatusChanged(ControlPanelType, UpdatesStatus); void controlTypeChanged(); void lastErrorChanged(UpdatesStatus, UpdateErrorType); @@ -457,6 +462,7 @@ public slots: QString m_updateDisabledIcon; QString m_updateDisabledTips; bool m_batterIsOK; + bool m_postUpdateCheckCompleted; int m_lastStatus; bool m_immutableAutoRecovery; diff --git a/src/dcc-update-plugin/operation/updatework.cpp b/src/dcc-update-plugin/operation/updatework.cpp index 9de67a43..17f732dd 100644 --- a/src/dcc-update-plugin/operation/updatework.cpp +++ b/src/dcc-update-plugin/operation/updatework.cpp @@ -132,6 +132,9 @@ UpdateWorker::UpdateWorker(UpdateModel* model, QObject* parent) , m_backupJob(nullptr) , m_installPackageJob(nullptr) , m_removePackageJob(nullptr) + , m_checkSystemJob(nullptr) + , m_updateMode(0) + , m_currentCheckStage(0) { qCDebug(logDccUpdatePlugin) << "Initializing UpdateWorker"; qRegisterMetaType("UpdatesStatus"); @@ -151,6 +154,7 @@ UpdateWorker::~UpdateWorker() deleteJob(m_backupJob); deleteJob(m_installPackageJob); deleteJob(m_removePackageJob); + deleteJob(m_checkSystemJob); if (m_lastoreHeartBeatTimer != nullptr) { if (m_lastoreHeartBeatTimer->isActive()) { @@ -774,6 +778,11 @@ void UpdateWorker::doUpgrade(int updateTypes, bool doBackup) cleanLaStoreJob(m_distUpgradeJob); cleanLaStoreJob(m_backupJob); + if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsWaylandPlatform)) { + m_updateMode = updateTypes; + m_model->setPostUpdateCheckCompleted(false); + } + QDBusPendingCall call = m_updateInter->DistUpgradePartly(updateTypes, doBackup); QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(call, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, updateTypes, watcher, doBackup] { @@ -1711,6 +1720,13 @@ void UpdateWorker::onDistUpgradeStatusChanged(const QString& status) if (updateStatus == UpgradeComplete) { cleanLaStoreJob(m_distUpgradeJob); updateSystemVersion(); + + // TODO: treeland 环境下重启后无法启动 dde-update 进程, 这里直接在安装更新完成后,进行检查: + // 串行执行: CheckUpgrade(stage=1, CSS_BeforeLogin) → CheckUpgrade(stage=2, CSS_AfterLogin) → 标记完成 + if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::IsWaylandPlatform)) { + doCheckSystemOnWayland(1); + } + } else { if (updateStatus == UpgradeFailed && m_distUpgradeJob) { const QString& description = m_distUpgradeJob->description(); @@ -1858,3 +1874,68 @@ void UpdateWorker::cleanUpgradeDeliveryCache() } }); } + +void UpdateWorker::doCheckSystemOnWayland(int stage) +{ + qCInfo(logDccUpdatePlugin) << "treeland: start check system, stage:" << stage; + m_currentCheckStage = stage; + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(m_updateInter->CheckUpgrade(m_updateMode, stage), this); + connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, watcher] { + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + qCWarning(logDccUpdatePlugin) << "CheckUpgrade stage" << m_currentCheckStage + << "failed:" << reply.error().message(); + // 即使检查失败也标记完成,不阻塞后续流程 + m_model->setPostUpdateCheckCompleted(true); + } else { + const QString jobPath = reply.value().path(); + qCInfo(logDccUpdatePlugin) << "Check system job created:" << jobPath << "stage:" << m_currentCheckStage; + setCheckSystemJob(jobPath); + } + watcher->deleteLater(); + }); +} + +void UpdateWorker::setCheckSystemJob(const QString& jobPath) +{ + qCInfo(logDccUpdatePlugin) << "Create check system job, path:" << jobPath; + if (m_checkSystemJob || jobPath.isEmpty()) { + qCWarning(logDccUpdatePlugin) << "Check system job already exists or path is empty"; + m_model->setPostUpdateCheckCompleted(true); + return; + } + + m_checkSystemJob = new UpdateJobDBusProxy(jobPath, this); + connect(m_checkSystemJob, &UpdateJobDBusProxy::StatusChanged, this, &UpdateWorker::onCheckSystemJobStatusChanged); + // 主动触发一次状态同步,避免 job 在连接信号前已完成 + onCheckSystemJobStatusChanged(m_checkSystemJob->status()); +} + +void UpdateWorker::onCheckSystemJobStatusChanged(const QString& status) +{ + qCInfo(logDccUpdatePlugin) << "Check system job status changed, stage:" << m_currentCheckStage << "status:" << status; + + // 仅关注终态:failed / succeed / end + if (status == "failed" || status == "succeed" || status == "end") { + cleanLaStoreJob(m_checkSystemJob); + + if (m_currentCheckStage == 1) { + if (status == "failed") { + qCWarning(logDccUpdatePlugin) << "CheckUpgrade stage CSS_BeforeLogin failed, cannot continue to CSS_AfterLogin"; + m_model->setPostUpdateCheckCompleted(true); + return; + } else if (status == "end") { + // CSS_BeforeLogin 阶段完成,继续 CSS_AfterLogin 阶段 + qCInfo(logDccUpdatePlugin) << "treeland: CSS_BeforeLogin completed, starting CSS_AfterLogin"; + QTimer::singleShot(1000, this, [this] { + doCheckSystemOnWayland(2); + }); + } + } else { + // CSS_AfterLogin 阶段完成,标记检查完成 + qCInfo(logDccUpdatePlugin) << "treeland: CSS_AfterLogin completed, mark check completed"; + m_model->setPostUpdateCheckCompleted(true); + } + } +} diff --git a/src/dcc-update-plugin/operation/updatework.h b/src/dcc-update-plugin/operation/updatework.h index 0b594ef8..17263ee6 100644 --- a/src/dcc-update-plugin/operation/updatework.h +++ b/src/dcc-update-plugin/operation/updatework.h @@ -59,6 +59,8 @@ class UpdateWorker : public QObject Q_INVOKABLE void setShutdownAndUpgrade(bool isShutdownUpdate = false); void setBackupJob(const QString& jobPath); void setDistUpgradeJob(const QString& jobPath); + void doCheckSystemOnWayland(int stage); + void setCheckSystemJob(const QString& jobPath); void updateSystemVersion(); // 更新设置-更新类型 @@ -133,6 +135,7 @@ public Q_SLOTS: void onDistUpgradeStatusChanged(const QString& status); void onInstallPackageStatusChanged(const QString& value); void onRemovePackageStatusChanged(const QString& value); + void onCheckSystemJobStatusChanged(const QString& status); Q_SIGNALS: void requestCloseTestingChannel(); @@ -163,6 +166,10 @@ public Q_SLOTS: QPointer m_backupJob; QPointer m_installPackageJob; QPointer m_removePackageJob; + QPointer m_checkSystemJob; + + int m_updateMode; + int m_currentCheckStage; // 当前 check system 阶段: 1=CSS_BeforeLogin, 2=CSS_AfterLogin }; #endif // UPDATEWORK_H diff --git a/src/dcc-update-plugin/qml/UpdateMain.qml b/src/dcc-update-plugin/qml/UpdateMain.qml index f543f44f..5596e7c1 100644 --- a/src/dcc-update-plugin/qml/UpdateMain.qml +++ b/src/dcc-update-plugin/qml/UpdateMain.qml @@ -199,6 +199,7 @@ DccObject { updateTips: qsTr("To ensure proper functioning of your system and applications, please restart your computer after the update") btnActions: [ qsTr("Reboot now") ] updateListcheck: false + busyState: !dccData.model().postUpdateCheckCompleted onBtnClicked: function(index, updateType) { dccData.work().reStart() @@ -318,8 +319,12 @@ DccObject { if (dccData.model().isPrivateUpdate) { dccData.work().doUpgrade(updateListModels.getAllUpdateType(), true) } else { - updateSelectLoader.updateType = updateType - updateSelectLoader.active = true + if (DccApp.isTreeland()) { + dccData.work().doUpgrade(updateType, true) + } else { + updateSelectLoader.updateType = updateType + updateSelectLoader.active = true + } } } else if (index === 1) { dccData.work().reCheckWithUi(); diff --git a/src/dde-update/misc/dde-update-autostart.desktop b/src/dde-update/misc/dde-update-autostart.desktop index 80b9345e..d4ff66cd 100644 --- a/src/dde-update/misc/dde-update-autostart.desktop +++ b/src/dde-update/misc/dde-update-autostart.desktop @@ -2,5 +2,5 @@ Name=dde-update Type=Application NoDisplay=true -Exec=sh -c 'if [ -f /tmp/deepin_update_option.json ]; then /usr/bin/dde-update ; fi' +Exec=sh -c 'if [ -f /tmp/deepin_update_option.json ] && [ "$XDG_SESSION_TYPE" != "wayland" ]; then /usr/bin/dde-update ; fi' X-Deepin-Vendor=deepin \ No newline at end of file