diff --git a/src/webextensionadapter.cpp b/src/webextensionadapter.cpp index 28cb8386d3..89d09c93fd 100644 --- a/src/webextensionadapter.cpp +++ b/src/webextensionadapter.cpp @@ -13,6 +13,7 @@ #include #include +#include "connectionhealth.h" #include "controller.h" #include "feature/feature.h" #include "leakdetector.h" @@ -41,6 +42,13 @@ struct match : Ts... { template match(Ts...) -> match; +template +const char* asString(T qEnumValue) { + const QMetaObject* meta = qt_getEnumMetaObject(qEnumValue); + int index = meta->indexOfEnumerator(qt_getEnumName(qEnumValue)); + return meta->enumerator(index).valueToKey(qEnumValue); +}; + Logger logger("WebExtensionAdapter"); } // namespace @@ -55,6 +63,8 @@ WebExtensionAdapter::WebExtensionAdapter(QObject* parent) &WebExtensionAdapter::writeState); connect(vpn->controller(), &Controller::stateChanged, this, &WebExtensionAdapter::writeState); + connect(vpn->connectionHealth(), &ConnectionHealth::stabilityChanged, this, + &WebExtensionAdapter::writeState); mProxyStateChanged = vpn->proxyController()->stateBindable().subscribe( [this]() { serializeStatus(); }); @@ -161,25 +171,13 @@ QJsonObject WebExtensionAdapter::serializeStatus() { { int stateValue = vpn->state(); if (stateValue > App::StateCustom) { - MozillaVPN::CustomState state = - static_cast(stateValue); - const QMetaObject* meta = qt_getEnumMetaObject(state); - int index = meta->indexOfEnumerator(qt_getEnumName(state)); - obj["app"] = meta->enumerator(index).valueToKey(state); + obj["app"] = asString(static_cast(stateValue)); } else { - App::State state = static_cast(stateValue); - const QMetaObject* meta = qt_getEnumMetaObject(state); - int index = meta->indexOfEnumerator(qt_getEnumName(state)); - obj["app"] = meta->enumerator(index).valueToKey(state); + obj["app"] = asString(static_cast(stateValue)); } } - - { - Controller::State state = vpn->controller()->state(); - const QMetaObject* meta = qt_getEnumMetaObject(state); - int index = meta->indexOfEnumerator(qt_getEnumName(state)); - obj["vpn"] = meta->enumerator(index).valueToKey(state); - } + obj["vpn"] = asString(vpn->controller()->state()); + obj["connectionHealth"] = asString(vpn->connectionHealth()->stability()); #if defined MZ_PROXY_ENABLED { auto* proxyController = vpn->proxyController(); diff --git a/tests/functional/testWebExtensionApi.js b/tests/functional/testWebExtensionApi.js index 2d6ed6d484..0b2eed96f9 100644 --- a/tests/functional/testWebExtensionApi.js +++ b/tests/functional/testWebExtensionApi.js @@ -28,6 +28,7 @@ describe('WebExtension API', function() { sentToClient(new ExtensionMessage('status'), sock); const msg = await statusPromise assert(msg.status.version, `A Version is sent in msg: ${JSON.stringify(msg)}` ) + assert(msg.status.connectionHealth, `The current Connection Health status is sent in msg: ${JSON.stringify(msg)}` ) sock.destroy(); }); it('A Webextension can activate the VPN', async () => { @@ -104,6 +105,15 @@ describe('WebExtension API', function() { sock.destroy(); }); + it('A Webextension will be notified if the stability becomes instable ', async () => { + const sock = await connectExtension(); + const messagePipe = getMessageStream(sock); + const statusPromise = readResponseOfType('status', messagePipe); + await vpn.forceConnectionStabilityStatus("unstable"); + const msg = await statusPromise + assert(msg.status.connectionHealth == "Unstable", "The extension was notified of the instability: "+ msg.status.connectionHealth) + sock.destroy(); + }); }); }