moved the platform-specific android code for the new ui
This commit is contained in:
parent
5b8a0881b7
commit
0a1359ed16
31 changed files with 854 additions and 764 deletions
|
@ -13,17 +13,16 @@
|
|||
|
||||
#include "android_controller.h"
|
||||
#include "private/qandroidextras_p.h"
|
||||
#include "ui/pages_logic/StartPageLogic.h"
|
||||
|
||||
#include "androidvpnactivity.h"
|
||||
#include "androidutils.h"
|
||||
#include "androidvpnactivity.h"
|
||||
|
||||
namespace {
|
||||
AndroidController* s_instance = nullptr;
|
||||
namespace
|
||||
{
|
||||
AndroidController *s_instance = nullptr;
|
||||
|
||||
constexpr auto PERMISSIONHELPER_CLASS =
|
||||
"org/amnezia/vpn/qt/VPNPermissionHelper";
|
||||
} // namespace
|
||||
constexpr auto PERMISSIONHELPER_CLASS = "org/amnezia/vpn/qt/VPNPermissionHelper";
|
||||
} // namespace
|
||||
|
||||
AndroidController::AndroidController() : QObject()
|
||||
{
|
||||
|
@ -33,109 +32,127 @@ AndroidController::AndroidController() : QObject()
|
|||
|
||||
auto activity = AndroidVPNActivity::instance();
|
||||
|
||||
connect(activity, &AndroidVPNActivity::serviceConnected, this, []() {
|
||||
qDebug() << "Transact: service connected";
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, "");
|
||||
}, Qt::QueuedConnection);
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::serviceConnected, this,
|
||||
[]() {
|
||||
qDebug() << "Transact: service connected";
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, "");
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventInitialized, this,
|
||||
[this](const QString& parcelBody) {
|
||||
// We might get multiple Init events as widgets, or fragments
|
||||
// might query this.
|
||||
if (m_init) {
|
||||
return;
|
||||
}
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventInitialized, this,
|
||||
[this](const QString &parcelBody) {
|
||||
// We might get multiple Init events as widgets, or fragments
|
||||
// might query this.
|
||||
if (m_init) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Transact: init";
|
||||
qDebug() << "Transact: init";
|
||||
|
||||
m_init = true;
|
||||
m_init = true;
|
||||
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
qlonglong time = doc.object()["time"].toVariant().toLongLong();
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
qlonglong time = doc.object()["time"].toVariant().toLongLong();
|
||||
|
||||
isConnected = doc.object()["connected"].toBool();
|
||||
isConnected = doc.object()["connected"].toBool();
|
||||
|
||||
if (isConnected) {
|
||||
emit scheduleStatusCheckSignal();
|
||||
}
|
||||
if (isConnected) {
|
||||
emit scheduleStatusCheckSignal();
|
||||
}
|
||||
|
||||
emit initialized(
|
||||
true, isConnected,
|
||||
time > 0 ? QDateTime::fromMSecsSinceEpoch(time) : QDateTime());
|
||||
emit initialized(true, isConnected, time > 0 ? QDateTime::fromMSecsSinceEpoch(time) : QDateTime());
|
||||
|
||||
setFallbackConnectedNotification();
|
||||
}, Qt::QueuedConnection);
|
||||
setFallbackConnectedNotification();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventConnected, this,
|
||||
[this](const QString& parcelBody) {
|
||||
Q_UNUSED(parcelBody);
|
||||
qDebug() << "Transact: connected";
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventConnected, this,
|
||||
[this](const QString &parcelBody) {
|
||||
Q_UNUSED(parcelBody);
|
||||
qDebug() << "Transact: connected";
|
||||
|
||||
if (!isConnected) {
|
||||
emit scheduleStatusCheckSignal();
|
||||
}
|
||||
if (!isConnected) {
|
||||
emit scheduleStatusCheckSignal();
|
||||
}
|
||||
|
||||
isConnected = true;
|
||||
isConnected = true;
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::Connected);
|
||||
}, Qt::QueuedConnection);
|
||||
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventDisconnected, this,
|
||||
[this]() {
|
||||
qDebug() << "Transact: disconnected";
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventDisconnected, this,
|
||||
[this]() {
|
||||
qDebug() << "Transact: disconnected";
|
||||
|
||||
isConnected = false;
|
||||
isConnected = false;
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::Disconnected);
|
||||
}, Qt::QueuedConnection);
|
||||
emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventStatisticUpdate, this,
|
||||
[this](const QString& parcelBody) {
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventStatisticUpdate, this,
|
||||
[this](const QString &parcelBody) {
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
|
||||
QString rx = doc.object()["rx_bytes"].toString();
|
||||
QString tx = doc.object()["tx_bytes"].toString();
|
||||
QString endpoint = doc.object()["endpoint"].toString();
|
||||
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
||||
QString rx = doc.object()["rx_bytes"].toString();
|
||||
QString tx = doc.object()["tx_bytes"].toString();
|
||||
QString endpoint = doc.object()["endpoint"].toString();
|
||||
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
||||
|
||||
emit statusUpdated(rx, tx, endpoint, deviceIPv4);
|
||||
}, Qt::QueuedConnection);
|
||||
emit statusUpdated(rx, tx, endpoint, deviceIPv4);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventBackendLogs, this,
|
||||
[this](const QString& parcelBody) {
|
||||
qDebug() << "Transact: backend logs";
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventBackendLogs, this,
|
||||
[this](const QString &parcelBody) {
|
||||
qDebug() << "Transact: backend logs";
|
||||
|
||||
QString buffer = parcelBody.toUtf8();
|
||||
if (m_logCallback) {
|
||||
m_logCallback(buffer);
|
||||
}
|
||||
}, Qt::QueuedConnection);
|
||||
QString buffer = parcelBody.toUtf8();
|
||||
if (m_logCallback) {
|
||||
m_logCallback(buffer);
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventActivationError, this,
|
||||
[this](const QString& parcelBody) {
|
||||
Q_UNUSED(parcelBody)
|
||||
qDebug() << "Transact: error";
|
||||
emit connectionStateChanged(VpnProtocol::Error);
|
||||
}, Qt::QueuedConnection);
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventActivationError, this,
|
||||
[this](const QString &parcelBody) {
|
||||
Q_UNUSED(parcelBody)
|
||||
qDebug() << "Transact: error";
|
||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventConfigImport, this,
|
||||
[this](const QString& parcelBody) {
|
||||
qDebug() << "Transact: config import";
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::eventConfigImport, this,
|
||||
[this](const QString &parcelBody) {
|
||||
qDebug() << "Transact: config import";
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
|
||||
QString buffer = doc.object()["config"].toString();
|
||||
qDebug() << "Transact: config string" << buffer;
|
||||
importConfig(buffer);
|
||||
}, Qt::QueuedConnection);
|
||||
QString buffer = doc.object()["config"].toString();
|
||||
qDebug() << "Transact: config string" << buffer;
|
||||
importConfigFromOutside(buffer);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::serviceDisconnected, this,
|
||||
[this]() {
|
||||
qDebug() << "Transact: service disconnected";
|
||||
m_serviceConnected = false;
|
||||
}, Qt::QueuedConnection);
|
||||
connect(
|
||||
activity, &AndroidVPNActivity::serviceDisconnected, this,
|
||||
[this]() {
|
||||
qDebug() << "Transact: service disconnected";
|
||||
m_serviceConnected = false;
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
AndroidController* AndroidController::instance() {
|
||||
AndroidController *AndroidController::instance()
|
||||
{
|
||||
if (!s_instance) {
|
||||
s_instance = new AndroidController();
|
||||
}
|
||||
|
@ -143,16 +160,13 @@ AndroidController* AndroidController::instance() {
|
|||
return s_instance;
|
||||
}
|
||||
|
||||
bool AndroidController::initialize(StartPageLogic *startPageLogic)
|
||||
bool AndroidController::initialize()
|
||||
{
|
||||
qDebug() << "Initializing";
|
||||
|
||||
m_startPageLogic = startPageLogic;
|
||||
|
||||
// Hook in the native implementation for startActivityForResult into the JNI
|
||||
JNINativeMethod methods[]{{"startActivityForResult",
|
||||
"(Landroid/content/Intent;)V",
|
||||
reinterpret_cast<void*>(startActivityForResult)}};
|
||||
JNINativeMethod methods[] { { "startActivityForResult", "(Landroid/content/Intent;)V",
|
||||
reinterpret_cast<void *>(startActivityForResult) } };
|
||||
QJniObject javaClass(PERMISSIONHELPER_CLASS);
|
||||
QJniEnvironment env;
|
||||
jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
|
||||
|
@ -168,11 +182,9 @@ ErrorCode AndroidController::start()
|
|||
{
|
||||
qDebug() << "Prompting for VPN permission";
|
||||
QJniObject activity = AndroidUtils::getActivity();
|
||||
auto appContext = activity.callObjectMethod(
|
||||
"getApplicationContext", "()Landroid/content/Context;");
|
||||
QJniObject::callStaticMethod<void>(
|
||||
PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
|
||||
appContext.object());
|
||||
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||
QJniObject::callStaticMethod<void>(PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
|
||||
appContext.object());
|
||||
|
||||
QJsonDocument doc(m_vpnConfig);
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_ACTIVATE, doc.toJson());
|
||||
|
@ -180,7 +192,8 @@ ErrorCode AndroidController::start()
|
|||
return NoError;
|
||||
}
|
||||
|
||||
void AndroidController::stop() {
|
||||
void AndroidController::stop()
|
||||
{
|
||||
qDebug() << "AndroidController::stop";
|
||||
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_DEACTIVATE, QString());
|
||||
|
@ -188,16 +201,16 @@ void AndroidController::stop() {
|
|||
|
||||
// Activates the tunnel that is currently set
|
||||
// in the VPN Service
|
||||
void AndroidController::resumeStart() {
|
||||
void AndroidController::resumeStart()
|
||||
{
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_RESUME_ACTIVATE, QString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the current notification text that is shown
|
||||
*/
|
||||
void AndroidController::setNotificationText(const QString& title,
|
||||
const QString& message,
|
||||
int timerSec) {
|
||||
void AndroidController::setNotificationText(const QString &title, const QString &message, int timerSec)
|
||||
{
|
||||
QJsonObject args;
|
||||
args["title"] = title;
|
||||
args["message"] = message;
|
||||
|
@ -207,7 +220,8 @@ void AndroidController::setNotificationText(const QString& title,
|
|||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_TEXT, doc.toJson());
|
||||
}
|
||||
|
||||
void AndroidController::shareConfig(const QString& configContent, const QString& suggestedName) {
|
||||
void AndroidController::shareConfig(const QString &configContent, const QString &suggestedName)
|
||||
{
|
||||
AndroidVPNActivity::saveFileAs(configContent, suggestedName);
|
||||
}
|
||||
|
||||
|
@ -216,7 +230,8 @@ void AndroidController::shareConfig(const QString& configContent, const QString&
|
|||
* switches into the Connected state without the app open
|
||||
* e.g via always-on vpn
|
||||
*/
|
||||
void AndroidController::setFallbackConnectedNotification() {
|
||||
void AndroidController::setFallbackConnectedNotification()
|
||||
{
|
||||
QJsonObject args;
|
||||
args["title"] = tr("AmneziaVPN");
|
||||
//% "Ready for you to connect"
|
||||
|
@ -227,11 +242,13 @@ void AndroidController::setFallbackConnectedNotification() {
|
|||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_FALLBACK, doc.toJson());
|
||||
}
|
||||
|
||||
void AndroidController::checkStatus() {
|
||||
void AndroidController::checkStatus()
|
||||
{
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, QString());
|
||||
}
|
||||
|
||||
void AndroidController::getBackendLogs(std::function<void(const QString&)>&& a_callback) {
|
||||
void AndroidController::getBackendLogs(std::function<void(const QString &)> &&a_callback)
|
||||
{
|
||||
qDebug() << "get logs";
|
||||
|
||||
m_logCallback = std::move(a_callback);
|
||||
|
@ -239,16 +256,13 @@ void AndroidController::getBackendLogs(std::function<void(const QString&)>&& a_c
|
|||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_GET_LOG, QString());
|
||||
}
|
||||
|
||||
void AndroidController::cleanupBackendLogs() {
|
||||
void AndroidController::cleanupBackendLogs()
|
||||
{
|
||||
qDebug() << "cleanup logs";
|
||||
|
||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_CLEANUP_LOG, QString());
|
||||
}
|
||||
|
||||
void AndroidController::importConfig(const QString& data){
|
||||
m_startPageLogic->importAnyFile(data);
|
||||
}
|
||||
|
||||
const QJsonObject &AndroidController::vpnConfig() const
|
||||
{
|
||||
return m_vpnConfig;
|
||||
|
@ -285,31 +299,29 @@ void AndroidController::startActivityForResult(JNIEnv *env, jobject, jobject int
|
|||
qDebug() << "start vpnPermissionHelper";
|
||||
Q_UNUSED(env);
|
||||
|
||||
QtAndroidPrivate::startActivity(intent, 1337,
|
||||
[](int receiverRequestCode, int resultCode,
|
||||
const QJniObject& data) {
|
||||
// Currently this function just used in
|
||||
// VPNService.kt::checkPermissions. So the result
|
||||
// we're getting is if the User gave us the
|
||||
// Vpn.bind permission. In case of NO we should
|
||||
// abort.
|
||||
Q_UNUSED(receiverRequestCode);
|
||||
Q_UNUSED(data);
|
||||
QtAndroidPrivate::startActivity(intent, 1337, [](int receiverRequestCode, int resultCode, const QJniObject &data) {
|
||||
// Currently this function just used in
|
||||
// VPNService.kt::checkPermissions. So the result
|
||||
// we're getting is if the User gave us the
|
||||
// Vpn.bind permission. In case of NO we should
|
||||
// abort.
|
||||
Q_UNUSED(receiverRequestCode);
|
||||
Q_UNUSED(data);
|
||||
|
||||
AndroidController* controller = AndroidController::instance();
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
AndroidController *controller = AndroidController::instance();
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultCode == ACTIVITY_RESULT_OK) {
|
||||
qDebug() << "VPN PROMPT RESULT - Accepted";
|
||||
controller->resumeStart();
|
||||
return;
|
||||
}
|
||||
// If the request got rejected abort the current
|
||||
// connection.
|
||||
qWarning() << "VPN PROMPT RESULT - Rejected";
|
||||
emit controller->connectionStateChanged(VpnProtocol::Disconnected);
|
||||
});
|
||||
if (resultCode == ACTIVITY_RESULT_OK) {
|
||||
qDebug() << "VPN PROMPT RESULT - Accepted";
|
||||
controller->resumeStart();
|
||||
return;
|
||||
}
|
||||
// If the request got rejected abort the current
|
||||
// connection.
|
||||
qWarning() << "VPN PROMPT RESULT - Rejected";
|
||||
emit controller->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue