android notification service stub, improve login

Added retroshare-android-notify-service a stub will handle notifications
  to android system, at the moment it only attempt autologin if default
  password is used
retroshare-android-service quit QCoreApplication gracefully
Android Studio update has changed some android build files
Create BusyOverlay.qml componet so it is reusable accross the qml app
Contacts.qml create a pseudonimous GXS identity as needed without
  prompting the user
RsLoginPassView.qml nicer look, on mobile phone password usage is not
  common so do not use password by default
QML app main view handle correctly +waiting_startup+ runstate
QML app main view use BusyOverlay as initial item
This commit is contained in:
Gioacchino Mazzurco 2017-04-07 18:26:08 +02:00
parent 70e91f7164
commit bcbd5230eb
24 changed files with 562 additions and 94 deletions

View file

@ -0,0 +1 @@
../../retroshare-qml-app/src/libresapilocalclient.cpp

View file

@ -0,0 +1 @@
../../retroshare-qml-app/src/libresapilocalclient.h

View file

@ -0,0 +1,73 @@
/*
* RetroShare Android Service
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QCoreApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QFileInfo>
#include <QDebug>
#ifdef __ANDROID__
# include "util/androiddebug.h"
#endif
#include "libresapilocalclient.h"
#include "retroshare/rsinit.h"
int main(int argc, char *argv[])
{
#ifdef __ANDROID__
AndroidStdIOCatcher dbg; (void) dbg;
#endif
QCoreApplication app(argc, argv);
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
sockPath.append("/libresapi.sock");
QQmlApplicationEngine engine;
qmlRegisterType<LibresapiLocalClient>(
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
"LibresapiLocalClient");
#ifdef QT_DEBUG
engine.rootContext()->setContextProperty("QT_DEBUG", true);
#else
engine.rootContext()->setContextProperty("QT_DEBUG", false);
#endif // QT_DEBUG
engine.rootContext()->setContextProperty("apiSocketPath", sockPath);
LibresapiLocalClient rsApi;
while (!QFileInfo::exists(sockPath))
{
qDebug() << "RetroShareAndroidNotifyService waiting for core to"
<< "listen on:" << sockPath;
usleep(2500000);
}
rsApi.openConnection(sockPath);
engine.rootContext()->setContextProperty("rsApi", &rsApi);
engine.load(QUrl(QLatin1String("qrc:/notify.qml")));
return app.exec();
}

View file

@ -0,0 +1,151 @@
/*
* RetroShare Android Autologin Service
* Copyright (C) 2017 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQml 2.2
import org.retroshare.qml_components.LibresapiLocalClient 1.0
QtObject
{
id: mo
property string profileName
property string profileSslId
property string hardcodedPassword: "hardcoded default password"
property int loginAttemptCount: 0
property bool attemptingLogin: false
property Timer runStateTimer: Timer
{
repeat: true
interval: 5000
triggeredOnStart: true
Component.onCompleted: start()
onTriggered:
rsApi.request("/control/runstate/", "", mo.runStateCallback)
}
function runStateCallback(par)
{
var jsonReponse = JSON.parse(par.response)
var runState = jsonReponse.data.runstate
if(typeof(runState) !== 'string')
{
console.log("runStateCallback(...) Core is hanged")
return
}
switch(runState)
{
case "waiting_init":
console.log("Core is starting")
break
case "fatal_error":
console.log("Core hanged")
break
case "waiting_account_select":
if(!attemptingLogin && loginAttemptCount < 5)
rsApi.request("/control/locations/", "", requestLocationsListCB)
break
case "waiting_startup":
break
case "running_ok":
case "running_ok_no_full_control":
runStateTimer.interval = 30000
break
}
}
function requestLocationsListCB(par)
{
console.log("requestLocationsListCB")
var jsonData = JSON.parse(par.response).data
if(jsonData.length === 1)
{
// There is only one location so we can attempt autologin
var location = jsonData[0]
profileName = location.name
profileSslId = location.peer_id
if(!attemptingLogin && loginAttemptCount < 5) attemptLogin()
}
else if (jsonData.length === 0)
{
console.log("requestLocationsListCB 0")
// The user haven't created a location yet
// TODO: notify user to create a location
}
else
{
console.log("requestLocationsListCB *")
// There is more then one location to choose from
// TODO: notify user to login manually
}
}
function attemptLogin()
{
console.log("attemptLogin")
attemptingLogin = true
++loginAttemptCount
rsApi.request(
"/control/login/", JSON.stringify({ id: profileSslId }),
attemptLoginCB)
}
function attemptLoginCB(par)
{
console.log("attemptLoginCB")
var jsonRet = JSON.parse(par.response).returncode
if (jsonRet === "ok") attemptPassTimer.start()
else console.log("Login hanged!")
}
property Timer attemptPassTimer: Timer
{
interval: 700
repeat: true
triggeredOnStart: true
onTriggered: rsApi.request("/control/password/", "", attemptPasswordCB)
function attemptPasswordCB(par)
{
console.log("attemptPasswordCB", mo.attemptPassTimer, "running?", running)
if(JSON.parse(par.response).data.want_password)
{
console.log("attemptPasswordCB want_password")
rsApi.request(
"/control/password/",
JSON.stringify({ password: mo.hardcodedPassword }),
attemptPasswordCBCB)
}
}
function attemptPasswordCBCB()
{
console.log("attemptPasswordCBCB")
stop()
/* Wait 10 seconds so the core has time to process login and update
* runstate */
var timeStart = new Date().getTime();
while (new Date().getTime() - timeStart < 10000) {}
mo.attemptingLogin = false
rsApi.request("/control/runstate/", "", mo.runStateCallback)
}
}
}

View file

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>notify.qml</file>
</qresource>
</RCC>

View file

@ -0,0 +1,22 @@
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
TARGET = retroshare-android-notify-service
QT += core network qml
QT -= gui
CONFIG += c++11
CONFIG += dll
RESOURCES += qml.qrc
android-g++:TEMPLATE = lib
!android-g++:TEMPLATE = app
HEADERS += libresapilocalclient.h
SOURCES += libresapilocalclient.cpp notify.cpp
DEPENDPATH *= ../../libretroshare/src
INCLUDEPATH *= ../../libretroshare/src
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
LIBS *= ../../libretroshare/src/lib/libretroshare.a