Revision control
++ // Copyright (C) 2026 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
++
++ #include <QApplication>
++ #include <QJsonObject>
++ #include <QLabel>
++ #include <QPointer>
++ #include <QPushButton>
++ #include <QString>
++ #include <QVBoxLayout>
++ #include <QWidget>
++ #include <QtCore/qharmonyappjscontext.h>
++ #include <QtCore/qharmonyjscontext.h>
++ #include <QtCore/qharmonyjsonconversions.h>
++ #include <functional>
++ #include <napi.h>
++
++ using QHarmonyApplication = QNativeInterface::QHarmonyApplication;
++
++ namespace {
++
++ const QString wantParametersPropName = QStringLiteral("parameters");
++ const QString restartCountWantParamName = QStringLiteral("org.qtproject.example.restartCount");
++
++ //! [2]
++ void showStatusInLabel(QPointer<QLabel> statusLabel, QString text)
++ {
++ QHarmonyApplication::runOnQtThread(
++ [statusLabel, text]() {
++ if (statusLabel)
++ statusLabel->setText(text);
++ });
++ }
++
++ void showFailureInLabel(QPointer<QLabel> statusLabel, const QString &errorText)
++ {
++ showStatusInLabel(statusLabel, QStringLiteral("Failed to restart application: %1").arg(errorText));
++ }
++ //! [2]
++
++ //! [0]
++ void restartApplicationWithWant(QHarmonyAppJsContext &appJsContext, Napi::Object want, QPointer<QLabel> statusLabel)
++ {
++ Napi::Env env(appJsContext.env());
++ Napi::Object ability(env, appJsContext.defaultAbility());
++ if (ability.IsEmpty()) {
++ showFailureInLabel(statusLabel, QStringLiteral("no ability to restart from"));
++ return;
++ }
++
++ try {
++ auto abilityContext = ability.Get("context").As<Napi::Object>();
++ auto getApplicationContext = abilityContext.Get("getApplicationContext").As<Napi::Function>();
++ auto applicationContext = getApplicationContext.Call(abilityContext, {}).As<Napi::Object>();
++ auto restartAppFunc = applicationContext.Get("restartApp").As<Napi::Function>();
++ restartAppFunc.Call(applicationContext, {want});
++ } catch (const Napi::Error &error) {
++ showFailureInLabel(statusLabel, QString::fromUtf8(error.what()));
++ }
++ }
++ //! [0]
++
++ Napi::Object appLaunchWant(QHarmonyAppJsContext &appJsContext)
++ {
++ Napi::Env env(appJsContext.env());
++ Napi::Object ability(env, appJsContext.defaultAbility());
++ if (ability.IsEmpty())
++ return Napi::Object();
++ return ability.Get("launchWant").As<Napi::Object>();
++ }
++
++ QJsonObject readLaunchWant()
++ {
++ return QHarmonyApplication::runOnJsThreadAndWait(
++ [](QHarmonyJsContext &jsContext) {
++ auto &appJsContext = QHarmonyAppJsContext::fromJsContext(jsContext);
++ return QtHarmony::mapJsObjectToQJsonObject(appJsContext.env(), appLaunchWant(appJsContext));
++ });
++ }
++
++ QWidget *createActionButton(const QString &label, QWidget *parent, std::function<void()> action)
++ {
++ auto *button = new QPushButton(label, parent);
++ QObject::connect(button, &QPushButton::clicked, parent, std::move(action));
++ return button;
++ }
++
++ int restartCountFromWant(const QJsonObject &want)
++ {
++ return want.value(wantParametersPropName).toObject().value(restartCountWantParamName).toInt();
++ }
++
++ QJsonObject makeWantWithRestartCount(const QJsonObject &launchWant, int restartCount)
++ {
++ QJsonObject parameters = launchWant.value(wantParametersPropName).toObject();
++ parameters.insert(restartCountWantParamName, restartCount);
++ QJsonObject want = launchWant;
++ want.insert(wantParametersPropName, parameters);
++ return want;
++ }
++
++ }
++
++ int main(int argc, char *argv[])
++ {
++ QApplication app(argc, argv);
++
++ const QJsonObject launchWant = readLaunchWant();
++ const int restartCount = restartCountFromWant(launchWant);
++
++ QWidget window;
++ window.setWindowTitle(QStringLiteral("Restart application example"));
++
++ auto *statusLabel = new QLabel(&window);
++ statusLabel->setWordWrap(true);
++
++ auto *layout = new QVBoxLayout(&window);
++ //! [1]
++ layout->addWidget(
++ createActionButton(
++ QStringLiteral("Restart with the launch Want\n(the restart count stays the same)"),
++ &window,
++ [statusLabel]() {
++ statusLabel->clear();
++ QHarmonyApplication::runOnJsThread(
++ [statusLabel = QPointer<QLabel>(statusLabel)](QHarmonyJsContext &jsContext) {
++ auto &appJsContext = QHarmonyAppJsContext::fromJsContext(jsContext);
++ restartApplicationWithWant(appJsContext, appLaunchWant(appJsContext), statusLabel);
++ });
++ }));
++ layout->addWidget(
++ createActionButton(
++ QStringLiteral("Restart with the restart count increased"),
++ &window,
++ [statusLabel, want = makeWantWithRestartCount(launchWant, restartCount + 1)]() {
++ statusLabel->clear();
++ QHarmonyApplication::runOnJsThread(
++ [want, statusLabel = QPointer<QLabel>(statusLabel)](QHarmonyJsContext &jsContext) {
++ auto &appJsContext = QHarmonyAppJsContext::fromJsContext(jsContext);
++ Napi::Object jsWant(appJsContext.env(), QtHarmony::mapQJsonObjectToJsObject(appJsContext.env(), want));
++ restartApplicationWithWant(appJsContext, jsWant, statusLabel);
++ });
++ }));
++ //! [1]
++ layout->addWidget(new QLabel(QStringLiteral("Restart count: %1").arg(restartCount), &window));
++ layout->addWidget(statusLabel);
++
++ window.show();
++ return app.exec();
++ }