2018-07-23 15:21:31 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2017-present, Status Research and Development GmbH.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rctstatus.h"
|
|
|
|
#include "bridge.h"
|
|
|
|
#include "eventdispatcher.h"
|
|
|
|
|
|
|
|
#include <QDebug>
|
2018-12-15 18:57:00 +00:00
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QStorageInfo>
|
2018-07-23 15:21:31 +00:00
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QByteArray>
|
|
|
|
#include <QVariantMap>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QStandardPaths>
|
2018-09-07 09:53:43 +00:00
|
|
|
#include <QtConcurrent>
|
2018-07-23 15:21:31 +00:00
|
|
|
|
|
|
|
#include "libstatus.h"
|
|
|
|
|
2018-12-15 18:57:00 +00:00
|
|
|
extern QString getDataStoragePath();
|
|
|
|
extern QString getLogFilePath();
|
|
|
|
|
2018-07-23 15:21:31 +00:00
|
|
|
namespace {
|
|
|
|
struct RegisterQMLMetaType {
|
|
|
|
RegisterQMLMetaType() {
|
|
|
|
qRegisterMetaType<RCTStatus*>();
|
|
|
|
}
|
|
|
|
} registerMetaType;
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
class RCTStatusPrivate {
|
|
|
|
public:
|
|
|
|
static Bridge* bridge;
|
|
|
|
static RCTStatus* rctStatus;
|
|
|
|
};
|
|
|
|
|
|
|
|
Bridge* RCTStatusPrivate::bridge = nullptr;
|
|
|
|
RCTStatus* RCTStatusPrivate::rctStatus = nullptr;
|
2018-11-06 16:01:43 +00:00
|
|
|
|
|
|
|
Q_LOGGING_CATEGORY(RCTSTATUS, "RCTStatus")
|
2018-07-23 15:21:31 +00:00
|
|
|
|
|
|
|
RCTStatus::RCTStatus(QObject* parent) : QObject(parent), d_ptr(new RCTStatusPrivate) {
|
|
|
|
RCTStatusPrivate::rctStatus = this;
|
2018-08-16 19:51:48 +00:00
|
|
|
SetSignalEventCallback((void*)&RCTStatus::statusGoEventCallback);
|
|
|
|
connect(this, &RCTStatus::statusGoEvent, this, &RCTStatus::onStatusGoEvent);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RCTStatus::~RCTStatus() {}
|
|
|
|
|
|
|
|
void RCTStatus::setBridge(Bridge* bridge) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
d->bridge = bridge;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString RCTStatus::moduleName() {
|
|
|
|
return "Status";
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<ModuleMethod*> RCTStatus::methodsToExport() {
|
|
|
|
return QList<ModuleMethod*>{};
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap RCTStatus::constantsToExport() {
|
|
|
|
return QVariantMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RCTStatus::getDeviceUUID(double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::getDeviceUUID call";
|
2018-07-23 15:21:31 +00:00
|
|
|
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{"com.status.StatusIm"});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-09-07 09:53:43 +00:00
|
|
|
void RCTStatus::startNode(QString configString) {
|
2018-07-23 15:21:31 +00:00
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::startNode call - configString:" << configString;
|
2018-07-23 15:21:31 +00:00
|
|
|
|
|
|
|
QJsonParseError jsonError;
|
2018-09-07 09:53:43 +00:00
|
|
|
const QJsonDocument& jsonDoc = QJsonDocument::fromJson(configString.toUtf8(), &jsonError);
|
2018-07-23 15:21:31 +00:00
|
|
|
if (jsonError.error != QJsonParseError::NoError){
|
2018-11-06 16:01:43 +00:00
|
|
|
qCWarning(RCTSTATUS) << jsonError.errorString();
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap configJSON = jsonDoc.toVariant().toMap();
|
2019-01-17 22:46:48 +00:00
|
|
|
QVariantMap shhextConfig = configJSON["ShhextConfig"].toMap();
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::startNode configString: " << configJSON;
|
2018-07-23 15:21:31 +00:00
|
|
|
|
|
|
|
int networkId = configJSON["NetworkId"].toInt();
|
2018-09-07 09:53:43 +00:00
|
|
|
QString relativeDataDirPath = configJSON["DataDir"].toString();
|
|
|
|
if (!relativeDataDirPath.startsWith("/"))
|
|
|
|
relativeDataDirPath.prepend("/");
|
|
|
|
|
2018-12-15 18:57:00 +00:00
|
|
|
QString rootDirPath = getDataStoragePath();
|
2018-09-07 09:53:43 +00:00
|
|
|
QDir rootDir(rootDirPath);
|
|
|
|
QString absDataDirPath = rootDirPath + relativeDataDirPath;
|
|
|
|
QDir dataDir(absDataDirPath);
|
|
|
|
if (!dataDir.exists()) {
|
|
|
|
dataDir.mkpath(".");
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-12-15 18:57:00 +00:00
|
|
|
d_gethLogFilePath = dataDir.absoluteFilePath("geth.log");
|
2018-09-07 09:53:43 +00:00
|
|
|
configJSON["DataDir"] = absDataDirPath;
|
|
|
|
configJSON["KeyStoreDir"] = rootDir.absoluteFilePath("keystore");
|
2018-12-15 18:57:00 +00:00
|
|
|
configJSON["LogFile"] = d_gethLogFilePath;
|
2018-07-23 15:21:31 +00:00
|
|
|
|
2019-02-21 14:51:00 +00:00
|
|
|
shhextConfig["BackupDisabledDataDir"] = rootDirPath;
|
|
|
|
|
2019-01-17 22:46:48 +00:00
|
|
|
configJSON["ShhExtConfig"] = shhextConfig;
|
|
|
|
|
2018-09-07 09:53:43 +00:00
|
|
|
const QJsonDocument& updatedJsonDoc = QJsonDocument::fromVariant(configJSON);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCInfo(RCTSTATUS) << "::startNode updated configString: " << updatedJsonDoc.toVariant().toMap();
|
2018-09-07 09:53:43 +00:00
|
|
|
const char* result = StartNode(QString(updatedJsonDoc.toJson(QJsonDocument::Compact)).toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::startNode StartNode", result);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::stopNode() {
|
2018-11-06 16:01:43 +00:00
|
|
|
qCInfo(RCTSTATUS) << "::stopNode call";
|
2018-07-23 15:21:31 +00:00
|
|
|
const char* result = StopNode();
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::stopNode StopNode", result);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::createAccount(QString password, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCInfo(RCTSTATUS) << "::createAccount call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString password, double callbackId) {
|
|
|
|
const char* result = CreateAccount(password.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::createAccount CreateAccount", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, password, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-01-17 22:46:48 +00:00
|
|
|
void RCTStatus::sendDataNotification(QString dataPayloadJSON, QString tokensJSON, double callbackId) {
|
2018-07-23 15:21:31 +00:00
|
|
|
Q_D(RCTStatus);
|
2019-01-17 22:46:48 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::sendDataNotification call - callbackId:" << callbackId;
|
2018-11-20 18:36:11 +00:00
|
|
|
QtConcurrent::run([&](QString dataPayloadJSON, QString tokensJSON, double callbackId) {
|
2019-01-17 22:46:48 +00:00
|
|
|
const char* result = SendDataNotification(dataPayloadJSON.toUtf8().data(), tokensJSON.toUtf8().data());
|
|
|
|
logStatusGoResult("::sendDataNotification SendDataNotification", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
2018-11-20 18:36:11 +00:00
|
|
|
}, dataPayloadJSON, tokensJSON, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-12-15 18:57:00 +00:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QStandardPaths>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QtGui/private/qzipwriter_p.h>
|
|
|
|
|
|
|
|
void showFileInGraphicalShell(QWidget *parent, const QFileInfo &fileInfo)
|
|
|
|
{
|
|
|
|
// Mac, Windows support folder or file.
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
const QString explorer = QStandardPaths::findExecutable(QLatin1String("explorer.exe"));
|
|
|
|
if (explorer.isEmpty()) {
|
|
|
|
QMessageBox::warning(parent,
|
|
|
|
QApplication::translate("Core::Internal",
|
|
|
|
"Launching Windows Explorer Failed"),
|
|
|
|
QApplication::translate("Core::Internal",
|
|
|
|
"Could not find explorer.exe in path to launch Windows Explorer."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QStringList param;
|
|
|
|
if (!fileInfo.isDir())
|
|
|
|
param += QLatin1String("/select,");
|
|
|
|
param += QDir::toNativeSeparators(fileInfo.canonicalFilePath());
|
|
|
|
QProcess::startDetached(explorer, param);
|
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
QStringList scriptArgs;
|
|
|
|
scriptArgs << QLatin1String("-e")
|
|
|
|
<< QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
|
|
|
|
.arg(fileInfo.canonicalFilePath());
|
|
|
|
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
|
|
|
scriptArgs.clear();
|
|
|
|
scriptArgs << QLatin1String("-e")
|
|
|
|
<< QLatin1String("tell application \"Finder\" to activate");
|
|
|
|
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
|
|
|
#else
|
|
|
|
// we cannot select a file here, because no file browser really supports it...
|
|
|
|
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.dir().absolutePath();
|
|
|
|
QProcess browserProc;
|
|
|
|
browserProc.setProgram("xdg-open");
|
|
|
|
browserProc.setArguments(QStringList(folder));
|
|
|
|
bool success = browserProc.startDetached();
|
|
|
|
const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
|
|
|
|
success = success && error.isEmpty();
|
|
|
|
if (!success) {
|
|
|
|
QMessageBox::warning(parent, "Launching Explorer Failed", error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-04-30 11:49:45 +00:00
|
|
|
void RCTStatus::sendLogs(QString dbJSON, QString jsLogs, double callbackId) {
|
2018-12-15 18:57:00 +00:00
|
|
|
Q_D(RCTStatus);
|
|
|
|
|
|
|
|
qCDebug(RCTSTATUS) << "::sendLogs call - logFilePath:" << getLogFilePath()
|
|
|
|
<< "d_gethLogFilePath:" << d_gethLogFilePath
|
|
|
|
<< "dbJSON:" << dbJSON;
|
|
|
|
|
|
|
|
QString tmpDirName("Status.im");
|
|
|
|
QDir tmpDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
|
|
|
|
if (!tmpDir.mkpath(tmpDirName)) {
|
|
|
|
qCWarning(RCTSTATUS) << "::sendLogs could not create temp dir:" << tmpDirName;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that at least 20MB are available for log generation
|
|
|
|
QStorageInfo storage(tmpDir);
|
|
|
|
if (storage.bytesAvailable() < 20 * 1024 * 1024) {
|
|
|
|
QMessageBox dlg;
|
|
|
|
dlg.warning(QApplication::activeWindow(),
|
|
|
|
"Error", QString("Insufficient storage space available in %1 for log generation. Please free up some space.").arg(storage.rootPath()),
|
|
|
|
QMessageBox::Close);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QFile zipFile(tmpDir.absoluteFilePath(tmpDirName + QDir::separator() + "Status-debug-logs.zip"));
|
|
|
|
QZipWriter zipWriter(&zipFile);
|
|
|
|
QFile gethLogFile(d_gethLogFilePath);
|
|
|
|
QFile logFile(getLogFilePath());
|
|
|
|
zipWriter.addFile("db.json", dbJSON.toUtf8());
|
2019-04-30 11:49:45 +00:00
|
|
|
zipWriter.addFile("js_logs.log", jsLogs.toUtf8());
|
2018-12-15 18:57:00 +00:00
|
|
|
if (gethLogFile.exists()) {
|
|
|
|
zipWriter.addFile(QFileInfo(gethLogFile).fileName(), &gethLogFile);
|
|
|
|
}
|
|
|
|
if (logFile.exists()) {
|
|
|
|
zipWriter.addFile(QFileInfo(logFile).fileName(), &logFile);
|
|
|
|
}
|
|
|
|
zipWriter.close();
|
|
|
|
|
|
|
|
showFileInGraphicalShell(QApplication::activeWindow(), QFileInfo(zipFile));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-23 15:21:31 +00:00
|
|
|
void RCTStatus::addPeer(QString enode, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::addPeer call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString enode, double callbackId) {
|
|
|
|
const char* result = AddPeer(enode.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::addPeer AddPeer", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, enode, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::recoverAccount(QString passphrase, QString password, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCInfo(RCTSTATUS) << "::recoverAccount call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString passphrase, QString password, double callbackId) {
|
|
|
|
const char* result = RecoverAccount(password.toUtf8().data(), passphrase.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::recoverAccount RecoverAccount", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, passphrase, password, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::login(QString address, QString password, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCInfo(RCTSTATUS) << "::login call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString address, QString password, double callbackId) {
|
|
|
|
const char* result = Login(address.toUtf8().data(), password.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::login Login", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, address, password, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-12-03 19:19:56 +00:00
|
|
|
void RCTStatus::verify(QString address, QString password, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
qCInfo(RCTSTATUS) << "::verify call - callbackId:" << callbackId;
|
|
|
|
QtConcurrent::run([&](QString address, QString password, double callbackId) {
|
2018-12-15 18:57:00 +00:00
|
|
|
QDir rootDir(getDataStoragePath());
|
2018-12-03 19:19:56 +00:00
|
|
|
QString keystorePath = rootDir.absoluteFilePath("keystore");
|
|
|
|
const char* result = VerifyAccountPassword(keystorePath.toUtf8().data(), address.toUtf8().data(), password.toUtf8().data());
|
|
|
|
logStatusGoResult("::verify VerifyAccountPassword", result);
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, address, password, callbackId);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-23 15:21:31 +00:00
|
|
|
|
2018-08-20 11:05:51 +00:00
|
|
|
void RCTStatus::sendTransaction(QString txArgsJSON, QString password, double callbackId) {
|
2018-07-23 15:21:31 +00:00
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::sendTransaction call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString txArgsJSON, QString password, double callbackId) {
|
|
|
|
const char* result = SendTransaction(txArgsJSON.toUtf8().data(), password.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::sendTransaction SendTransaction", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, txArgsJSON, password, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-08-20 11:05:51 +00:00
|
|
|
|
|
|
|
void RCTStatus::signMessage(QString rpcParams, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::signMessage call - callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString rpcParams, double callbackId) {
|
|
|
|
const char* result = SignMessage(rpcParams.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::signMessage SignMessage", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, rpcParams, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-07-19 15:51:06 +00:00
|
|
|
void RCTStatus::signGroupMembership(QString content, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::signGroupMembership - callbackId:" << callbackId;
|
2018-07-19 15:51:06 +00:00
|
|
|
QtConcurrent::run([&](QString content, double callbackId) {
|
|
|
|
const char* result = SignGroupMembership(content.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::signGroupMembership SignGroupMembership", result);
|
2018-07-19 15:51:06 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, content, callbackId);
|
|
|
|
}
|
|
|
|
|
2018-10-01 08:47:20 +00:00
|
|
|
void RCTStatus::extractGroupMembershipSignatures(QString signatures, double callbackId) {
|
2018-07-19 15:51:06 +00:00
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::extractGroupMembershipSignatures - callbackId:" << callbackId;
|
2018-07-19 15:51:06 +00:00
|
|
|
QtConcurrent::run([&](QString signatures, double callbackId) {
|
2018-10-01 08:47:20 +00:00
|
|
|
const char* result = ExtractGroupMembershipSignatures(signatures.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::extractGroupMembershipSignatures ExtractGroupMembershipSignatures", result);
|
2018-07-19 15:51:06 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, signatures, callbackId);
|
|
|
|
}
|
2018-08-20 11:05:51 +00:00
|
|
|
|
2018-11-02 13:48:45 +00:00
|
|
|
void RCTStatus::enableInstallation(QString installationId, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
QtConcurrent::run([&](QString installationId, double callbackId) {
|
|
|
|
const char* result = EnableInstallation(installationId.toUtf8().data());
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, installationId, callbackId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RCTStatus::disableInstallation(QString installationId, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
QtConcurrent::run([&](QString installationId, double callbackId) {
|
|
|
|
const char* result = DisableInstallation(installationId.toUtf8().data());
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, installationId, callbackId);
|
|
|
|
}
|
|
|
|
|
2018-07-23 15:21:31 +00:00
|
|
|
void RCTStatus::setAdjustResize() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::setAdjustPan() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::setSoftInputMode(int i) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::clearCookies() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RCTStatus::clearStorageAPIs() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-08-20 11:05:51 +00:00
|
|
|
void RCTStatus::callRPC(QString payload, double callbackId) {
|
2018-07-23 15:21:31 +00:00
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::callRPC call - payload:" << payload.left(128) << "callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString payload, double callbackId) {
|
|
|
|
const char* result = CallRPC(payload.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::callRPC CallRPC", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, payload, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-08-20 11:05:51 +00:00
|
|
|
void RCTStatus::callPrivateRPC(QString payload, double callbackId) {
|
2018-07-23 15:21:31 +00:00
|
|
|
Q_D(RCTStatus);
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::callPrivateRPC call - payload:" << payload.left(128) << "callbackId:" << callbackId;
|
2018-09-07 09:53:43 +00:00
|
|
|
QtConcurrent::run([&](QString payload, double callbackId) {
|
|
|
|
const char* result = CallPrivateRPC(payload.toUtf8().data());
|
2018-11-06 16:01:43 +00:00
|
|
|
logStatusGoResult("::callPrivateRPC CallPrivateRPC", result);
|
2018-09-07 09:53:43 +00:00
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, payload, callbackId);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RCTStatus::closeApplication() {
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RCTStatus::JSCEnabled() {
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::JSCEnabled call";
|
2018-07-23 15:21:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-16 19:51:48 +00:00
|
|
|
void RCTStatus::statusGoEventCallback(const char* event) {
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::statusGoEventCallback call - event: " << event;
|
2018-08-16 19:51:48 +00:00
|
|
|
RCTStatusPrivate::rctStatus->emitStatusGoEvent(event);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 19:51:48 +00:00
|
|
|
void RCTStatus::emitStatusGoEvent(QString event) {
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::emitStatusGoEvent call - event: " << event;
|
2018-08-16 19:51:48 +00:00
|
|
|
Q_EMIT statusGoEvent(event);
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 19:51:48 +00:00
|
|
|
void RCTStatus::onStatusGoEvent(QString event) {
|
2018-11-06 16:01:43 +00:00
|
|
|
qCDebug(RCTSTATUS) << "::onStatusGoEvent call - event: " << event.toUtf8().data();
|
2018-08-16 19:51:48 +00:00
|
|
|
RCTStatusPrivate::bridge->eventDispatcher()->sendDeviceEvent("gethEvent", QVariantMap{{"jsonEvent", event.toUtf8().data()}});
|
2018-07-23 15:21:31 +00:00
|
|
|
}
|
2018-09-14 16:52:14 +00:00
|
|
|
|
2018-11-06 16:01:43 +00:00
|
|
|
void RCTStatus::logStatusGoResult(const char* methodName, const char* result)
|
2018-09-14 16:52:14 +00:00
|
|
|
{
|
|
|
|
QJsonParseError jsonError;
|
|
|
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(QString(result).toUtf8(), &jsonError);
|
2018-11-06 16:01:43 +00:00
|
|
|
if (jsonError.error != QJsonParseError::NoError) {
|
|
|
|
qCWarning(RCTSTATUS) << qUtf8Printable(jsonError.errorString());
|
|
|
|
return;
|
2018-09-14 16:52:14 +00:00
|
|
|
}
|
|
|
|
|
2018-11-06 16:01:43 +00:00
|
|
|
QString error = jsonDoc.toVariant().toMap().value("error").toString();
|
|
|
|
if (error.isEmpty()) {
|
|
|
|
qCDebug(RCTSTATUS) << methodName << "succeeded";
|
|
|
|
} else {
|
|
|
|
qCWarning(RCTSTATUS) << methodName << "- error:" << qUtf8Printable(error);
|
|
|
|
}
|
2018-09-14 16:52:14 +00:00
|
|
|
}
|
Add mailservers confirmations & use peer count for online status
We now check that we are only connected to some `peers` instead of using `NetInfo` from `react-native`.
This is because it has been reported to be quite flaky at times, not reporting online status after sleeping, and for privacy concerns (on ios it pings `apple.com`, on desktop `google.com`).
Adds a new banner `Wallet Offline` and change `Connecting to peers` to `Chat offline`.
A message will be marked as `Sent` only if it made it to the mailserver you are connected to, which will increase the guarantees that we can make about a message (if you see it as sent, it has reached at least a mailserver), this has the consequence that:
- If you are not connected to any mailserver or the mailserver is non responsive/down, and you send a message, it will be marked as `Not sent`, although it might have been actually made it in the network.
Probably this is something that we would like to communicate to the user through UX (i.e. tick if made it to at least a peer, double tick if it made to a mailserver )
Currently I have only enabled this feature in nightlies & devs, I would give it a run and see how we feel about it.
2018-12-06 10:53:45 +00:00
|
|
|
|
|
|
|
void RCTStatus::updateMailservers(QString enodes, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
qCDebug(RCTSTATUS) << "::updateMailservers call - callbackId:" << callbackId;
|
|
|
|
QtConcurrent::run([&](QString enodes, double callbackId) {
|
|
|
|
const char* result = UpdateMailservers(enodes.toUtf8().data());
|
|
|
|
logStatusGoResult("::updateMailservers UpdateMailservers", result);
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, enodes, callbackId);
|
|
|
|
}
|
2019-03-22 13:57:27 +00:00
|
|
|
|
2019-03-29 18:00:12 +00:00
|
|
|
void RCTStatus::getNodesFromContract(QString url, QString address, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
qCDebug(RCTSTATUS) << "::getNodesFromContract call - callbackId:" << callbackId;
|
|
|
|
QtConcurrent::run([&](QString url, QString address, double callbackId) {
|
|
|
|
const char* result = GetNodesFromContract(url.toUtf8().data(), address.toUtf8().data());
|
|
|
|
logStatusGoResult("::getNodesFromContract GetNodesFromContract", result);
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, url, address, callbackId);
|
|
|
|
}
|
|
|
|
|
2019-03-22 13:57:27 +00:00
|
|
|
void RCTStatus::chaosModeUpdate(bool on, double callbackId) {
|
|
|
|
Q_D(RCTStatus);
|
|
|
|
qCDebug(RCTSTATUS) << "::chaosModeUpdate call - callbackId:" << callbackId;
|
|
|
|
QtConcurrent::run([&](bool on, double callbackId) {
|
|
|
|
const char* result = ChaosModeUpdate(on);
|
|
|
|
logStatusGoResult("::chaosModeUpdate ChaosModeUpdate", result);
|
|
|
|
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
|
|
|
|
}, on, callbackId);
|
|
|
|
}
|