Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into feature/container-existence-on-container-setup
This commit is contained in:
commit
f2e9631af4
24 changed files with 468 additions and 229 deletions
|
|
@ -3,15 +3,70 @@
|
|||
#include "ui/uilogic.h"
|
||||
#include "ui/pages_logic/StartPageLogic.h"
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include <QJniEnvironment>
|
||||
#include <QJniObject>
|
||||
#include "../../platforms/android/androidutils.h"
|
||||
#endif
|
||||
|
||||
using namespace amnezia;
|
||||
using namespace PageEnumNS;
|
||||
|
||||
namespace {
|
||||
QrDecoderLogic* mInstance = nullptr;
|
||||
constexpr auto CLASSNAME = "org.amnezia.vpn.qt.CameraActivity";
|
||||
}
|
||||
|
||||
QrDecoderLogic::QrDecoderLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent)
|
||||
{
|
||||
mInstance = this;
|
||||
|
||||
#if (defined(Q_OS_ANDROID))
|
||||
AndroidUtils::runOnAndroidThreadAsync([]() {
|
||||
JNINativeMethod methods[]{
|
||||
{"passDataToDecoder", "(Ljava/lang/String;)V", reinterpret_cast<void*>(onNewDataChunk)},
|
||||
};
|
||||
|
||||
QJniObject javaClass(CLASSNAME);
|
||||
QJniEnvironment env;
|
||||
jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
|
||||
env->RegisterNatives(objectClass, methods, sizeof(methods) / sizeof(methods[0]));
|
||||
env->DeleteLocalRef(objectClass);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void QrDecoderLogic::stopDecodingQr()
|
||||
{
|
||||
#if (defined(Q_OS_ANDROID))
|
||||
QJniObject::callStaticMethod<void>(CLASSNAME, "stopQrCodeReader", "()V");
|
||||
#endif
|
||||
|
||||
emit stopDecode();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
void QrDecoderLogic::onNewDataChunk(JNIEnv *env, jobject thiz, jstring data)
|
||||
{
|
||||
Q_UNUSED(thiz);
|
||||
const char* buffer = env->GetStringUTFChars(data, nullptr);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString parcelBody(buffer);
|
||||
env->ReleaseStringUTFChars(data, buffer);
|
||||
|
||||
if (mInstance != nullptr) {
|
||||
if (!mInstance->m_detectingEnabled) {
|
||||
mInstance->onUpdatePage();
|
||||
}
|
||||
mInstance->onDetectedQrCode(parcelBody);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void QrDecoderLogic::onUpdatePage()
|
||||
{
|
||||
m_chunks.clear();
|
||||
|
|
@ -24,7 +79,6 @@ void QrDecoderLogic::onUpdatePage()
|
|||
void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
||||
{
|
||||
//qDebug() << code;
|
||||
|
||||
if (!detectingEnabled()) return;
|
||||
|
||||
// check if chunk received
|
||||
|
|
@ -32,12 +86,12 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
|||
QDataStream s(&ba, QIODevice::ReadOnly);
|
||||
qint16 magic; s >> magic;
|
||||
|
||||
|
||||
if (magic == amnezia::qrMagicCode) {
|
||||
quint8 chunksCount; s >> chunksCount;
|
||||
if (totalChunksCount() != chunksCount) {
|
||||
m_chunks.clear();
|
||||
}
|
||||
|
||||
set_totalChunksCount(chunksCount);
|
||||
|
||||
quint8 chunkId; s >> chunkId;
|
||||
|
|
@ -46,6 +100,7 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
|||
|
||||
if (m_chunks.size() == totalChunksCount()) {
|
||||
QByteArray data;
|
||||
|
||||
for (int i = 0; i < totalChunksCount(); ++i) {
|
||||
data.append(m_chunks.value(i));
|
||||
}
|
||||
|
|
@ -53,21 +108,18 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
|||
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(data);
|
||||
if (ok) {
|
||||
set_detectingEnabled(false);
|
||||
emit stopDecode();
|
||||
}
|
||||
else {
|
||||
stopDecodingQr();
|
||||
} else {
|
||||
m_chunks.clear();
|
||||
set_totalChunksCount(0);
|
||||
set_receivedChunksCount(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(ba);
|
||||
if (ok) {
|
||||
set_detectingEnabled(false);
|
||||
emit stopDecode();
|
||||
stopDecodingQr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include "PageLogicBase.h"
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "jni.h"
|
||||
#endif
|
||||
|
||||
class UiLogic;
|
||||
|
||||
class QrDecoderLogic : public PageLogicBase
|
||||
|
|
@ -16,10 +20,17 @@ public:
|
|||
Q_INVOKABLE void onUpdatePage() override;
|
||||
Q_INVOKABLE void onDetectedQrCode(const QString &code);
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
static void onNewDataChunk(JNIEnv *env, jobject thiz, jstring data);
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit QrDecoderLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
~QrDecoderLogic() = default;
|
||||
|
||||
private:
|
||||
void stopDecodingQr();
|
||||
|
||||
signals:
|
||||
void startDecode();
|
||||
void stopDecode();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#ifdef Q_OS_ANDROID
|
||||
#include <QJniObject>
|
||||
#include "../../platforms/android/androidutils.h"
|
||||
#include "../../platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
|
@ -184,6 +185,13 @@ void StartPageLogic::onPushButtonImportOpenFile()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
void StartPageLogic::startQrDecoder()
|
||||
{
|
||||
AndroidController::instance()->startQrReaderActivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool StartPageLogic::importConnection(const QJsonObject &profile)
|
||||
{
|
||||
ServerCredentials credentials;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ public:
|
|||
Q_INVOKABLE void onPushButtonImport();
|
||||
Q_INVOKABLE void onPushButtonImportOpenFile();
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
Q_INVOKABLE void startQrDecoder();
|
||||
#endif
|
||||
|
||||
bool importConnection(const QJsonObject &profile);
|
||||
bool importConnectionFromCode(QString code);
|
||||
bool importConnectionFromQr(const QByteArray &data);
|
||||
|
|
|
|||
|
|
@ -1,164 +0,0 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtMultimedia
|
||||
import PageEnum 1.0
|
||||
import QZXing 3.2
|
||||
|
||||
import "./"
|
||||
import "../Controls"
|
||||
import "../Config"
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
page: PageEnum.QrDecoder
|
||||
logic: QrDecoderLogic
|
||||
|
||||
onDeactivated: {
|
||||
console.debug("Stopping QR decoder")
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
|
||||
BackButton {
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Import configuration")
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Qt.platform.os != "ios" ? QrDecoderLogic : null
|
||||
function onStartDecode() {
|
||||
console.debug("Starting QR decoder")
|
||||
loader.sourceComponent = component
|
||||
}
|
||||
function onStopDecode() {
|
||||
console.debug("Stopping QR decoder")
|
||||
loader.sourceComponent = undefined
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
|
||||
anchors.top: caption.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Component {
|
||||
id: component
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
Camera
|
||||
{
|
||||
id:camera
|
||||
focus {
|
||||
focusMode: CameraFocus.FocusContinuous
|
||||
focusPointMode: CameraFocus.FocusPointAuto
|
||||
}
|
||||
}
|
||||
|
||||
VideoOutput
|
||||
{
|
||||
id: videoOutput
|
||||
source: camera
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
autoOrientation: true
|
||||
fillMode: VideoOutput.PreserveAspectFit
|
||||
// filters: [ zxingFilter ]
|
||||
|
||||
|
||||
Rectangle {
|
||||
color: "black"
|
||||
opacity: 0.5
|
||||
width: videoOutput.contentRect.width * 0.15
|
||||
height: videoOutput.contentRect.height
|
||||
x: (videoOutput.width - videoOutput.contentRect.width)/2
|
||||
anchors.verticalCenter: videoOutput.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "black"
|
||||
opacity: 0.5
|
||||
width: videoOutput.contentRect.width * 0.15
|
||||
height: videoOutput.contentRect.height
|
||||
x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width * 0.15
|
||||
anchors.verticalCenter: videoOutput.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "black"
|
||||
opacity: 0.5
|
||||
width: videoOutput.contentRect.width * 0.7
|
||||
height: videoOutput.contentRect.height * 0.15
|
||||
x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15
|
||||
y: (videoOutput.height - videoOutput.contentRect.height)/2
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "black"
|
||||
opacity: 0.5
|
||||
width: videoOutput.contentRect.width * 0.7
|
||||
height: videoOutput.contentRect.height * 0.15
|
||||
x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15
|
||||
y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height * 0.15
|
||||
}
|
||||
|
||||
LabelType {
|
||||
width: parent.width
|
||||
text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount)
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
visible: QrDecoderLogic.totalChunksCount > 0
|
||||
anchors.horizontalCenter: videoOutput.horizontalCenter
|
||||
y: videoOutput.height/2 + videoOutput.contentRect.height/2
|
||||
}
|
||||
}
|
||||
|
||||
QZXingFilter
|
||||
{
|
||||
id: zxingFilter
|
||||
orientation: videoOutput.orientation
|
||||
captureRect: {
|
||||
// setup bindings
|
||||
videoOutput.contentRect;
|
||||
videoOutput.sourceRect;
|
||||
return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect(
|
||||
0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0
|
||||
)));
|
||||
}
|
||||
|
||||
decoder {
|
||||
enabledDecoders: QZXing.DecoderFormat_QR_CODE
|
||||
|
||||
onTagFound: {
|
||||
QrDecoderLogic.onDetectedQrCode(tag)
|
||||
}
|
||||
|
||||
tryHarder: true
|
||||
}
|
||||
|
||||
property int framesDecoded: 0
|
||||
property real timePerFrameDecode: 0
|
||||
|
||||
onDecodingFinished:
|
||||
{
|
||||
timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1);
|
||||
framesDecoded++;
|
||||
if(succeeded)
|
||||
console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ PageBase {
|
|||
if (Qt.platform.os === "ios") {
|
||||
UiLogic.goToPage(PageEnum.QrDecoderIos)
|
||||
} else {
|
||||
UiLogic.goToPage(PageEnum.QrDecoder)
|
||||
StartPageLogic.startQrDecoder()
|
||||
}
|
||||
}
|
||||
enabled: StartPageLogic.pushButtonConnectEnabled
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue