diff --git a/retroshare-android-notify-service/src/AutologinManager.qml b/retroshare-android-notify-service/src/AutologinManager.qml new file mode 100644 index 000000000..10931e26a --- /dev/null +++ b/retroshare-android-notify-service/src/AutologinManager.qml @@ -0,0 +1,167 @@ +/* + * RetroShare Android Autologin Service + * Copyright (C) 2017 Gioacchino Mazzurco + * + * 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 . + */ + +import QtQml 2.2 +import org.retroshare.qml_components.LibresapiLocalClient 1.0 + +QtObject +{ + id: am + + property bool coreReady: false + + property string profileName + property string profileSslId + property string hardcodedPassword: "hardcoded default password" + property int loginAttemptCount: 0 + property bool attemptingLogin: false + + function delay(msecs, func) + { + var tmr = Qt.createQmlObject("import QtQml 2.2; Timer {}", am); + tmr.interval = msecs; + tmr.repeat = false; + tmr.triggered.connect(function() { func(); tmr.destroy(msecs) }); + tmr.start(); + } + + property Timer runStateTimer: Timer + { + repeat: true + interval: 5000 + triggeredOnStart: true + Component.onCompleted: start() + onTriggered: + rsApi.request("/control/runstate/", "", am.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": + coreReady = false + console.log("Core is starting") + break + case "fatal_error": + coreReady = false + console.log("Core hanged") + break + case "waiting_account_select": + coreReady = false + if(!attemptingLogin && loginAttemptCount < 5) + rsApi.request("/control/locations/", "", requestLocationsListCB) + break + case "waiting_startup": + coreReady = false + break + case "running_ok": + case "running_ok_no_full_control": + coreReady = true + 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) + { + if(JSON.parse(par.response).data.want_password) + { + console.log("attemptPasswordCB want_password") + rsApi.request( + "/control/password/", + JSON.stringify({ password: am.hardcodedPassword }), + attemptPasswordCBCB) + } + } + + function attemptPasswordCBCB() + { + console.log("attemptPasswordCBCB") + stop() + am.runStateTimer.stop() + + /* Wait 10 seconds so the core has time to process login and update + * runstate */ + delay(10000, function() + { + am.attemptingLogin = false + am.runStateTimer.start() + }) + } + } +} diff --git a/retroshare-android-notify-service/src/TokensManager.qml b/retroshare-android-notify-service/src/TokensManager.qml new file mode 120000 index 000000000..065833c82 --- /dev/null +++ b/retroshare-android-notify-service/src/TokensManager.qml @@ -0,0 +1 @@ +../../retroshare-qml-app/src/qml/TokensManager.qml \ No newline at end of file diff --git a/retroshare-android-notify-service/src/notify.qml b/retroshare-android-notify-service/src/notify.qml index 655287f3a..4e66711af 100644 --- a/retroshare-android-notify-service/src/notify.qml +++ b/retroshare-android-notify-service/src/notify.qml @@ -18,134 +18,33 @@ import QtQml 2.2 import org.retroshare.qml_components.LibresapiLocalClient 1.0 +import "." //Needed for TokensManager singleton QtObject { - id: mo + id: notifyRoot - property string profileName - property string profileSslId - property string hardcodedPassword: "hardcoded default password" - property int loginAttemptCount: 0 - property bool attemptingLogin: false + property alias coreReady: coreWatcher.coreReady - property Timer runStateTimer: Timer + property AutologinManager _aM: AutologinManager { id: coreWatcher } + + onCoreReadyChanged: if(coreReady) refreshUnread() + + function refreshUnreadCallback(par) { - 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("notifyRoot.refreshUnreadCB()") + var json = JSON.parse(par.response) + TokensManager.registerToken(json.statetoken, refreshUnread) + if(json.data.length > 0) { - 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 + console.log("notifyRoot.refreshUnreadCB() got", json.data.length, + "unread messages") + //TODO: display android notification } } - - function requestLocationsListCB(par) + function refreshUnread() { - 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) - } + console.log("notifyRoot.refreshUnread()") + rsApi.request("/chat/unread_msgs", "", refreshUnreadCallback) } } diff --git a/retroshare-android-notify-service/src/qml.qrc b/retroshare-android-notify-service/src/qml.qrc index 4d56492f2..244961228 100644 --- a/retroshare-android-notify-service/src/qml.qrc +++ b/retroshare-android-notify-service/src/qml.qrc @@ -1,5 +1,8 @@ notify.qml + TokensManager.qml + AutologinManager.qml + qmldir diff --git a/retroshare-android-notify-service/src/qmldir b/retroshare-android-notify-service/src/qmldir new file mode 100644 index 000000000..087adf650 --- /dev/null +++ b/retroshare-android-notify-service/src/qmldir @@ -0,0 +1 @@ +singleton TokensManager 1.0 TokensManager.qml